5

See title really.

Assuming we're already on the master branch:

What would be the difference between git branch -f master HEAD~ and git reset HEAD~?

As far as I can tell both of these commands move the branch/HEAD pointers one up in the commit chain, but are there any other differences between these two worth noting?

4
  • In the first case you would remain on the current branch, while on the second you would switch to master. Commented Jan 16, 2018 at 16:12
  • Assuming we're already on master. Editing OP to clarify. Commented Jan 16, 2018 at 16:14
  • fatal: Cannot force update the current branch. Commented Jan 16, 2018 at 16:21
  • git branch -f master HEAD~ gets me fatal: Cannot force update the current branch.
    – jingx
    Commented Jan 16, 2018 at 16:22

2 Answers 2

4

Assuming master is the current branch, git branch -f master HEAD~ refuses to do anything and reports the error "fatal: Cannot force update the current branch."

If you are on a different branch, git branch -f master HEAD~ moves the branch master on the first parent of the current branch and does not affect the current branch, the index or the working tree.

git reset HEAD~ is the same as git reset --mixed HEAD~. It moves the current branch on its first parent, updates the index to match the new position of the branch and does not affect the working tree.

As you can see, there are many differences between the two commands.

Please read the documentation of git branch.

Remark: If git branch -f master HEAD~ would work when master is the current branch, its effect would probably be the same as git reset --soft HEAD~. We will never know because this form of git branch refuses to change the branch that is currently checked out.


The OP asked in a comment: "I am also aware that mixed is a default for reset but there are also soft and hard but I don't know the differences."

Scenario:

  1. git checkout master
  2. modify file1
  3. git add file1
  4. git commit

After this steps:

  • git reset --soft HEAD~1 moves only the master branch where it was before the last commit; it brings the repo back to the state where it was after step 3;
  • git reset --mixed HEAD~1 moves the branch and updates the index to match it; it brings the repo to the state it was after step 2;
  • git reset --hard HEAD~1 moves the branch then updates the index and the working tree to match it; it brings the repo to the state it was after step 1.

Of course, this is a simplified explanation and the "brings the repo to the state" parts apply only to this simplified scenario. If you git reset to a different commit then keep only the explanation about what happens to the branch, the index and the working tree and figure out how the repo will look like after each flavour of the git reset command.

10
  • It moves the current branch on its first parent, updates the index to match the new position of the branch and does not affect the working tree. I don't understand what this means. Updates index but not working tree? Commented Jan 16, 2018 at 16:33
  • I am also aware that mixed is a default for reset but there are also soft and hard but I don't know the differences. Commented Jan 16, 2018 at 16:34
  • So branch has an implicit soft whereas reset has implicit mixed? Commented Jan 16, 2018 at 16:55
  • 1
    @user9225276 there is no soft on git branch. You asked what's the difference. git reset --soft moves only the branch and doesn't affect the index and the working tree. git checkout -f also moves only the branch and does not affect the index and the working tree. This is where their similarities end. git reset operates on the current branch. git branch -f refuses to work on the current branch. And git branch doesn't have soft/hard/mixed. Read about git branch and git reset. They do different things.
    – axiac
    Commented Jan 16, 2018 at 17:46
  • This is incorrect. git branch --force <branch> <commit> is equivalent to git switch <branch> && git reset --hard <commit>, not git switch <branch> && git reset --soft <commit> like suggested in this answer, since git branch --force <branch> <commit> does affect the working area and staging area by resetting them to <commit>.
    – Géry Ogam
    Commented Nov 21, 2022 at 18:20
0
git branch --force <branch> <commit>

is equivalent to

git switch <branch> && git reset --hard <commit> && git switch -

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