[git] Merge, update, and pull Git branches without using checkouts

The Short Answer

As long as you're doing a fast-forward merge, then you can simply use

git fetch <remote> <sourceBranch>:<destinationBranch>

Examples:

# Merge local branch foo into local branch master,
# without having to checkout master first.
# Here `.` means to use the local repository as the "remote":
git fetch . foo:master

# Merge remote branch origin/foo into local branch foo,
# without having to checkout foo first:
git fetch origin foo:foo

While Amber's answer will also work in fast-forward cases, using git fetch in this way instead is a little safer than just force-moving the branch reference, since git fetch will automatically prevent accidental non-fast-forwards as long as you don't use + in the refspec.

The Long Answer

You cannot merge a branch B into branch A without checking out A first if it would result in a non-fast-forward merge. This is because a working copy is needed to resolve any potential conflicts.

However, in the case of fast-forward merges, this is possible, because such merges can never result in conflicts, by definition. To do this without checking out a branch first, you can use git fetch with a refspec.

Here's an example of updating master (disallowing non-fast-forward changes) if you have another branch feature checked out:

git fetch upstream master:master

This use-case is so common, that you'll probably want to make an alias for it in your git configuration file, like this one:

[alias]
    sync = !sh -c 'git checkout --quiet HEAD; git fetch upstream master:master; git checkout --quiet -'

What this alias does is the following:

  1. git checkout HEAD: this puts your working copy into a detached-head state. This is useful if you want to update master while you happen to have it checked-out. I think it was necessary to do with because otherwise the branch reference for master won't move, but I don't remember if that's really right off-the-top of my head.

  2. git fetch upstream master:master: this fast-forwards your local master to the same place as upstream/master.

  3. git checkout - checks out your previously checked-out branch (that's what the - does in this case).

The syntax of git fetch for (non-)fast-forward merges

If you want the fetch command to fail if the update is non-fast-forward, then you simply use a refspec of the form

git fetch <remote> <remoteBranch>:<localBranch>

If you want to allow non-fast-forward updates, then you add a + to the front of the refspec:

git fetch <remote> +<remoteBranch>:<localBranch>

Note that you can pass your local repo as the "remote" parameter using .:

git fetch . <sourceBranch>:<destinationBranch>

The Documentation

From the git fetch documentation that explains this syntax (emphasis mine):

<refspec>

The format of a <refspec> parameter is an optional plus +, followed by the source ref <src>, followed by a colon :, followed by the destination ref <dst>.

The remote ref that matches <src> is fetched, and if <dst> is not empty string, the local ref that matches it is fast-forwarded using <src>. If the optional plus + is used, the local ref is updated even if it does not result in a fast-forward update.

See Also

  1. Git checkout and merge without touching working tree

  2. Merging without changing the working directory

Examples related to git

Does the target directory for a git clone have to match the repo name? Git fatal: protocol 'https' is not supported Git is not working after macOS Update (xcrun: error: invalid active developer path (/Library/Developer/CommandLineTools) git clone: Authentication failed for <URL> destination path already exists and is not an empty directory SSL_connect: SSL_ERROR_SYSCALL in connection to github.com:443 GitLab remote: HTTP Basic: Access denied and fatal Authentication How can I switch to another branch in git? VS 2017 Git Local Commit DB.lock error on every commit How to remove an unpushed outgoing commit in Visual Studio?

Examples related to git-merge

Abort a Git Merge Git pull - Please move or remove them before you can merge Git: How configure KDiff3 as merge tool and diff tool Git: How to pull a single file from a server repository in Git? How to resolve git error: "Updates were rejected because the tip of your current branch is behind" error: Your local changes to the following files would be overwritten by checkout Please enter a commit message to explain why this merge is necessary, especially if it merges an updated upstream into a topic branch How to merge specific files from Git branches git remove merge commit from history The following untracked working tree files would be overwritten by merge, but I don't care

Examples related to git-pull

Trying to pull files from my Github repository: "refusing to merge unrelated histories" Git pull - Please move or remove them before you can merge There is no tracking information for the current branch How to unmerge a Git merge? Git: How to pull a single file from a server repository in Git? Why does git say "Pull is not possible because you have unmerged files"? fatal: could not read Username for 'https://github.com': No such file or directory Difference between git pull and git pull --rebase Is it possible to pull just one file in Git? How do I ignore an error on 'git pull' about my local changes would be overwritten by merge?

Examples related to git-checkout

How can I switch to another branch in git? Git checkout - switching back to HEAD What is git tag, How to create tags & How to checkout git remote tag(s) How can I move HEAD back to a previous location? (Detached head) & Undo commits error: pathspec 'test-branch' did not match any file(s) known to git git checkout all the files How can I check out a GitHub pull request with git? "Cannot update paths and switch to branch at the same time" error: Your local changes to the following files would be overwritten by checkout Git command to checkout any branch and overwrite local changes