Search code examples
gitgit-mergegit-commit

what does git reset HEAD filename do?


I'm on branch-B and I'm trying to merge branch-A into branch-B, but I want to merge all changes except for just one file. After some search, I found this solution:

git merge --no-commit <merge-branch>
git reset HEAD myfile.txt
git checkout -- myfile.txt
git commit -m "merged <merge-branch>"

I got really confused as to the second line: git reset HEAD myfile.txt; What does this line do? How does it help to the goal of merging all except one file?


Solution

  • The thing to remember when using git reset is that git keeps track of two sets of files:

    • Your "working tree", the checked out files you edit directly.
    • The "index", or "staging area", the files that will be committed when you next run git commit, which you generally manage with git add and git rm.

    It also keeps track of what commit you have currently got checked out, as well as which branch.

    git reset has various modes and arguments, which you can look up in the documentation.

    When specified with one or more paths as well as a branch or commit reference (anything "tree-ish", as the git manual puts it), git reset sets those files in the index / staging area to their state at that commit, but doesn't touch the working copy or branch pointer.

    Finally, HEAD refers to whatever commit you currently have checked out.

    So in this case git reset HEAD myfile.txt changes the index to say "when I next commit, please make the content of myfile.txt the same as in the currently checked out commit". In other words, you don't want to commit any changes to that file.

    The next line (git checkout -- myfile.txt) does the same for the working tree. If you run a git status in between, you'll see that all the changes to myfile.txt are listed as "unstaged".