How do I fast-forward other tracking branches in git?
We are working with the model of a single remote repository that all of us use. We branch for new features and reintegrate into a trunk branch. Our workflow is that we should integrate from trunk into our working branches when other features are integrated into the trunk.
As such, it's not uncommon for us to do:
(branch) $ git commit -a -m"blah blah blah"
(branch) $ git fetch # origin/trunk is updated
(branch) $ git checkout trunk
(trunk) $ git pull # trunk is fast-forwarded to current version of origin/trunk.
(trunk) $ git checkout branch
(branch) $ git merge trunk
(branch) $ git push
I don't like the "git checkout trunk/git pull/git checkout branch" cycle. It's usually combined with Visual Studio complaining that all my files and projects have changed on disk, and should it reload them. For both checkouts. And the pull. And the merge. The merge is unavoidable, but because of how git works, it should be able to do the fast-forward on trunk without actually needing to check it out.
But I don't know the command, and my开发者_运维技巧 google-foo has failed me on this. Anyone know how?
I think the easiest way to avoid the git checkout trunk
, git pull
, git checkout branch
cycle is to use this answer:
git fetch upstream trunk:trunk
This does exactly what you want - fast-forward your local branch trunk
to the remote branch's HEAD.
Do you really need to update a local trunk
branch?
Just fetch origin/trunk
and merge
it directly in the branch you are working on.
And that is Mark Longair's advice: git: fetch
and merge
, don’t pull
.
Oliver mentions in his answer (upvoted):
git fetch upstream trunk:trunk
As he comments:
you can skip the merge and simply fast-forward, using a one-liner.
It does fast-forward the local branch trunk
to the remote branch's HEAD.
See more at "git: update a local branch without checking it out?"
I agree with VonC's answer, but thought it might be fun to answer the question "How do you fast-forward master
if you're on another branch?" anyway. I don't think there's a way to do this just using porcelain commands, but this script does the job (obviously you'd want to change master
to trunk
in your case):
#!/bin/sh
BRANCH=master
NEWER=origin/master
if [ x"$(git symbolic-ref HEAD)" = x"refs/heads/$BRANCH" ]
then
echo "This doesn't make sense if you're already on the branch '$BRANCH'"
echo "Just run: git merge $NEWER"
exit 1
fi
BRANCH_HASH=$(git rev-parse $BRANCH)
NEWER_HASH=$(git rev-parse $NEWER)
MERGE_BASE=$(git merge-base $BRANCH_HASH $NEWER_HASH)
if [ "$MERGE_BASE" = "$BRANCH_HASH" ]
then
git update-ref "refs/heads/$BRANCH" "$NEWER_HASH" "$BRANCH_HASH"
else
echo "$BRANCH can't be fast-forwarded to $NEWER"
exit 1
fi
Update 2012-10-20: this script was just a quick example; for a script that does the same but for merging any arbitrary commit-ish into a local branch (so long as the merge would be a fast-forward), see Jefromi's answer to a similar question.
If you don't need the local copy of trunk, you can just merge the upstream one: git merge origin/trunk
, replacing it into your sugested code it ends up as:
(branch) $ git commit -a -m"blah blah blah"
(branch) $ git fetch # origin/trunk is updated
(branch) $ git merge origin/trunk
(branch) $ git push
Try the following:
$ git pull trunk branch
精彩评论