remove - Reset or revert a specific file to a specific revision using Git?




revert commit on specific file (20)

git-aliases, awk and shell-functions to the rescue!

git prevision <N> <filename>

where <N> is the number of revisions of the file to rollback for file <filename>.
For example, to checkout the immediate previous revision of a single file x/y/z.c, run

git prevision -1 x/y/z.c

How git prevision works?

Add the following to your gitconfig

[alias]
        prevision = "!f() { git checkout `git log --oneline $2 |  awk -v commit="$1" 'FNR == -commit+1 {print $1}'` $2;} ;f"

The command basically

  • performs a git log on the specified file and
  • picks the appropriate commit-id in the history of the file and
  • executes a git checkout to the commit-id for the specified file.

Essentially, all that one would manually do in this situation,
wrapped-up in one beautiful, efficient git-alias - git-prevision

I have made some changes to a file which has been committed a few times as part of a group of files, but now want to reset/revert the changes on it back to a previous version.

I have done a git log along with a git diff to find the revision I need, but just have no idea how to get the file back to its former state in the past.


You can do it in 4 steps:

  1. revert the entire commit with the file you want to specifically revert - it will create a new commit on your branch
  2. soft reset that commit - removes the commit and moves the changes to the working area
  3. handpick the files to revert and commit them
  4. drop all other files in your work area

What you need to type in your terminal:

  1. git revert <commit_hash>
  2. git reset HEAD~1
  3. git add <file_i_want_to_revert> && git commit -m 'reverting file'
  4. git checkout .

good luck


And to revert to last committed version, which is most frequently needed, you can use this simpler command.

git checkout HEAD file/to/restore

Assuming the hash of the commit you want is c5f567:

git checkout c5f567 -- file1/to/restore file2/to/restore

The git checkout man page gives more information.

If you want to revert to the commit before c5f567, append ~1 (works with any number):

git checkout c5f567~1 -- file1/to/restore file2/to/restore

As a side note, I've always been uncomfortable with this command because it's used for both ordinary things (changing between branches) and unusual, destructive things (discarding changes in the working directory).


For me none of the reply seemed really clear and therefore I would like to add mine which seems super easy.

I have a commit abc1 and after it I have done several (or one modification) to a file file.txt.

Now say that I messed up something in the file file.txt and I want to go back to a previous commit abc1.

1.git checkout file.txt : this will remove local changes, if you don't need them

2.git checkout abc1 file.txt : this will bring your file to your wanted version

3.git commit -m "Restored file.txt to version abc1" : this will commit your reversion.

  1. git push : this will push everything on the remote repository

Between the step 2 and 3 of course you can do git status to understand what is going on. Usually you should see the file.txt already added and that is why there is no need of a git add.


Here is my way.

a) In Android Studio, open the file.

b) git -> Show History, find the previous commit I want to revert to. Get the commit_id (i.e. commit hash).

c) git checkout commit_id file_path


I had the same issue just now and I found this answer easiest to understand (commit-ref is the SHA value of the change in the log you want to go back to):

git checkout [commit-ref] [filename]

This will put that old version in your working directory and from there you can commit it if you want.


I have to plug EasyGit here, which is a wrapper to make git more approachable to novices without confusing seasoned users. One of the things it does is give more meanings to git revert. In this case, you would simply say:

eg revert foo/bar foo/baz


If you know how many commits you need to go back, you can use:

git checkout master~5 image.png

This assumes that you're on the master branch, and the version you want is 5 commits back.


If you're using Git Extensions and you only want to revert to the parent commit for the file, you can select the commit that contains the changes you want to revert, then select the 'Diff' tab in the details pane, right-click the file you want to revert, then 'Reset file(s) to' ...., then 'A' (the parent)


In the case that you want to revert a file to a previous commit (and the file you want to revert already committed) you can use

git checkout HEAD^1 path/to/file

or

git checkout HEAD~1 path/to/file

Then just stage and commit the "new" version.

Armed with the knowledge that a commit can have two parents in the case of a merge, you should know that HEAD^1 is the first parent and HEAD~1 is the second parent.

Either will work if there is only one parent in the tree.


Many answers here claims to use git reset ... <file> or git checkout ... <file> but by doing so, you will loose every modifications on <file> committed after the commit you want to revert.

If you want to revert changes from one commit on a single file only, just as git revert would do but only for one file (or say a subset of the commit files), I suggest to use both git diff and git apply like that (with <sha> = the hash of the commit you want to revert) :

git diff <sha>^ <sha> path/to/file.ext | git apply -R

Basically, it will first generate a patch corresponding to the changes you want to revert, and then reverse-apply the patch to drop those changes.

Of course, it shall not work if reverted lines had been modified by any commit between <sha1> and HEAD (conflict).


Note, however, that git checkout ./foo and git checkout HEAD ./foo are not exactly the same thing; case in point:

$ echo A > foo
$ git add foo
$ git commit -m 'A' foo
Created commit a1f085f: A
1 files changed, 1 insertions(+), 0 deletions(-)
create mode 100644 foo
$ echo B >> foo
$ git add foo
$ echo C >> foo
$ cat foo
A
B
C
$ git checkout ./foo
$ cat foo
A
B
$ git checkout HEAD ./foo
$ cat foo
A

(The second add stages the file in the index, but it does not get committed.)

Git checkout ./foo means revert path ./foo from the index; adding HEAD instructs Git to revert that path in the index to its HEAD revision before doing so.


Obviously someone either needs to write an intelligible book on git, or git needs to be better explained in the documentation. Faced with this same problem I guessed that

cd <working copy>
git revert master

would undo the last commit which is seemed to do.

Ian


Use git log to obtain the hash key for specific version and then use git checkout <hashkey>

Note: Do not forget to type the hash before the last one. Last hash points your current position (HEAD) and changes nothing.


You can quickly review the changes made to a file using the diff command:

git diff <commit hash> <filename>

Then to revert a specific file to that commit use the reset command:

git reset <commit hash> <filename>

You may need to use the --hard option if you have local modifications.

A good workflow for managaging waypoints is to use tags to cleanly mark points in your timeline. I can't quite understand your last sentence but what you may want is diverge a branch from a previous point in time. To do this, use the handy checkout command:

git checkout <commit hash>
git checkout -b <new branch name>

You can then rebase that against your mainline when you are ready to merge those changes:

git checkout <my branch>
git rebase master
git checkout master
git merge <my branch>

You have to be careful when you say "rollback". If you used to have one version of a file in commit $A, and then later made two changes in two separate commits $B and $C (so what you are seeing is the third iteration of the file), and if you say "I want to roll back to the first one", do you really mean it?

If you want to get rid of the changes both the second and the third iteration, it is very simple:

$ git checkout $A file

and then you commit the result. The command asks "I want to check out the file from the state recorded by the commit $A".

On the other hand, what you meant is to get rid of the change the second iteration (i.e. commit $B) brought in, while keeping what commit $C did to the file, you would want to revert $B

$ git revert $B

Note that whoever created commit $B may not have been very disciplined and may have committed totally unrelated change in the same commit, and this revert may touch files other than file you see offending changes, so you may want to check the result carefully after doing so.


git checkout ref|commitHash -- filePath

e.g.

git checkout HEAD~5 -- foo.bar
or 
git checkout 048ee28 -- foo.bar

git checkout -- foo

That will reset foo to HEAD. You can also:

git checkout HEAD^ foo

for one revision back, etc.


git revert <hash>

Will revert a given commit. It sounds like you think git revert only affects the most recent commit.

That doesn't solve your problem, if you want to revert a change in a specific file and that commit changed more than that file.





version-control