36

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?

Blaise Pascal
  • 915
  • 1
  • 6
  • 14
  • 1
    Does this answer your question? [Merge, update, and pull Git branches without using checkouts](https://stackoverflow.com/questions/3216360/merge-update-and-pull-git-branches-without-using-checkouts) – Genhis Mar 21 '22 at 15:12
  • that's "google-fu" – yano Jan 18 '23 at 17:28

5 Answers5

56

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.

Community
  • 1
  • 1
Oliver
  • 9,239
  • 9
  • 69
  • 100
  • 14
    `git fetch origin trunk:trunk` for the beginners who are not fluent with the generic "upstream" term. – pdem Jan 05 '17 at 14:49
27

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?"

Community
  • 1
  • 1
VonC
  • 1,262,500
  • 529
  • 4,410
  • 5,250
  • 9
    :) I have to say I'm slightly freaked out that you happened to have referred to that post (thanks!) in reply to a user whose namesake is mentioned in its first line... – Mark Longair Feb 28 '11 at 21:28
  • 1
    So your recommendation would be to do "git merge origin/trunk" instead of the checkout/pull/checkout/merge dance? I'll try that the next time this crops up. – Blaise Pascal Feb 28 '11 at 21:39
  • 2
    Using `git fetch upstream trunk:trunk` you can skip the merge and simply fast-forward, using a one-liner. See [my answer](http://stackoverflow.com/a/21601318/177710). – Oliver May 13 '14 at 15:36
  • @Oliver good point, I didn't see your answer at the time (+1). I have included it in my answer for more visibility. – VonC May 13 '14 at 15:41
  • Merging doesn't suit rebasing work in progress scenario, while Oliver's answer does. – mlt Jun 18 '15 at 20:21
8

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.

Community
  • 1
  • 1
Mark Longair
  • 446,582
  • 72
  • 411
  • 327
  • I thought git used to do something very similar to this but when I just checked git-pull.sh in the source I didn't see any indication it still does. – Arrowmaster Feb 28 '11 at 23:43
  • I just used this script - thanks for the tip! I'm surprised this isn't built into `git-merge` though. You'd have thought it's quite a common use case. – mattjgalloway Jul 05 '12 at 17:19
  • 1
    You can do this with `git branch -f master origin/master`, but you don't want to: If it's not a fast-forward merge you'll lose commits and conflicts. – Christopher Aug 15 '12 at 15:40
  • 1
    Over on http://stackoverflow.com/a/4157435/119963 someone pointed me here; I think my script there does the same thing, but is more fleshed out, so you can safely use it as `git merge-ff `. – Cascabel Oct 20 '12 at 15:49
  • @Jefromi: thanks for pointing that out - I've updated my answer with a link to your answer. – Mark Longair Oct 20 '12 at 18:06
  • 1
    You can fast-forward master if you're on another branch with `git fetch` to fetch the remote branch followed by `git fetch . origin/master:master` to fast-forward the tracking branch. (Perhaps that wasn't possible 6 years ago ;-) ) – Bennett McElwee May 07 '19 at 22:42
0

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
Puggan Se
  • 5,738
  • 2
  • 22
  • 48
-5

Try the following:

$ git pull trunk branch
Servy
  • 202,030
  • 26
  • 332
  • 449
Pablitorun
  • 1,035
  • 1
  • 8
  • 18
  • first checkout branch then do git pull git://foo.com/someone/bar.git trunk – Pablitorun Feb 28 '11 at 21:53
  • sll I meant was you should be able to do t his all in one step with pull, but as mentioned above some think this isn't the best idea. – Pablitorun Feb 28 '11 at 21:55
  • Sorry, it does not really answer the question since it merge the current branch with the remote "trunk" branch, We want to merge (fast forward) the local branch "trunk" with the remote branch "trunk" while beeing on any another branch and without modifing it. – pdem Jan 05 '17 at 14:52