After the last commit, I modified a bunch of files in my working copy, but I want to undo the changes to one of those files, as in reset it to the same state as the most recent commit.
However, I only want to undo the working copy changes of just that one file alone, nothing else with it.
How do I do that?
You can use
git checkout -- file
You can do it without the --
(as suggested by nimrodm), but if the filename looks like a branch or tag (or other revision identifier), it may get confused, so using --
is best.
You can also check out a particular version of a file:
git checkout v1.2.3 -- file # tag v1.2.3
git checkout stable -- file # stable branch
git checkout origin/master -- file # upstream master
git checkout HEAD -- file # the version from the most recent commit
git checkout HEAD^ -- file # the version before the most recent commit
Answered 2023-09-20 21:00:03
git reset HEAD <filename> ; git checkout -- <filename>
- anyone HEAD^^
for 2 commits from the most recent, or HEAD^^^
for 3 commits back. You can also use HEAD~2
, or HEAD~3
, which gets more convenient if you want to go more commits back, while HEAD^2
means "the second parent of this commit"; because of merge commits, a commit can have more than one previous commit, so with HEAD^
a number selects which of those parents, while with HEAD~
a number always selects the first parent but that number of commits back. See git help rev-parse
for more details. - anyone Just use
git checkout filename
This will replace filename with the latest version from the current branch.
WARNING: your changes will be discarded — no backup is kept.
Answered 2023-09-20 21:00:03
git checkout x
and x happens to be a branch name as well as a file name, I'm not sure what the default behavior is but I think git will assume you want to switch to branch x. When you use --
you're saying that what follows is file name(s). - anyone --
from it. While still correct, as @hasen points out, if there is an ambiguity between filename and branch names you may end up with very undesired behavior here! - anyone --
, nice and easy. When you name branches using file names, there must be bad thinking somewhere... - anyone git checkout <commit> <filename>
I used this today because I realized that my favicon had been overwritten a few commits ago when I upgrated to drupal 6.10, so I had to get it back. Here is what I did:
git checkout 088ecd favicon.ico
Answered 2023-09-20 21:00:03
git log --oneline <filename>
will give you a more compact log, and only include changes to the specific file - anyone git reflog <filename>
- anyone If your file is already staged (happens when you do a git add etc after the file is edited) to unstage your changes.
Use
git reset HEAD <file>
Then
git checkout <file>
If not already staged, just use
git checkout <file>
Answered 2023-09-20 21:00:03
I have Done through git bash:
(use "git checkout -- <file>..." to discard changes in working directory)
Answered 2023-09-20 21:00:03
If you want to just undo the previous commit's changes to that one file, you can try this:
git checkout branchname^ filename
This will checkout the file as it was before the last commit. If you want to go a few more commits back, use the branchname~n
notation.
Answered 2023-09-20 21:00:03
branchname^
- anyone Git 2.23 introduced a restore
to do just that, in an attempt, I think, to make the answer to these kind of questions straightforward.
git restore [--] <pathspec>...
As always, the --
could be needed but when a file name starts with a dash. (The confusion with a branch name is not possible here, as restore
's perimeter does not include branches, unlike the do-all checkout
)
To be complete, restore
can also restore staged files with --staged
, and restore from a different commit than HEAD
with --source=<tree>
.
Answered 2023-09-20 21:00:03
git restore .
- anyone This answers is for command needed for undoing local changes which are in multiple specific files in same or multiple folders (or directories). This answers specifically addresses question where a user has more than one file but the user doesn't want to undo all local changes:
if you have one or more files you could apply the same command (
git checkout -- file
) to each of those files by listing each of their location separated by space as in:
git checkout -- name1/name2/fileOne.ext nameA/subFolder/fileTwo.ext
mind the space above between name1/name2/fileOne.ext nameA/subFolder/fileTwo.ext
For multiple files in the same folder:
If you happen to need to discard changes for all of the files in a certain directory, use the git checkout as follows:
git checkout -- name1/name2/*
The asterisk in the above does the trick of undoing all files at that location under name1/name2.
And, similarly the following can undo changes in all files for multiple folders:
git checkout -- name1/name2/* nameA/subFolder/*
again mind the space between name1/name2/* nameA/subFolder/* in the above.
Note: name1, name2, nameA, subFolder - all of these example folder names indicate the folder or package where the file(s) in question may be residing.
Answered 2023-09-20 21:00:03
I always get confused with this, so here is a reminder test case; let's say we have this bash
script to test git
:
set -x
rm -rf test
mkdir test
cd test
git init
git config user.name test
git config user.email test@test.com
echo 1 > a.txt
echo 1 > b.txt
git add *
git commit -m "initial commit"
echo 2 >> b.txt
git add b.txt
git commit -m "second commit"
echo 3 >> b.txt
At this point, the change is not staged in the cache, so git status
is:
$ git status
On branch master
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
modified: b.txt
no changes added to commit (use "git add" and/or "git commit -a")
If from this point, we do git checkout
, the result is this:
$ git checkout HEAD -- b.txt
$ git status
On branch master
nothing to commit, working directory clean
If instead we do git reset
, the result is:
$ git reset HEAD -- b.txt
Unstaged changes after reset:
M b.txt
$ git status
On branch master
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
modified: b.txt
no changes added to commit (use "git add" and/or "git commit -a")
So, in this case - if the changes are not staged, git reset
makes no difference, while git checkout
overwrites the changes.
Now, let's say that the last change from the script above is staged/cached, that is to say we also did git add b.txt
at the end.
In this case, git status
at this point is:
$ git status
On branch master
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
modified: b.txt
If from this point, we do git checkout
, the result is this:
$ git checkout HEAD -- b.txt
$ git status
On branch master
nothing to commit, working directory clean
If instead we do git reset
, the result is:
$ git reset HEAD -- b.txt
Unstaged changes after reset:
M b.txt
$ git status
On branch master
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
modified: b.txt
no changes added to commit (use "git add" and/or "git commit -a")
So, in this case - if the changes are staged, git reset
will basically make staged changes into unstaged changes - while git checkout
will overwrite the changes completely.
Answered 2023-09-20 21:00:03
I restore my files using the SHA id, What i do is git checkout <sha hash id> <file name>
Answered 2023-09-20 21:00:03
git checkout
is the old way of doing this. After the 2020 update the preferred way is:
git restore file.txt
See this duplicate answer (be sure to scroll down to the 2020 update): https://stackoverflow.com/a/31281748/12763497
Answered 2023-09-20 21:00:03
If you have not yet pushed or otherwise shared your commit:
git diff --stat HEAD^...HEAD | \
fgrep filename_snippet_to_revert | cut -d' ' -f2 | xargs git checkout HEAD^ --
git commit -a --amend
Answered 2023-09-20 21:00:03
If it is already committed, you can revert the change for the file and commit again, then squash new commit with last commit.
Answered 2023-09-20 21:00:03
git checkout a3156ae4913a0226caa62d8627e0e9589b33d04c -p */SearchMaster.jsp
Breakdown: a3156ae4913a0226caa62d8627e0e9589b33d04c = This is the hash value of the commit. It's on my own personal branch (not master).
The -p flag is the path.
*/SearchMaster.jsp is the filename.
Answered 2023-09-20 21:00:03