Demystifying Advanced Git Commands for More Effective Version Control

Dor Amram
Similarweb Engineering
5 min readAug 2, 2023

Version control is a crucial part of any software development process, allowing developers to track and manage changes to their codebase over time. One of the most popular systems for version control is Git. While most developers are familiar with basic commands like `git commit` or `git push`, Git also has many advanced commands that can help you work more efficiently and manage complex code changes. Today, we are going to dive into some of these advanced Git commands to help you supercharge your workflow.

Before proceeding, ensure you have a basic understanding of Git and you’ve used it to manage version control. If you’re still new to Git, you might want to start with some of the basic commands first.

1. git bisect

`git bisect` is a binary search command in Git that enables you to find the commit that introduced a bug in your code. This can be incredibly useful when you know that your code was working at one point and has since broken, but you aren’t sure exactly when the bug was introduced.

The process starts by marking the last known good commit as `good` and the current bad commit as `bad`. Git will then checkout a commit in the middle, and you have to test your program. Depending on whether the bug appears or not, you mark this commit as `good` or `bad`. Git will then keep bisecting until it finds the exact commit that introduced the bug.

git bisect start
git bisect good {LAST_KNOWN_GOOD_COMMIT}
git bisect bad {CURRENTLY_BAD_COMMIT}

2. git rebase -i (Interactive Rebasing)

Git’s interactive rebasing feature allows you to modify previous commits by combining, altering, or even removing them. This can be particularly useful for cleaning up your commit history before merging a feature branch into the main branch.

git rebase -i HEAD~n

In this command, `n` is the number of commits you want to include in the rebase.

The command will open a text editor with a list of the last `n` commits, each prefixed with the word `pick`. You can replace `pick` with commands such as `reword` to change a commit’s message, `squash` to combine a commit with the one before it, or `drop` to remove a commit entirely.

3. git stash

`git stash` is a command that allows you to save changes that you don’t want to commit immediately. It’s very useful when you want to switch branches but you aren’t ready to commit your changes.

You can use `git stash save “message”` to save your changes with a descriptive message. The changes are saved into a stack, and you can retrieve them later with the `git stash pop` command.

git stash save "work in progress for feature X"

4. git cherry-pick

`git cherry-pick` is a powerful command that allows you to apply the changes from an existing commit to your current working branch. This is useful when you want to grab a specific change from another branch without merging all the changes from that branch.

git cherry-pick {COMMIT_HASH}

In the above command, replace `{commit_hash}` with the hash of the commit you want to cherry pick.

5. git reflog

If you’ve ever been in a situation where you lost a commit, `git reflog` is the superhero command that can help you recover it. `git reflog` maintains a log of where your HEAD and branch references have pointed in the past. This makes it possible to recover lost commits, or even lost branches.

git reflog

Handy Git Aliases for a Streamlined Workflow

As an added bonus, I’d love to share with you some of my favorite Git aliases that have supercharged my own workflow. These are shortcuts that I’ve devised over time, designed to save keystrokes and make your Git experience more seamless. Let’s take a look:

1. The Cleaning Tool

This bash function, f, is intended to automatically delete all local Git branches that have been merged into the current or specified branch, excluding the current or specified branch itself. This is useful for repository maintenance and reducing clutter, as it automates the cleanup of outdated branches that are no longer needed after their changes have been integrated.

!f() { DEFAULT=$(git default); git branch --merged ${1-$DEFAULT} | grep -v  ${1-$DEFAULT}$ | xargs git branch -d; }; f

2. Synchronize with the Master

This alias is the perfect one-click solution to synchronize your feature branch with the master. It reduces a multi-step process to a single command.

git checkout master && git pull && git checkout - && git rebase master

3. Detect Frequently Modified Files

This command provides an overview of how often each file in your Git repository has been modified, helping you understand the evolution and high-change areas of your codebase.
Frequently modified files in a Git repository might indicate areas of the codebase that are complex, unstable, or subject to regular updates. Such areas are often more prone to errors or bugs due to the continuous changes, potentially making them a source of recurring issues in the software. Therefore, the given command can help developers identify these “hotspots” and allocate more time for thorough code review, testing, or refactoring in these areas to improve code quality and stability.

git log --all --find-renames --find-copies --name-only --format=format: | sort | egrep -v '^$' | uniq -c | sort -n | awk 'BEGIN {print "Count\tFile"} {print $1 "\t" $2}'

4. Safeguard Changes

This command offers a safety net during experimentation. It saves all your changes in a new commit, then undoes that commit, effectively storing all changes, including untracked ones.

git add -A && git commit -qm 'WIPE SAVEPOINT' && git reset HEAD~1 - hard
Me after using these aliases

Adding these aliases to your toolkit is like getting your favorite superhero powers. Use them wisely, and they will make you an even more effective and efficient Git user.

Git is a powerful tool, and like any powerful tool, it takes time to understand and use it to its full potential. The commands we discussed in this post are only the tip of the iceberg when it comes to Git’s capabilities. As you become more comfortable with Git, I encourage you to explore the documentation and discover other advanced commands and options that can further enhance your workflow.

Remember that while it’s important to understand and be able to use these advanced commands, it’s equally important to use them judiciously. Git is a tool designed to aid development, not to create unnecessary complexity. Happy Gitting!

--

--