Commit to Clean Commits

Posted onby

0 views

Let's say you worked on two functions, that were completely different, and you are now planning to stage (add), commit and push your changes. One way you could go about this is by adding both in a single commit and pushing the changes but since the changes are unrelated, it would get difficult to keep track of what changes were made in a particular commit in the long run. Moreover, if the changes are huge and touching different areas of the source code, it would get complex for your peer to review it. Therefore, for these reasons, you should commit to committing homogenous, clean and descriptive commits.

If you want to split your changes into a bunch of meaningful commits, git has got you covered. Git's add provides you with an option, edit, to manually choose what parts of the changes you want to stage (add). Let's understand how to use it.

The Edit

As a running example, let's consider that we have to work on the following script.

$ cat script.py
def add(a: int, b: int) -> int:
	pass

Let's say we decided to complete the add and introduce a new greet_user function.

$ git diff
diff --git a/scirpt.py b/scirpt.py
index 8585104..c3fb9a3 100644
--- a/scirpt.py
+++ b/scirpt.py
@@ -1,2 +1,5 @@
 def add(a: int, b: int) -> int:
-    pass
+    return a + b
+
+def greet_user(username: str) -> None:
+    print(f'Hello, {username}.')

As the changes made are completely different, we would not want to add them in a single commit. To fix this, one thing we can do is going back in the editor to delete the changes for the first function, stage the other one, commit it, go back again, rewrite everything for the first function, stage and finally commit it. This seems doable for small changes but what if you had an absurd amount of changes? This is where --edit comes into the picture. With git add's edit all you got to do is:

  • Delete the lines that you don't want to stage (the lines you add begin with +).
  • Replace the - with a space for the lines that you don't want to get removed.

You can read more about this in $ git --help add under EDITING PATCHES.

Here's how this would go, if we were to commit the greet_user function first.

$ git add -e

This would open the file in your text editor to edit.

  1 diff --git a/scirpt.py b/scirpt.py
  2 index 8585104..c3fb9a3 100644
  3 --- a/scirpt.py
  4 +++ b/scirpt.py
  5 @@ -1,2 +1,5 @@
  6  def add(a: int, b: int) -> int:
  7 -    pass
  8 +    return a + b
  9 +
 10 +def greet_user(username: str) -> None:
 11 +    print(f'Hello, {username}.')

As we only want to commit the greet_user function, we'd delete the 8 the line, replace - in the 7th line with a space, save and close the editor.

  1 diff --git a/scirpt.py b/scirpt.py
  2 index 8585104..c3fb9a3 100644
  3 --- a/scirpt.py
  4 +++ b/scirpt.py
  5 @@ -1,2 +1,5 @@
  6  def add(a: int, b: int) -> int:
  7      pass
  8 +
  9 +def greet_user(username: str) -> None:
 10 +    print(f'Hello, {username}.')

We can look at what has been staged as well.

$ git diff --cached
diff --git a/scirpt.py b/scirpt.py
index 8585104..dd42b90 100644
--- a/scirpt.py
+++ b/scirpt.py
@@ -1,2 +1,5 @@
 def add(a: int, b: int) -> int:
     pass
+
+def greet_user(username: str) -> None:
+    print(f'Hello, {username}.')

Finally, after committing the changes, this is how it would look.

$ git log --oneline
e15ca94 (HEAD -> master) script: Add greet_user to say hello.
4976530 script: Add signature for add.
$ cat scirpt.py
def add(a: int, b: int) -> int:
    return a + b

def greet_user(username: str) -> None:
    print(f'Hello, {username}.')
$ git diff
diff --git a/scirpt.py b/scirpt.py
index dd42b90..c3fb9a3 100644
--- a/scirpt.py
+++ b/scirpt.py
@@ -1,5 +1,5 @@
 def add(a: int, b: int) -> int:
-    pass
+    return a + b

 def greet_user(username: str) -> None:
     print(f'Hello, {username}.')

Notice how the changes for the add function are still there, next you could stage these changes and commit it separately.

Troubleshooting

If you end up getting the following error, you might want to check if you followed the conventions correctly and inspect .git/ADD_EDIT.patch. It is likely that moving .git/ADD_EDIT.patch will solve your problem (unless it has something that you need).

error: corrupt patch at line x
fatal: Could not apply '.git/ADD_EDIT.patch'

PS: There was a recent bug in this feature which was fixed in v2.21 so make sure you're using v2.21 or above.