Thursday, January 30, 2020

git - revert a file to older version away by few commits

Lets's say there is config.cfg on which 6 commits have been done. We need to revert the file to version as it was on 2nd commit.


Latest git repository looks like this after committing 6 changes:

 $ cd myapp                         
$ git init                             
Initialized empty Git repository in myapp/.git/

$ for i in 1 2 3 4 5 6               
do                                 
  echo $i >>config.cfg                 
  echo $i >>static.cfg               
  git add config.cfg static.cfg
  git commit -m "Commiting version $i"
done

[master (root-commit) 9b0d011] Commiting version 1
2 files changed, 2 insertions(+)
create mode 100644 config.cfg
create mode 100644 static.cfg
[master 68387a7] Commiting version 2
2 files changed, 2 insertions(+)
[master c16b5bb] Commiting version 3
2 files changed, 2 insertions(+)
[master 405f4c4] Commiting version 4
2 files changed, 2 insertions(+)
[master 768bb51] Commiting version 5
2 files changed, 2 insertions(+)
[master 45a8393] Commiting version 6
2 files changed, 2 insertions(+)

Version 6 of config.cfg file looks like this:

$ cat config.cfg 
1
2
3
4
5
6
$ cat static.cfg
1
2
3
4
5
6

git repository commit log look like this at this stage

$ git log --oneline 
45a8393 (HEAD -> master) Committing version 6     
768bb51 Commiting version 5                                   405f4c4 Commiting version 4                                 
c16b5bb Commiting version 3                                 
68387a7 Commiting version 2                                 
9b0d011 Commiting version 1                                                                                                          

Attempt to revert to version 2 commit fails as there are few more commit on config.cfg between version 2 and version 6.

$ git revert 68387a7   
error: could not revert 68387a7... Commiting version 2  
hint: after resolving the conflicts, mark the corrected paths 
hint: with 'git add ' or 'git rm '  
hint: and commit the result with 'git commit'                                                                                         
$ git status       
On branch master   
You are currently reverting commit 68387a7.                 
  (fix conflicts and run "git revert --continue")           
  (use "git revert --abort" to cancel the revert operation)    Changes to be committed:                                        (use "git reset HEAD ..." to unstage)                  (use "git add ..." to mark resolution)
both modified:   static.cfg

The correct way to revert to version 2 of config file is:
  1- checkout config.cfg file from version 2 commit 
  2- Check status and verify that checked out file in staging area is modified and it looks same as version 2 file
  3- commit this file on top of HEAD commit 45a8393

$ git status
On branch master
nothing to commit, working tree clean
$ git checkout 68387a7 config.cfg
$ git status
On branch master
Changes to be committed:
  (use "git reset HEAD ..." to unstage)
modified:   config.cfg

$ cat config.cfg 
1
2
$ git commit -m'Commit config file as version 2'
[master f30f027] Commit config file as version 2
1 file changed, 4 deletions(-)

        $ git log --oneline
f30f027 (HEAD -> master) Commit config file as version 2
45a8393 Commiting version 6
768bb51 Commiting version 5
405f4c4 Commiting version 4
c16b5bb Commiting version 3
68387a7 Commiting version 2
9b0d011 Commiting version 1

$ git status
On branch master
nothing to commit, working tree clean

Verify that config.cfg has been reverted back to same as version 2 and there is no change in any other file

$ cat config.cfg 
1
2
$ cat static.cfg 
1
2
3
4
5
6


Share if you know a better way!