310

I switched to master after developing on a branch for a long time. The log shows:

Your branch is behind 'origin/master' by 167 commits, and can be fast-forwarded.

I tried:

git checkout HEAD

It doesn't have any effect. This is because I have checked out an intermediate commit on master.

How can I make master stay on head?

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
pengguang001
  • 4,045
  • 6
  • 27
  • 31

12 Answers12

425

Try git merge origin/master. If you want to be sure that it only does a fast-forward, you can say git merge --ff-only origin/master.

rob mayoff
  • 375,296
  • 67
  • 796
  • 848
  • 4
    This is nice to use when your remote has some authentication hoops to jump through. When I pull in one branch, I have to authenticate. Then, when I switch to another branch (i.e., to cherry-pick my changes), I prefer using this `merge` command so that I don't have to re-authenticate. – RustyTheBoyRobot Dec 09 '13 at 20:07
  • 41
    `--ff-only` is extremely useful. – Luke Jan 06 '15 at 14:09
  • 6
    I don't know if the `origin/master` portion is required or if it sensibly defaults, but I found it useful to make an alias for fast forward so I wanted to make sure the upstream branch is used instead of hard coding it to `origin/master`: `ff = merge --ff-only @{u}` (`@{u}` is upstream). – Vala Apr 02 '15 at 09:29
  • 3
    thats better than suggested answer if you are offline – Jacek Pietal Aug 11 '16 at 10:18
  • 1
    Could you explain why a simple pull doesn't do the same thing? Also, is pull still needed if we do this? – Zuzu Corneliu Apr 04 '19 at 09:32
  • 1
    @CorneliuZuzu - the question was how to fast forward. A simple pull command may not fast forward. Especially if you are trying to fast forward a different branch. Let's say you are in brach foo and you want to fast forward it to the head of origin/bar. – nagylzs Sep 27 '19 at 16:17
272

Doing:

git checkout master
git pull origin

will fetch and merge the origin/master branch (you may just say git pull as origin is the default).

Greg Hewgill
  • 951,095
  • 183
  • 1,149
  • 1,285
  • 58
    I think Rob's answer is better. I usually encounter this situation where I have *just finished pulling* and then I switch to a different branch, which needs to be fast-forwarded. It's annoying to me if I have to do another (no-op) pull and wait for it to complete; doing a local-only operation is faster and is what I want anyway. –  May 09 '13 at 18:09
  • @BaronSchwartz : Does it mean that when you switch to the other branch, it will have been fast-forwarded on it's own when I run `git merge --ff-only origin/master` from the **master** branch and I don't have to `pull` it again? – aspiring1 May 30 '21 at 12:12
44

In your situation, git rebase would also do the trick. Since you have no changes that master doesn't have, git will just fast-forward. If you are working with a rebase workflow, that might be more advisable, as you wouldn't end up with a merge commit if you mess up.

username@workstation:~/work$ git status
# On branch master
# Your branch is behind 'origin/master' by 1 commit, and can be fast-forwarded.
#   (use "git pull" to update your local branch)
#
nothing to commit, working directory clean
username@workstation:~/work$ git rebase
First, rewinding head to replay your work on top of it...
Fast-forwarded master to refs/remotes/origin/master.
# On branch master
nothing to commit, working directory clean
voidvector
  • 1,976
  • 2
  • 18
  • 19
  • 2
    And very useful for me as we are not supposed to use git pull! – Stefan Sep 05 '14 at 09:30
  • 1
    Even if you have some change pending, you can always stash and rebase, i don't know if this is the 'proper' way but works wonders. – fn. Nov 23 '15 at 10:28
  • To add some insight to @Stefan's statement, `git pull` has [some problems](https://stackoverflow.com/q/15316601/6353323) that informed employers (or just git projects) would rather not deal with. In particular, it leaves a merge commit. The downsides to that, however, really just come to personal (or the employer's personal) taste. – Lazerbeak12345 Feb 11 '22 at 03:36
29
git checkout master
git pull

should do the job.

You will get the "Your branch is behind" message every time when you work on a branch different than master, someone does changes to master and you git pull.

(branch) $ //hack hack hack, while someone push the changes to origin/master
(branch) $ git pull   

now the origin/master reference is pulled, but your master is not merged with it

(branch) $ git checkout master
(master) $ 

now master is behind origin/master and can be fast forwarded

this will pull and merge (so merge also newer commits to origin/master)
(master) $ git pull 

this will just merge what you have already pulled
(master) $ git merge origin/master

now your master and origin/master are in sync

Kuba
  • 2,986
  • 2
  • 26
  • 32
25

To anyone who wants to fast-forward, they are not on to another remote branch (including itself) without checking out that branch. You can do:

git fetch origin master:other

This basically fast forwards the index of other to origin/master if you are not on other branch. You can fast forward multiple branches this way.

If you are working on another branch for some time, and want to update stale branches from remote to their respective head:

git fetch origin master:master other:other etc:etc
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Sunny Patel
  • 7,830
  • 2
  • 31
  • 46
14

If you are standing on a different branch and want to checkout the newest version of master you can also do

git checkout -B master origin/master

jontro
  • 10,241
  • 6
  • 46
  • 71
13

In your case, to fast-forward, run:

$ git merge --ff-only origin/master

This uses the --ff-only option of git merge, as the question specifically asks for "fast-forward".

Here is an excerpt from git-merge(1) that shows more fast-forward options:

--ff, --no-ff, --ff-only
    Specifies how a merge is handled when the merged-in history is already a descendant of the current history.  --ff is the default unless merging an annotated
    (and possibly signed) tag that is not stored in its natural place in the refs/tags/ hierarchy, in which case --no-ff is assumed.

    With --ff, when possible resolve the merge as a fast-forward (only update the branch pointer to match the merged branch; do not create a merge commit). When
    not possible (when the merged-in history is not a descendant of the current history), create a merge commit.

    With --no-ff, create a merge commit in all cases, even when the merge could instead be resolved as a fast-forward.

    With --ff-only, resolve the merge as a fast-forward when possible. When not possible, refuse to merge and exit with a non-zero status.

I fast-forward often enough that it warranted an alias:

$ git config --global alias.ff 'merge --ff-only @{upstream}'

Now I can run this to fast-forward:

$ git ff
aude
  • 1,372
  • 16
  • 20
3

To rebase the current local tracker branch moving local changes on top of the latest remote state:

git fetch && git rebase

More generally, to fast-forward and drop the local changes (hard reset)*:

git fetch && git checkout ${the_branch_name} && git reset --hard origin/${the_branch_name}

To fast-forward and keep the local changes (rebase):

git fetch && git checkout ${the_branch_name} && git rebase origin/${the_branch_name}

* - to undo the change caused by an unintentional hard reset, first do git reflog. That displays the state of the HEAD in reverse order. Find the hash the HEAD was pointing to before the reset operation (usually obvious) and hard reset the branch to that hash.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
bobah
  • 18,364
  • 2
  • 37
  • 70
2

Complexities aren't required. Just stand at your branch and do a git pull. It worked for me.

Or, as a second try, git pull origin master. But only in case if you are unlucky with the first command.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
2

In cases where you're somewhere behind on a branch,
it is safer to rebase any local changes you may have:

git pull --rebase

This helps prevent unnecessary merge-commits.

(This is the same as doing git fetch && git rebase.)

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Gonen
  • 4,005
  • 1
  • 31
  • 39
0

In my way, it returns all changed to head and is the fast way:

git fetch origin master
git reset --hard FETCH_HEAD
git clean -df
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Vahid Alvandi
  • 588
  • 9
  • 17
-4

Move your branch pointer to the HEAD:

git branch -f master

Your branch master already exists, so Git will not allow you to overwrite it, unless you use... -f (this argument stands for --force)

Or you can use rebase:

git rebase HEAD master

Do it at your own risk ;)

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Do Async
  • 4,081
  • 1
  • 22
  • 25
  • 5
    Do not attempt this. if you have following situation bad things will happen: C0 --- C1 --- C2 --- C3 --- C4(master). C0 --- C1 --- C2 --- B1 --- B2 --- B3(dev) If your Head is at B3(dev) and you do git branch -f master, you will end up with C0 --- C1 --- C2 --- B1 --- B2 --- B3(dev)(master). C3 --- C4 are not reachable from any branch and eventually will be garbage collected. If you find yourself in this situation look at reflog and checkout C4 commit with -b option to create a new branch. – A_P Dec 28 '18 at 19:49