Published on

Removing unstaged changes to your individual files in Git

Last Modified on
Last modified on
Authors
Removing unstaged changes to your individual files in Git
Photo by Praveen Thirumurugan on Unsplash

Have you ever worked on project files, made changes which you have not yet committed, and then wanted to revert back to the version of the file before you had made those changes? I know I have!

Removing the unstaged changes to your individual files is actually a simple process. Because perhaps you don’t want to git reset all your modified files. Perhaps you just want to revert the files individually.

Let’s say I made changes in a project, and I wanted to revert back to the latest version of a file before I had made the current changes to it, and my targeted file name is index.html, and it is located at the root of my project, which we can call example-portfolio-site-namecheap. I make some markup changes to index.html, and get the following back in the Terminal console after making the changes:

git status
On branch main
Your branch is up to date with 'origin/main'.

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:   index.html

Then, before actually staging that file or committing those changes, I want to revert back to its previous state (before making those changes). I would simply do the following command:

git checkout index.html

And the following would be returned in the Terminal console after running the command:

Updated 1 path from the index

And when I go to check the file to see if it reverted back to its previous state, it did! And when I run the git command git status, I get the following back in the Terminal console:

On branch main
Your branch is up to date with 'origin/main'.

nothing to commit, working tree clean

If I made changes in several files, and wanted to revert back to the previous state of more than one of those files, I could do the following:

git checkout index.html join.html

And I get back the following in the Terminal console:

Updated 2 paths from the index

Here, I am removing the unstated changes from the files called index.html and join.html all at once.

Butwhat does Updated 2 paths from the index mean? There actually is something called a Git index, and it is a binary file (usually residing in .git/index), containing a sorted list of path names, each with permissions and the SHA1 of a blob object (file). For example, in my local (and remote) repository called example-portfolio-site-namecheap, I have the following content inside my .git folder:

.              HEAD           description    info           refs
..             ORIG_HEAD      hooks          logs
COMMIT_EDITMSG config         index          objects

As you can see, the .git folder contains a file called index (.git/index). And if you want to view the contents of the index in a human-readable way, you would run the git ls-files command. git ls-files simply outputs the file names of the project. Fo example, git ls-files outputs the following for my example-portfolio-site-namecheap index:

git ls-files
.gitignore
.stylelintrc
about.html
favicon.ico
images/alexander-stanishev-lT5QahSnruU-unsplash.webp
images/aman-jakhar-vakM4byYz2Y-unsplash.webp
images/boxed-water-is-better-6aZp4_KfXT8-unsplash.webp
images/boxed-water-is-better-km8IZ4xX9vA-unsplash.webp
images/bryan-garces-IXUM4cJynP0-unsplash.webp
images/burst-aoN3HWLbhdI-unsplash.webp
images/caleb-jones-J3JMyXWQHXU-unsplash.webp
images/cedric-vt-ILffJKYd1eA-unsplash.webp
images/clark-van-der-beken-chcyjyRQV74-unsplash.webp
images/daniel-roe-lpjb_UMOyx8-unsplash.webp
images/daniil-komov-0LHKGHV982w-unsplash.webp
images/dorothea-oldani-aIdp1RsXeaQ-unsplash.webp
images/dorothea-oldani-taPsJHnNJ_8-unsplash.webp
images/eberhard-grossgasteiger-y2azHvupCVo-unsplash.webp
images/hans-veth-ZtsoAKpbsjk-unsplash.webp
images/james-wainscoat-0mV5Vqs9BB8-unsplash.webp
images/jason-leung-wHddViTmSvA-unsplash.webp
images/john-spofford-CDODVpRt3K0-unsplash.webp
images/joshua-daniel-6904Y06M2R4-unsplash.webp
images/joshua-earle-ZMcLVBi9xx4-unsplash.webp
images/meric-tuna-DpbFm4N2BXs-unsplash.webp
images/patrice-bouchard-OeYUyI7jWwc-unsplash.webp
images/peter-lloyd-M-7eSVirG54-unsplash.webp
images/richard-lee-IB1nXa8ASuk-unsplash.webp
images/saeed-lajami-5Lh-mrpbXZk-unsplash.webp
images/sebastian-pichler-sblp4evk2gs-unsplash.webp
images/sneha-cecil-o6is0IIEXnY-unsplash.webp
images/steve-harrris-kAmNlU_b1G4-unsplash.webp
images/vincent-van-zalinge-vUNQaTtZeOo-unsplash.webp
index.html
join.html
package-lock.json
package.json
portfolio.html
resume.html
scripts/hamburger.js
scripts/hover.js
scripts/lazy-load.js
scripts/link-highlight.js
styles/join.css
styles/main.css
styles/portfolio.css
styles/quote-cloud.css
styles/resume.css

The index lists what is being tracked in the repository (project). And the git command git ls-files -s lists all files tracked, including object name, mode bits, and stage number in the output. For example:

100644 e86d016a35847caa2d33f921aa78d1b4d6b18f6c 0       .gitignore

The number 100644 is the mode bit, e86d016a35847caa2d33f921aa78d1b4d6b18f6c is the latest SHA1 (commit hash) that the .gitignore file is part of, 0 is the stage number, and .gitignore is the file (object) name.

There are two mode bits in Git. One is represented by 644, and the other by 755. They represent unix permissions. Just like we have permissions for users on our macOS with these values. 644 means the owner (of the file) can read/write, group/others can read only, and 755  means read and execute access for everyone and also write access for the owner of the file. In my project, I have all 644 permissions.

The stage numbers, *represented here by 0, are used for handling merge conflicts. According to the article Git: Understanding the Index File by Mincing Huang (this information was very difficult to find),

-   Slot 0: “normal”, un-conflicted, all-is-well entry.
-   Slot 1: “base”, the common ancestor version.
-   Slot 2: “ours”, the target (HEAD) version.
-   Slot 3: “theirs”, the being-merged-in version.

So a stage number of 0 is good!

And .gitignore is self-explanatory. The name of the file.

And that is it!

What does the git index contain EXACTLY?: stackoverflow.com

Git: Understanding the Index File: mincong.io

git-lis-files: git-scm.com

Understanding File Permissions: MULTACOM

File permission with six bytes in git. What does it mean?: stackoverflow.com

Git - finding the SHA1 of an individual file in the index: stackoverflow.com