Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

git reset --hard HEAD vs git checkout <file>

Tags:

git

python

I have a file foo.py. I have made some changes to the working directory, but not staged or commited any changes yet. I know i can use git checkout foo.py to get rid of these changes. I also read about using git reset --hard HEADwhich essentially resets your working directory, staging area and commit history to match the latest commit.

Is there any reason to prefer using one over the other in my case, where my changes are still in working directory?

like image 801
1.618 Avatar asked Oct 17 '17 23:10

1.618


People also ask

What is the difference between git reset and git checkout?

Unlike git reset , git checkout doesn't move any branches around. This is useful for quickly inspecting an old version of your project. However, since there is no branch reference to the current HEAD , this puts you in a detached HEAD state.

What is the difference between git reset filename >' and git checkout filename >' commands?

git checkout master : checkout updates HEAD . It simply makes HEAD point to the master branch instead of the develop branch as it did initially. git reset master : On the other hand, reset will move the branch that HEAD points to. That branch is updated but HEAD still points to the same branch.

What does git reset head -- hard do?

Running git reset --hard ORIG_HEAD will let you go back to where you were, but it will discard your local changes, which you do not want. git reset --merge keeps your local changes.

What does it mean to reset the head git?

The git reset HEAD~2 command moves the current branch backward by two commits, effectively removing the two snapshots we just created from the project history. Remember that this kind of reset should only be used on unpublished commits.


2 Answers

Is there any reason to prefer using one over the other in my case, where my changes are still in working directory?

No, since they will accomplish the same thing.

Is there any reason to prefer using [git checkout -- path/to/file] over [git reset --hard] in [general but not in my specific case]?

Yes: this will affect only the one file. If your habit is git reset --hard to undo changes to one file, and you have work-tree and/or staged changes to other files too, and you git reset --hard, you may be out of luck getting those changes back without reconstructing them by hand.

Note that there is a third construct: git checkout HEAD path/to/file. The difference between this and the one without HEAD (with -- instead1) is that the one with HEAD means copy the version of the file that is in a permanent, unchangeable commit into the index / staging-area first, and then into the work-tree. The one with -- means copy the version of the file that is in the index / staging-area into the work-tree.


1The reason to use -- is to make sure Git never confuses a file name with anything else, like a branch name. For instance, suppose you name a file master, just to be obstinate. What, then, does git checkout master mean? Is it supposed to check out branch master, or extract file master? The -- in git checkout -- master makes it clear to Git—and to humans—that this means "extract file master".


Summary, or, things to keep in mind

There are, at all times, three active copies of each file:

  • one in HEAD;
  • one in the index / staging-area;
  • one in the work-tree.

The git status command looks at all three, comparing HEAD-vs-index first—this gives Git the list of "changes to be committed"—and then index-vs-work-tree second. The second one gives Git the list of "changes not staged for commit".

The git add command copies from the work-tree, into the index.

The git checkout command copies either from HEAD to the index and then the work-tree, or just from the index to the work-tree. So it's a bit complicated, with multiple modes of operation:

  • git checkout -- path/to/file: copies from index to work-tree. What's in HEAD does not matter here. The -- is usually optional, unless the file name looks like a branch name (e.g., a file named master) or an option (e.g., a file named -f).

  • git checkout HEAD -- path/to/file: copies from HEAD commit, to index, then to work-tree. What's in HEAD overwrites what's in the index, which then overwrites what's in the work-tree. The -- is usually optional, unless the file name looks like an option (e.g., -f).

    It's wise to use the -- always, just as a good habit.

The git reset command is complicated (it has many modes of operation).

(This is not to say that git checkout is simple: it, too, has many modes of operation, probably too many. But I think git reset is at least a little bit worse.)

like image 65
torek Avatar answered Sep 21 '22 04:09

torek


Maybe this can help :

git data transport commands git reset --hard

Source : https://www.patrickzahnd.ch

like image 38
Jack' Avatar answered Sep 19 '22 04:09

Jack'