6

Using the same table representation as in git-reset manual page, I have these states in my git repository:

working index HEAD
------------------
 B       B     A

What command will change the states to those?

working index HEAD
------------------
 A       B     A

I other word, I want to "reset" the working directory state to the HEAD state, but without touching the staging area state.

David Froger
  • 645
  • 6
  • 15

5 Answers5

3

As noted in this answer, there is now a native git command which does this:

git restore --source=HEAD --worktree -- .

See the manpage.

Anton Tykhyy
  • 19,370
  • 5
  • 54
  • 56
2

I assume this should work (ordering matters).

You will first need to commit what is in the index (to make the HEAD look like this index and the working directory: B -- using your annotations):

git commit

So, the HEAD will be B (using your annotations).

Now, print the reflog as we will need the hash of B:

git reflog

Now, run a couple of reset commands with different options:

git reset --hard HEAD~ # makes the working directory, the index, and the HEAD looks like this: A, A, A (respectively)
git reset --mixed <hashOfB> # makes the working directory, the index, and the HEAD looks like this: A, B, B (respectively)
git reset --soft HEAD~ # makes the working directory, the index, and the HEAD looks like this: A, B, A (respectively)

I hope this helps.

joker
  • 3,416
  • 2
  • 34
  • 37
1

As discusses in this thread, I thought initially about git checkout but:

FWIW, my understanding of the index is that it is the middle-man for moving things from your work-tree to the object-store AND for moving things from the object-store to your work-tree.
Therefore, when you checkout the blob, it first gets copied from the object-store to your index and then from the index to your work-tree.

So (same thread)

If you want to bypass the index, you can do so with cat-file or show; it just is not a useful operation in a normal workflow of building the next commit on top of the current one, and that is the only reason why there is no option such as "checkout --no-index HEAD~47 path". If somebody can write a convincing use case that shows why it is useful, such an option shouldn't be very hard to add.

git show @:myFile > myFile

You can do that directly from the folder where your file is, with a relative path:

git show @:./myFile > myFile
VonC
  • 1,262,500
  • 529
  • 4,410
  • 5,250
  • For more, see my older answer: http://stackoverflow.com/a/2910431/6309, and http://stackoverflow.com/a/610315/6309 – VonC Sep 09 '16 at 07:50
1

Here is one way to do this on a file by file basis :

# for each staged file :
git show A:path/to/file > path/to/file

git show A:path/to/file will output the content of said file in commit A.


Not exactly what you ask for : using git stash, you can keep a backup of your current index in the stash :

# optional : stash away modifications which are *not* in index
$ git stash --keep-index  

# 'git stash save' is the same as 'git stash',
# it only allows to put a more explicit message
$ git stash save "index while working on A"

$ git stash list
stash@{0}: On master: index while working on A
stash@{1}: WIP on master: 57632bc first

# you can access your index by using stash@{0} :
#   git show stash@{0}:file
#   git checkout stash@{0} .
#   git stash apply
#   etc ...
LeGEC
  • 46,477
  • 5
  • 57
  • 104
  • One flaw with `git show` is that `git show` does not run shown objects through the smudge filters. (It probably should, it's high-level-enough to have all the access it needs.) – torek Sep 09 '16 at 13:02
1

A plumbing way of doing this is to manually backup and restore the index before and after doing git checkout:

cp .git/index .git/index.bak
git checkout HEAD -- .
mv .git/index.bak .git/index
Leon
  • 31,443
  • 4
  • 72
  • 97