19

As I know, to get old version of some file I need input:

git checkout COMMIT-HASH -- file-name.ext

But if I wont to get all modified files from some commit? Can I input something like:

git checkout COMMIT-HASH -- *

P.S. I know that I can list files manually, but it's not convenient if there are many files.

Zoe
  • 27,060
  • 21
  • 118
  • 148
valior
  • 449
  • 2
  • 4
  • 8

4 Answers4

22

If I understand what you are asking correctly, I think one of these two will do the job:

git reset --merge <commit>

or

git checkout <commit> -- .

If there are files currently in your working directory that are not in <commit>, they will still be there, which might confuse things, depending on exactly why you want to do this. One alternative to get a clean working tree that is only the contents of <commit> would be this:

rm -r *
git archive --format=tar <commit> | tar xf -

For that matter, you could just empty your worktree before the git reset or git checkout commands above, as well...

None of these will actually move your HEAD, which I think is the effect you are trying to achieve...

twalberg
  • 59,951
  • 11
  • 89
  • 84
  • 2
    I believe that OP's question is resolved with `git checkout -- .`. He does not seem to intend to move the current branch, so `git reset --merge ` will not help. – ShaoWei Teo Feb 20 '18 at 06:22
  • 1
    @ShaoWeiTeo OK but that doesn't delete files. – Asclepius Dec 13 '19 at 22:12
  • you can delete files first then checkout. `git reset ` moves the branch head and may cause unexpected things. – hychou Apr 10 '20 at 04:32
  • I am not sure what I am doing wrong, but none of the suggestions here helped me. I want to create a new blank branch, and checkout the changes made in a given commit. I have created the blank branch, but I am unable to bring the changed files only, how I can do that? – tarekahf Jan 26 '22 at 22:41
2

I believe this SO question may be of use: How to list all the files in a commit?

Basically, to get a listing of the files, you can use git diff-tree:

git diff-tree --no-commit-id --name-only -r COMMIT_ID

Once you have that, you can feed it to git checkout:

git diff-tree --no-commit-id --name-only -r COMMIT_ID | \
    xargs git checkout COMMIT_ID --

So, the git diff-tree will help get the list of files, and the xargs git checkout COMMIT_ID -- will help reset the affected files back to the state they were in at that commit (you're only rolling back those particular files).

You probably need to do this at the top of your working tree. Also, I didn't try seeing what would happen if there's a rename involved, so there is likely another edge case you might need to consider. Spaces in path names could be a problem here too, but I didn't see a way to get the paths in a null-terminated format with git diff-tree. Perhaps git diff would be better in that case:

git diff --name-only -z COMMIT_ID^ COMMIT_ID | \
    xargs -0 git checkout COMMIT_ID --

Also, if you really want to go back in that way and there's really only one commit that's the issue, perhaps git revert would be a better way to go about it.

Community
  • 1
  • 1
John Szakmeister
  • 44,691
  • 9
  • 89
  • 79
  • Thanks, your link helps me. Final command that I need is: 'git show COMMIT_ID | patch -p1' – valior Jun 02 '14 at 08:28
  • Interesting... that's re-applying a commit, which is different that your question. :-) Glad you found what you needed though. – John Szakmeister Jun 02 '14 at 08:33
  • I want to do the same, but I am on Windows machine using PowerShell, could you please help me? I am not sure how to use `xargs` nor `patch` commands on Windows. – tarekahf Jan 26 '22 at 22:48
  • I create another question here: https://stackoverflow.com/a/23960193/4180447. I hope you can help me with the solution. – tarekahf Jan 26 '22 at 23:08
  • @tarekahf Your link appears to take me to the same question. You'll need to point me at the new question as I'm not sure what it is you're trying to do. – John Szakmeister Jan 27 '22 at 18:59
1

How about cherry-pick without commit

git cherry-pick COMMIT-HASH --no-commit
jasperjian
  • 383
  • 4
  • 6
  • 3
    This would apply changes from `COMMIT-HASH`, but it would not give you the exact files from that commit. Upstream changes from the target commit would not be included. I believe OP wants to update their workspace with all the files from the target commit. – Spark Feb 18 '20 at 23:05
-4

Just don't pass the filename at all.

git checkout COMMIT-HASH 
SLaks
  • 868,454
  • 176
  • 1,908
  • 1,964
  • 4
    This command moves HEAD to this COMMIT-HASH. I need something like git revert && git reset --mixed HEAD~1 but without resolve any conflicts. Just all files from that commit in that state and opportunity watch diff current and those state. – valior May 30 '14 at 14:19
  • IIRC, there is a flag to pass to `git reset` that will do that. – SLaks May 30 '14 at 14:22