David Froger
David Froger

Reputation: 665

git "reset" workdir to HEAD without touching staging area

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.

Upvotes: 6

Views: 525

Answers (5)

Anton Tykhyy
Anton Tykhyy

Reputation: 20076

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

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

See the manpage.

Upvotes: 4

joker
joker

Reputation: 3752

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.

Upvotes: 2

Leon
Leon

Reputation: 32484

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

Upvotes: 1

LeGEC
LeGEC

Reputation: 51870

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 ...

Upvotes: 1

VonC
VonC

Reputation: 1324937

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

Upvotes: 1

Related Questions