Konstantin
Konstantin

Reputation: 25339

How can I get working directory content as it was at specific commit

I have a git repository with some commits in it. I want to reproduce exact state of working directory as it was right after specific commit (Here i suppose that i've commited all changes that were made).

I tried to use git checkout, but this command doesn't delete existing files (which were added after desired commit) in working directory.

Simple example to illustrate my problem. I prepared repository using following commands

u@u-desktop:/tmp/git$ git init
Initialized empty Git repository in /tmp/git/.git/

u@u-desktop:/tmp/git$ echo 'ffff' > first.file
u@u-desktop:/tmp/git$ git add first.file
u@u-desktop:/tmp/git$ git commit -m "Important file was added"
[master (root-commit) fb05f7e] Important file was added
 1 files changed, 1 insertions(+), 0 deletions(-)
 create mode 100644 first.file

u@u-desktop:/tmp/git$ echo 'Second line' >> first.file 
u@u-desktop:/tmp/git$ git commit -m "Important data was added" -a
[master df93d04] Important data was added
 1 files changed, 1 insertions(+), 0 deletions(-)

u@u-desktop:/tmp/git$ echo 'ssss' > second.file
u@u-desktop:/tmp/git$ git add second.file
u@u-desktop:/tmp/git$ git commit -m "Second important file was added"
[master b6c106a] Second important file was added
 1 files changed, 1 insertions(+), 0 deletions(-)
 create mode 100644 second.file

u@u-desktop:/tmp/git$ echo 'tttt' > third.file
u@u-desktop:/tmp/git$ git add third.file
u@u-desktop:/tmp/git$ git commit -m "Third important file was added"
[master 33fce06] Third important file was added
 1 files changed, 1 insertions(+), 0 deletions(-)
 create mode 100644 third.file

Right now directory looks like this

u@u-desktop:/tmp/git$ ls
first.file  second.file  third.file

first.file has following content

u@u-desktop:/tmp/git$ cat first.file 
ffff
Second line

Now i want restore working directory as it looked right after first commit (fb05f7e)

u@u-desktop:/tmp/git$ git checkout fb05f7e .
u@u-desktop:/tmp/git$ cat first.file 
ffff

But second.file and third.file are still in the directory

u@u-desktop:/tmp/git$ ls
first.file  second.file  third.file

Upvotes: 1

Views: 1150

Answers (2)

Mark Longair
Mark Longair

Reputation: 467321

Just do:

git checkout fb05f7e

... i.e. without specifying the current directory (.) as the path to checkout. You'll find that second.file and third.file are removed as you expect.

The reason for this is that git checkout has two very different modes of operation, depending on whether you supply a path or not. If you do supply a path it doesn't change HEAD at all, it just

... updates the named paths in the working tree from the index file, or from a named <tree-ish> (most often a commit)

(That's from the git checkout documentation). This only updates the paths that were actually present in that other commit.

Upvotes: 4

Francois G
Francois G

Reputation: 11985

Remove the . in your git checkout. Selections from the man page:

   git checkout [<branch>], git checkout -b|-B <new_branch> [<start
     point>], git checkout [--detach] [<commit>]
       This form switches branches by updating the index, working tree,
       and HEAD to reflect the specified branch or commit.

       (...)

   git checkout [-p|--patch] [<tree-ish>] [--] <pathspec>...
       When <paths> or --patch are given, git checkout does not switch
       branches. It updates the named paths in the working tree from the
       index file or from a named <tree-ish> (most often a commit).

If, moreover you want to remove files that are not checked in the index, use git clean (read the man page, there's an "anti-oops" option you'll have to pass on the command line for it to work).

Upvotes: 4

Related Questions