Revert a file to a specific version in git

To revert a commit in git you can use the git revert command, this undoes all the changes of the given commit with a new commit. But what if you only want to revert one specific file to a specific revision?

First you need to identify the revision that you are after by using the git log command, you can see the history of a specific file by appending it to the command:

$ git log README.txt
commit 20f4b96db867e471b16b1392af0ffe05f2c5976e (HEAD -> feature-c)
Author: Mark Cornelissen <mark@boxture.com>
Date:   Thu Oct 7 20:03:20 2021 +0200

    Adding even more text, and FILE2

commit 30d3c934363f7effe51ac528cd1ce16dbab2bf57
Author: Mark Cornelissen <mark@boxture.com>
Date:   Thu Oct 7 20:02:28 2021 +0200

    Adding some more text and FILE1

commit d2bcd858aadf352f0fb33fe33249a972e08e3301 (origin/trunk, origin/HEAD, trunk)
Author: Mark Cornelissen <mark@boxture.com>
Date:   Sat Nov 7 08:50:17 2020 +0100

    Initial commit

Then use the git checkout command to get the version that you want to restore:

$ git checkout 30d3c934363f7effe51ac528cd1ce16dbab2bf57 -- README.txt
$ git status
On branch feature-c
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
        modified:   README.txt

The selected revision is now staged for commit, you can now either make further changes to it or commit it directly.

If you want to try the commands from this article you can get a copy of the repository I used from GitHub (and checkout branch feature-c though).

Stashing part of your changes with git

Do you ever run into that situation while coding where you need to temporarily undo some of your uncommitted changes? I sure do.

If you are a git user you have likely used git’s stash feature, this allows you to park changes that you have made rather than committing them. If you didn’t know already: you can even stash new files if you stage them first (using the git add command).

If you want to stash changes to specific files rather than all your changes you can use the push sub-command like shown in the below example:

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

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:   README.txt

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

no changes added to commit (use "git add" and/or "git commit -a")
$ git add .
$ git status
On branch trunk
Your branch is up to date with 'origin/trunk'.

Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
        new file:   FILE1.txt
        new file:   FILE2.txt
        new file:   FILE3.txt
        modified:   README.txt

$ git stash push README.txt FILE1.txt
Saved working directory and index state WIP on trunk: d2bcd85 Initial commit
$ git status
On branch trunk
Your branch is up to date with 'origin/trunk'.

Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
        new file:   FILE2.txt
        new file:   FILE3.txt

Restoring your stashed changes works as it normally would (using git stash pop).

Splitting commits using git rebase

We have all been there before: you’re working on a big feature branch, committing all over the place and then at some point you need to extract something out to merge it back to the main (or develop) branch. My usual to method is to split off a new branch and then use git rebase to keep only the commits of the parts that I want to extract out and merge that back after which I then rebase my feature branch on the target branch again.

But what if you find that some commit halfway through the changeset needs to be split up? That’s what I will be diving into in this article.

Continue reading “Splitting commits using git rebase”

Committing parts of your changes via the git command-line interface

If you have ever used made extensive use of GUI interfaces for git you may have come across the ability to stage and commit only parts of your changes to files rather than committing everything that you changed in said files at once. Recently I learned that the command-line interface to git supports the same feature using the -p flag when staging or even committing files which is what I briefly want to go through in this article.

Continue reading “Committing parts of your changes via the git command-line interface”