394

In Git, I understand that a branch is a pointer to a commit.

How do I make a specific branch point to a specific commit? Say I want to make master point at 1258f0d0aae..., how do I do that?

2

4 Answers 4

539

You can make master point at 1258f0d0aae this way:

git checkout master
git reset --hard 1258f0d0aae

But you have to be careful about doing this. It may well rewrite the history of that branch. That would create problems if you have published it and other people are working on the branch.

Also, the git reset --hard command will throw away any uncommitted changes (i.e. those just in your working tree or the index).

You can also force an update to a branch with:

git branch -f master 1258f0d0aae

... but git won't let you do that if you're on master at the time.

5
  • 6
    you don't need --hard
    – ahnbizcad
    Commented Feb 5, 2020 at 3:56
  • 9
    git branch -f is useful. It's nice that I can change the branch without checking it out first.
    – remcycles
    Commented Aug 2, 2021 at 2:42
  • 2
    git branch -f <branch> <starting-point> by default sets <branch> to point at <starting-point> and if <starting-point> is also a branch, it sets remote tracking branch to <branch> to branch <starting-point>. To avoid adjustment of remote tracking branch, use extra option --no-track: git branch --no-track -f <branch> <starting-point>
    – czerny
    Commented Apr 11, 2022 at 17:27
  • 1
    I have to look this up about once a month. Really unintuitive command.
    – Dominik
    Commented Apr 21, 2023 at 9:59
  • I noticed the note about it throwing away uncommitted changes after I doing it :( Why not just give a reset command that doesn't do that, it isn't part of the question
    – rakslice
    Commented Jun 24 at 21:12
175

If you are currently not on branch master, that's super easy:

git branch -f master 1258f0d0aae

This does exactly what you want: It points master at the given commit, and does nothing else.

If you are currently on master, you need to get into detached head state first. I'd recommend the following two command sequence:

git checkout 1258f0d0aae    #detach from master
git branch -f master HEAD   #exactly as above

#optionally reattach to master
git checkout master

Be aware, though, that any explicit manipulation of where a branch points has the potential to leave behind commits that are no longer reachable by any branches, and thus become object to garbage collection. So, think before you type git branch -f!


This method is better than the git reset --hard approach, as it does not destroy anything in the index or working directory.

10
  • 12
    This is always what I want when I search for this, and everyone is pushing reset --hard--I almost lost work doing that (thankfully had the stash still). Thank you for the straightforward, "I want to make no other changes" solution.
    – msouth
    Commented Jul 21, 2021 at 18:46
  • It does lose the detached commit. It's not deleted, but you have to find it in reflog. Commented Jan 28, 2022 at 14:32
  • 1
    @JustinTrevein That's exactly the point of the paragraph below the second code block. Also, the method only loses the detached commit if it's not reachable from some other branch, it's not unconditionally lost. But I'll take the hint that my warning was not sufficiently visible and bold up the "think before ..." part. Commented Mar 10, 2022 at 6:10
  • Just go git reset without --hard, then?
    – Gauthier
    Commented Nov 18, 2022 at 21:38
  • @Gauthier Nope. git reset without a mode is equivalent to git reset --mixed, and this will reset the index. I.e. you'll loose any work you may have done for a partial commit. The git checkout/git branch -f/git checkout sequence has the benefit that it's only the git checkout that ever touches your files, and that's generally relatively safe to perform. Much safer than simply forgetting the old index. Commented Nov 18, 2022 at 21:56
53

git branch -f <branchname> <commit>

I go with Mark Longair's solution and comments and recommend anyone reads those before acting, but I'd suggest the emphasis should be on

git branch -f <branchname> <commit>

Here is a scenario where I have needed to do this.

Scenario

Develop on the wrong branch and hence need to reset it.

Start Okay

Cleanly develop and release some software.

So far so good

Develop on wrong branch

Mistake: Accidentally stay on the release branch while developing further.

After a mistake

Realize the mistake

"OH NO! I accidentally developed on the release branch." The workspace is maybe cluttered with half changed files that represent work-in-progress and we really don't want to touch and mess with. We'd just like git to flip a few pointers to keep track of the current state and put that release branch back how it should be.

Create a branch for the development that is up to date holding the work committed so far and switch to it.

git branch development
git checkout development 

Changed to another branch

Correct the branch

Now we are in the problem situation and need its solution! Rectify the mistake (of taking the release branch forward with the development) and put the release branch back how it should be.

Correct the release branch to point back to the last real release.

git branch -f release release2

The release branch is now correct again, like this ...

Corrected

What if I pushed the mistake to a remote?

git push -f <remote> <branch> is well described in another thread, though the word "overwrite" in the title is misleading. Force "git push" to overwrite remote files

48
git reset --hard 1258f0d0aae

But be careful, if the descendant commits between 1258f0d0aae and HEAD are not referenced in other branches it'll be tedious (but not impossible) to recover them, so you'd better to create a "backup" branch at current HEAD, checkout master, and reset to the commit you want.

Also, be sure that you don't have uncommitted changes before a reset --hard, they will be truly lost (no way to recover).

2
  • 7
    In case anyone accidentally does this and needs to undo a few things, see git reflog git-scm.com/docs/git-reflog
    – vmrob
    Commented Jul 7, 2014 at 20:31
  • 18
    and use git push -f to push Commented Jan 7, 2016 at 10:12

Not the answer you're looking for? Browse other questions tagged or ask your own question.