Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Git checkout all files from exact commit

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.

like image 864
valior Avatar asked May 30 '14 14:05

valior


People also ask

Can you checkout a specific commit?

Checkout From Specific Git Commit ID Follow the steps to checkout from a specific commit id. Step 1: Clone the repository or fetch all the latest changes and commits. Step 2: Get the commit ID (SHA) that you want to checkout. From your local repository, you can get the commit SHA from the log.

How do you get a file from another commit?

Every commit message has a hash value next to the commit. You can use a similar command to checkout a file from a previous commit. Look at the git log and find the commit with the hash value where you want to grab the file.


2 Answers

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

like image 118
twalberg Avatar answered Sep 21 '22 10:09

twalberg


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.

like image 29
John Szakmeister Avatar answered Sep 20 '22 10:09

John Szakmeister