GilLabs notes, talks, and experiments

My favorite Git commands

30 May 2026

After reading a few posts about git commands like this one and this one, I decided to make my own version too. So, these are a few of my favorite ones:

git add -i

Lets you add files interactively to the staging area.

I like this command a lot when I change several files at the same time and want to split the work into smaller commits. Instead of sending everything to a commit at once, I can review file by file and choose what goes in.

git add -p

This one is similar to git add -i, but goes one level deeper: it lets you add specific parts of a file.

It is very useful when the same file has two different changes. For example, you fixed a bug and also did a small refactor in the same file. With git add -p, you can put only the bug fix in the current commit and leave the refactor for another commit.

git log --oneline --graph --all

This is the classic command to visualize history as a graph:

bash
git log --oneline --graph --all

I use it a lot to quickly understand where I am, which branches exist, where a merge happened, and whether my branch diverged from another one.

git rebase -i

git rebase -i is one of the most useful commands for cleaning up a sequence of commits before opening a PR or before sharing a branch.

With it, you can:

  • reorder commits
  • join small commits with squash or fixup
  • edit messages
  • remove commits that no longer make sense

Of course, it is also a command to use carefully, especially on branches that have already been shared. But on local branches, before publishing, it is excellent for turning a slightly messy sequence of work into a story that is easier to review.

git push origin HEAD:<branch>

Pushes the current commit from your HEAD to a specific branch on origin. Very useful if your local branch does not have the same name as the remote branch, or if you want to publish exactly the current state without switching branches.

git bisect

git bisect is one of those commands that I find conceptually beautiful: it does a binary search through the history to discover which commit introduced a bug.

The basic idea is to mark one commit as good and another as bad:

bash
git bisect startgit bisect badgit bisect good <good-commit>

From there, Git jumps through the history and you tell it whether each tested point is good or bad. In the end, it points to the suspicious commit.

The command becomes even more powerful when combined with automated tests, because you can let Git test the commits for you.

git reflog

The reflog often saves you after a "wrong reset", a "bad rebase", or some detached HEAD confusion.

While git log shows the history of commits reachable from the current branch, git reflog shows where your HEAD has recently been.

That means that when a commit "disappears", it often still appears in the reflog.

bash
git reflog

After finding the lost hash, you can create a temporary branch or carefully go back to that point.

Aliases and bash functions

Creating shortcuts and utility functions is a good addition to your personal devX. Along those lines, I have a repo with commands I have been collecting over the last few years:

https://github.com/adrianogil/git-tools

One example is gz, a function that runs git reset --hard to a reference selected with fzf. Just be careful, because hard reset can delete uncommitted changes.

bash
function ghard-reset-fz() {    if [ -n "$1" ]; then        echo "Git hard reset to ref $1"        git reset --hard "$1"        return $?    fi    # Build a nice list with:    # <ref> | <short-hash> | <author> | <date> | <subject>    local line ref    line=$(        git for-each-ref \            --sort=-committerdate \            --format='%(refname:short) | %(objectname:short) | %(authorname) | %(committerdate:short) | %(subject)' \            refs/heads refs/remotes \        | default-fuzzy-finder    ) || return 1  # user aborted    # Take only the first field (the ref name before the first '|')    ref=\((awk -F'|' '{gsub(/^ *| *\)/, "", \(1); print\)1}' <<< "$line")    if [ -z "$ref" ]; then        echo "No ref selected."        return 1    fi    echo "Git hard reset to ref $ref"    git reset --hard "$ref"}alias gz="ghard-reset-fz"

You can copy aliases from other people, but writing your own teaches you much more. Start with 3 commands you use every day. Give them good names. Document them. Improve them over time. This process builds both better tools and better Git intuition.