DEV Community

Cover image for Clean and maintainable Git Histories – Part 2
Claudio Altamura
Claudio Altamura

Posted on • Originally published at claudioaltamura.de

Clean and maintainable Git Histories – Part 2

3 simple tricks for managing git histories

It took me a while to learn these simple tricks for effectively managing Git histories with just a few commands. In the first article, I explained why clear, structured Git commit messages and cohesiv commits are important or why temporary commits make the history more difficult to read. This time, I will show you how to organise your commits before merging them. This will give you a clean, easy-to-understand commit history.

Changes should be reviewed and consolidated into a clear commit history. The aim is to include only changes that are relevant, just like book authors revise drafts before publishing. Consider cleaning up commit history for clarity and maintainability:

  • Add changes directly to the previous commit
    If you make minor adjustments to the last commit, you can add them directly into the previous commit by utilizing git commit --amend

  • Consolidate multiple commits into one single commit
    All changes can be grouped together into a single commit with
    git merge --squash

  • Tidy up your commits
    Remove temporary commits, combine multiple commits into one or change the content to create a simple, easy-to-read history with git rebase

Add changes directly to the previous commit

You can make minor corrections or unnecessary changes directly in the last commit using git commit --amend. This command lets us add new files, remove unwanted files or change the commit message – all without creating a new commit (simplified). Here's how to make changes:

  • Open your files in the working directory, and then either add new files using git add or remove files that you don't need any more using git rm
  • Now you can adjust a commit by adding the changes to the last one using the git commit --amend command.
  • You can also edit the commit message if you want.
  • And when the commit is already been pushed, you'll need to force push to the remote repository with git push --force-with-lease.

Consolidate multiple commits into one single commit

During development, you usually work in your feature branch and create several commits like partial steps, WIP commits or bug fixes. Often these intermediate states are not relevant for the main branch and inflate the history. In such a case, the changes can be reduced to one single, clean commit.

Before merging into the main branch, you can squash your commits so that only one summary commit appears in the main branch. The detailed intermediate steps in the feature branch are not retained – instead, a clear, complete commit is created that describes the entire change. Here is an example:

git checkout main
git merge --squash <feature-branch>
git commit -m "feat(auth): add JWT authentication"
git push origin main
Enter fullscreen mode Exit fullscreen mode

This method makes sure you've got a tidy and clear commit history by presenting the whole change as one completed commit – perfect for feature developments with lots of intermediate stages. This makes code reviews a lot of easier. And the main branch is kept simple and free of any unnecessary steps.

Disadvantages like losing granularity because you lose contextual information, or more complex conflict resolution because squash bundles multiple changes into one large commit, are often not that important.

Tidy up your commits

You can use git rebase -i <commit-hash> to edit the commit history interactively and to tidy up the commits. This is really useful for getting rid of temporary or debug commits, or for merging multiple commits. Let's say we want to edit the last five commits with git rebase -i HEAD~5. This will show you a list of the last five commits:

pick abcdef1 Commit A
pick abcdef2 Commit B
pick abcdef3 Commit C
pick abcdef4 Commit D
pich abcdef5 Commit E
Enter fullscreen mode Exit fullscreen mode

Now you can edit the commits as you like:

  • Change pick to squash for the commits you want to merge.

  • Use fixup, if you want to stick changes or corrections made in later commits into an earlier one, but you don't want to keep the message from the later one.

  • You can use the drop command to get rid of individual commits from the history. This is great for temporary or debug commits.

  • And use edit to make changes to a commit. Git stops at this point in the rebase process, so you can make changes in the working directory, like remove debug output or undo temporary changes.

Then just save those changes and you're all set! Now that you've changed the commit history, I think it's important to mention that you'll need to perform a forced push to update the changes in the remote repository using git push --force-with-lease.

A rebase cleans up the Git history. It makes the history linear, as if all the changes from your feature branch were applied directly to the latest version of the main branch. And there's no merge commit created that is causing any issues.

Just be careful:

  • If you re-write history, you might lose sight of the original context, especially when and how changes upstream were integrated.

  • If you rebase branches that have already been published, you might run into problems because you'll be changing the history. Other team members working on the same branch will run into conflicts and have to readjust their local changes.

Conclusion

In this two-part series of articles, we've taken a close look at keeping Git histories easy to understand and to maintain. This is something that often gets overlooked, but it's actually really important making sure the team works efficiently.

In this two-part series of articles, we've taken a close look at keeping Git histories easy to understand and to maintain. This is something that often gets overlooked, but it's actually really important making sure the team works efficiently.

Links

Rewriting history https://git-scm.com/book/en/v2/Git-Tools-Rewriting-History

Photo by Tobias Reich on Unsplash

Top comments (0)