I work on a project that has 2 branches, A and B. I typically work on branch A, and merge stuff from branch B. For the merging, I would typically do:
git merge origin/branchB
However, I would also like to keep a local copy of branch B, as I may occasionally check out the branch without first merging with my branch A. For this, I would do:
git checkout branchB
git pull
git checkout branchA
Is there a way to do the above in one command, and without having to switch branch back and forth? Should I be using git update-ref
for that? How?
You can clone the repo and do the merge in the new repo. On the same filesystem, this will hardlink rather than copy most of the data. Finish by pulling the results into the original repo.
For many cases (such as merging), you can just use the remote branch without having to update the local tracking branch. Adding a message in the reflog sounds like overkill and will stop it being quicker. To make it easier to recover, add the following into your git config
Then type
to see the recent history for your branch
The Short Answer
As long as you're doing a fast-forward merge, then you can simply use
Examples:
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, sincegit 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 branchfeature
checked out: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:
What this alias does is the following:
git checkout HEAD
: this puts your working copy into a detached-head state. This is useful if you want to updatemaster
while you happen to have it checked-out. I think it was necessary to do with because otherwise the branch reference formaster
won't move, but I don't remember if that's really right off-the-top of my head.git fetch upstream master:master
: this fast-forwards your localmaster
to the same place asupstream/master
.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 mergesIf you want the
fetch
command to fail if the update is non-fast-forward, then you simply use a refspec of the formIf you want to allow non-fast-forward updates, then you add a
+
to the front of the refspec:Note that you can pass your local repo as the "remote" parameter using
.
:The Documentation
From the
git fetch
documentation that explains this syntax (emphasis mine):See Also
Git checkout and merge without touching working tree
Merging without changing the working directory
Enter git-forward-merge:
https://github.com/schuyler1d/git-forward-merge
Only works for automatic merges, if there are conflicts you need to use the regular merge.