Working with Git: How to move between commits,  undo the changes made and ignore the files?
Git Checkout, Git Revert and Git Reset, Git Ignore

Working with Git: How to move between commits, undo the changes made and ignore the files? Git Checkout, Git Revert and Git Reset, Git Ignore

Moving between commits: Git Checkout

git checkout lets you move between the commits and view the changes that have been made.

Point to remember: git checkout does not delete the commits, instead it displays the files checked out at that point in time.

Syntax: git checkout [commit id]

(i) Consider the following git log

elcot@elcot-PC MINGW32 /d/GitRepository (master)
$ git log --oneline
ca82979 (HEAD -> master) Deleted python file
b967404 Added text to website.html
7795cdf Added text to file1.txt
f15f9b2 Created empty textfile, python file, html file
  • File status as of the last commit in the Project Folder:
    1. Written text file
    2. HTML File
    3. Deleted Python File

image.png

(ii) On executing the git checkout command,

elcot@elcot-PC MINGW32 /d/GitRepository (master)
$ git checkout 7795cdf
Note: switching to '7795cdf'.
  • The (HEAD-->master) is now in detached state.
  • HEAD is now at 7795cdf Added text to file1.txt

This way you can move between commits, and view the status of the files in that state of the commit.

image.png

Finally, git checkout master moves the HEAD back to the last commit.

elcot@elcot-PC MINGW32 /d/GitRepository ((7795cdf...))
$ git checkout master
Previous HEAD position was 7795cdf Added text to file1.txt
Switched to branch 'master'

Undoing Changes: Git Revert and Git Reset

One of the most important features of a version control system is to move back in time and rectify the errors made. Git gives the support and the ability to move to any point in time to undo the changes.

Whilst, git checkout allows you to move between the commits, view the status of the files at that point in time, and does not delete the commits.

git revert and git reset are used to go back in time and undo the previous commits.

Git Revert

git revert command is used to undo the changes only in the specific commit, (usually a single commit) and revert the changes in the new commit.
The state of the other commits will remain unchanged.

Syntax: git revert [commit ID]

For example, If the past commit created the code.py file in your local repository,
Then, a git revert will delete code.py from your local repository.

git revert [commit ID] - opens a VIM text editor.

elcot@elcot-PC MINGW32 /d/GitRepository (master)
$ git revert 9da569c

To exit VIM editor, press : to enter the command mode,
then q to quit and press ENTER key.

image.png

After VIM editor closes, the commit is updated with a message.

elcot@elcot-PC MINGW32 /d/GitRepository (master)
$ git log --oneline
49b850a (HEAD -> master) Revert "Created a python file"

image.png

Alternatively, if you don't want to enter VIM editor, execute
git revert [commit ID] --no-edit

This option also prevents entering a commit message.

image.png

Git Reset

git reset is used to undo changes between multiple commits and deletes the previous commits.

Working of a Git Tree

image.png

Types of Git Reset

  1. git reset --soft - keeps all the changes and moves the files to the Staging area.
  2. git reset --mixed - works by default, keeps all the changes, and moves the files to the Working directory.
  3. git reset --hard - completely destroys all the changes and moves to the old commit, bringing back all the working files in the local repository.

Consider the following git log

elcot@elcot-PC MINGW32 /d/GitRepository (master)
$ git log --oneline
0794bd6 (HEAD -> master) Revert "Added text in table.csv"
275e1ea Revert "Created a python file"
2997665 Added text in website.html
9da569c Created a python file
da9b506 Added text in table.csv
22cd1a8 Added text in file1.txt
672d0d8 Created a new text, html and csv file

Let us remove the Revert Commits and make the commit history clean. Consider going back to the commit,
2997665 Added text in website.html which has all 4 files in the working directory.

1. git reset --soft

git reset --soft can go back in commits, but it does not remove any changes you have made. The changes remain in place and the files enter the staging area where you can add or delete, make the necessary changes and then make a new commit.

Executing: git reset --soft

elcot@elcot-PC MINGW32 /d/GitRepository (master)
$ git reset --soft 2997665
  • The HEAD pointer has been moved to the mentioned commit
elcot@elcot-PC MINGW32 /d/GitRepository (master)
$ git log --oneline
2997665 (HEAD -> master) Added text in website.html
9da569c Created a python file
da9b506 Added text in table.csv
22cd1a8 Added text in file1.txt
672d0d8 Created a new text, html and csv file
  • The changes remain in place.
  • The files are in Staging Area and are ready to be committed.
elcot@elcot-PC MINGW32 /d/GitRepository (master)
$ git status
On branch master
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
        deleted:    code.py
        modified:   table.csv
  • You can add/remove and make any changes to the files and then make a new commit.
elcot@elcot-PC MINGW32 /d/GitRepository (master)
$ git log --oneline
68a9a94 (HEAD -> master) Soft reset - Added code.py and added text to table.csv
2997665 Added text in website.html
9da569c Created a python file
da9b506 Added text in table.csv
22cd1a8 Added text in file1.txt
672d0d8 Created a new text, html and csv file

2. git reset --mixed

git reset --mixed is the default reset command. In mixed reset, the changes made also remain in place but the files are moved to the Working Directory. If you want to commit, you can re-add the files to Staging Area, make the necessary changes, and then commit.

Executing: git reset --mixed

  • The previously made changes are updated.
elcot@elcot-PC MINGW32 /d/GitRepository (master)
$ git reset --mixed 2997665
Unstaged changes after reset:
D       code.py
M       table.csv
  • The changes remain and files are moved to the Working Directory.
elcot@elcot-PC MINGW32 /d/GitRepository (master)
$ git status
On branch master
Changes not staged for commit:
  (use "git add/rm <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
        deleted:    code.py
        modified:   table.csv

no changes added to commit (use "git add" and/or "git commit -a")
  • You can add/remove and make any changes to the files and then make a new commit.
elcot@elcot-PC MINGW32 /d/GitRepository (master)
$ git commit -a -m "Mixed reset "
[master 78ee12f] Mixed reset
 2 files changed, 1 deletion(-)
 delete mode 100644 code.py

elcot@elcot-PC MINGW32 /d/GitRepository (master)
$ git log --oneline
78ee12f (HEAD -> master) Mixed reset
2997665 Added text in website.html
9da569c Created a python file
da9b506 Added text in table.csv
22cd1a8 Added text in file1.txt
672d0d8 Created a new text, html and csv file

3. git reset --hard

git reset --hard goes back to the old commit leaving no changes in the Working directory or in Staging Area. It completely erases the changes made and deletes the data and no evidence will be left that the commits originally existed.

Executing: git reset --hard

  • The HEAD pointer directly moves to the old commit.
elcot@elcot-PC MINGW32 /d/GitRepository (master)
$ git reset --hard 2997665
HEAD is now at 2997665 Added text in website.html
  • No data left in the Working directory or in the Staging area.
elcot@elcot-PC MINGW32 /d/GitRepository (master)
$ git status
On branch master
nothing to commit, working tree clean
  • Does not create a new commit. It completely erases the changes made and goes back to the point where the old commit has all the data.
elcot@elcot-PC MINGW32 /d/GitRepository (master)
$ git log --oneline
2997665 (HEAD -> master) Added text in website.html
9da569c Created a python file
da9b506 Added text in table.csv
22cd1a8 Added text in file1.txt
672d0d8 Created a new text, html and csv file

Ignoring files with .gitignore

.gitignore is a text file containing the list of all files and directories that you do not want to track.

1. Creating a .gitignore file

touch .gitignore creates a plain text file in your Project folder.

elcot@elcot-PC MINGW32 /d/Study/Git/Project/MySoftware (master)
$ touch .gitignore

2. Adding file names and directories in .gitignore

In the .gitignore file, you can add the file names and directories you want to ignore.

Here, Autogen/* is a directory (a folder) containing a set of files and folders.
* signifies all the contents in the directory should be ignored.

Comments in .gitignore are prefixed with the hash symbol# and are ignored.

image.png

3. Ignoring currently tracking files

When adding the tracking files to .gitignore, execute the git rm -r --cached command, to ignore the currently tracking files. This removes all the cached files stored in the memory.

Consider the following files are currently tracked and added to .gitignore.

  • sample1.txt and sample2.txt in Trackingfiles Directory
  • file1.txt and file2.txt in Main Project Folder

On updating, though the above mentioned files are added in .gitignore,
these files are in a modified state as these files are being tracked and are stored in the cache memory.

elcot@elcot-PC MINGW32 /d/Study/Git/Project/MySoftware (master)
$ git status
On branch master
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
        modified:   Trackingfiles/sample1.txt
        modified:   Trackingfiles/sample2.txt
        modified:   file1.txt
        modified:   file2.txt

no changes added to commit (use "git add" and/or "git commit -a")

To stop tracking the files, use
git rm -r --cached to remove the cached files.

elcot@elcot-PC MINGW32 /d/Study/Git/Project/MySoftware (master)
$ git rm -r --cached .
rm '.gitignore'
rm 'Trackingfiles/sample1.txt'
rm 'Trackingfiles/sample2.txt'
rm 'file1.txt'
rm 'file2.txt'

elcot@elcot-PC MINGW32 /d/Study/Git/Project/MySoftware (master)
$ git status
On branch master
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
        deleted:    .gitignore
        deleted:    Trackingfiles/sample1.txt
        deleted:    Trackingfiles/sample2.txt
        deleted:    file1.txt
        deleted:    file2.txt

Untracked files:
  (use "git add <file>..." to include in what will be committed)
        .gitignore

.gitignore file must be tracked (added to Staging Area) to reflect the changes and ignore the files intentionally.

elcot@elcot-PC MINGW32 /d/Study/Git/Project/MySoftware (master)
$ git add .

elcot@elcot-PC MINGW32 /d/Study/Git/Project/MySoftware (master)
$ git status
On branch master
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
        deleted:    Trackingfiles/sample1.txt
        deleted:    Trackingfiles/sample2.txt
        deleted:    file1.txt
        deleted:    file2.txt

Files have been removed from the cache and now it intentionally ignores any modification to the file.

elcot@elcot-PC MINGW32 /d/Study/Git/Project/MySoftware (master)
$ git commit -m -"updated new files in gitignore" // Commit after removing from the cache
[master f1df66c] -updated new files in gitignore
 4 files changed, 0 insertions(+), 0 deletions(-)
 delete mode 100644 Trackingfiles/sample1.txt
 delete mode 100644 Trackingfiles/sample2.txt
 delete mode 100644 file1.txt
 delete mode 100644 file2.txt