kurekszymon

about

git got gut

you need to be familiar with git - that’s just the requirement nowadays - whether you are an experienced engineer or just getting started. using it doesn’t need to be complicated - it was created in 3 days, after all - but sometimes can be overwhelming. There are countless videos, articles, tips and tricks on how to use git efficiently, but all those materials rarely touch on the fact that made using it easier for me mentally - almost everything is reversible.

If you were to follow a proper route of learning git and after downloading git you’d click on Learn->Book, and read it, you would learn how to undo things or how to rewrite history or that you shouldn’t be worried to use reset and that is super useful! Although I don’t know anyone who did it this way.

Whether you are using CLI or some desktop client like Sourcetree or GitHub Desktop I think being aware of reversibility of commands can be beneficial for your work with this tool.

⚠️ note

this will be solely based on my experience and the way I like to work with git. it’s not the cleanest, most perfect way of doing that, it’s just super comfortable for me.

assumption

Like in all cases, one needs to make some assumptions about the end user / consumer. And while I don’t expect any consumers of this article (besides those I’ve forcefully requested to read it - sorry guys).

I will assume the reader knows at least basics of git.

other than that I think it should be fairly easy to understand what I’m trying to convey

amend (don’t let them know you’ve been working overnight)

Amending a commit is the most lightweight version of reversibility used by me. To me it somehow resembles this plane taking off without passengers meme - changes are committed, but not complete. Amend works in both cases (local / pushed to remote) - with a difference of a force push (local changes you can just amend, when you are amending commit that’s already pushed to the remote, you edit the tip of your HEAD, meaning you need to overwrite origin HEAD). Whenever you forget to add tracked files, stage changes, you’ve misspelled your commit message, or (my personal favorite) you don’t want your colleagues to know that you’ve been working over time so you want to overwrite commit date - git commit --amend is your friend.

git commit --amend # adds staged changes and opens default text editor so you can change message
git commit --amend --no-edit # adds staged changes to your last commit without changing message
git commit --amend -m "message" -m "description" -m "paragraph" # adds staged changes to your last commit and edit commit message in place

Out of every method resolving around reversibility, I think amend is my most commonly used command. Whether I forget to stage files, want to overwrite commit date, or don’t want to run CI/CD more than once (commit -> build -> squash -> build -> merge ), I’d just amend commit and force push it to the remote pre-squashed. It’s not a must have tool in your belt, but it’s pretty convenient if you ask me.

revert (and why it’s not what you may think)

When I initially stumbled upon git revert I thought that’s exactly what I need - to revert changes I pushed making a fool out of myself. Pocketing my pride I typed git log, copied first hash that appeared in my terminal and passed it to git revert {hash}.

[master 478a0082a] Revert "shameful commit"
 2 files changed, 5 insertions(+), 21 deletions(-)

looks pretty darn good if you ask me. Time to git push that thing.

commit 478a0082a638ecf5bb290fd967def009596e31b8 (HEAD -> master)
Author: Szymon Kurek
Date:   Wed Jan 28 17:52:37 2026 +0100

    Revert "shameful commit"

    This reverts commit ce3a42a28266959497bfb4e9a0c84114029d2eab.

commit ce3a42a28266959497bfb4e9a0c84114029d2eab
Author: Szymon Kurek
Date:   Sun Jan 28 16:59:41 2026 +0100

    shameful commit

Oh my lord - now there are two commits showing what an incompetent dev I am :’(.


While I find using revert good for actually reverting changes that introduce bugs and problems on master/RC branch (to be explicit about the intent), using revert on your local branch is usually not the solution you’re looking for.

what I really needed in this case was good ol’

reset (the goat)

git reset allows you to reverse what you did in previous commits (including staged and unstaged changes, depending on the flag you pass to it)

While writing this article I looked up docs for git reset, to confirm if I was using it correctly, and I learned there are three more flags on top of what I use (five in total).

I’ll only focus on the three options I use (I incorporated --mixed after looking at the docs), skipping remaining two since I don’t want to cover something I don’t know.


Personally I use git reset in various situations. Whether I want to squash my changes, or I need to rebase and I don’t want to deal with not important conflicts I’d do

git reset --soft HEAD~X && git stash && git rebase <target> && git stash apply

Just remember, that after rewinding your commits with reset, you’d need to push --force or push --force-with-lease. Not everything goes smoothly with resets and rebases, sometimes you push wrong state to the remote branch, and that’s why you can always rely on the bookkeeping:

reflog (time machine)

Whatever (that changes HEAD) you do in git is being tracked. Fortunately for you, it’s not your personal data, processed by some company, but local history of your edits. One can see it as a safety net, where all else has failed you.

result of git reflog

5f6e9f4 (HEAD -> main, origin/main, chore/show-reflog) HEAD@{0}: checkout: moving from main to chore/show-reflog
5f6e9f4 (HEAD -> main, origin/main, chore/show-reflog) HEAD@{1}: commit: posts: git-got-gut small tweaks
2be797d HEAD@{2}: commit: mds: [WIP] git-got-gut
5f99db1 HEAD@{3}: commit: mds: [WIP] git-got-gut: reset

What’s most interesting there for the user is the hash on the left hand side that lets you go back in time to specific HEAD change. It does allow you to “revert” something you’ve already force pushed to remote.

Going back in time using git reflog:

git reset --hard 2be797d
git log
# should display changes FROM the commit you've passed to git reset --hard

commit 2be797ded3e9bea998ffd1d79771fc7b92f0e1e7
Author: Szymon Kurek
Date:   Thu Jan 29 22:37:03 2026 +0100

    mds: [WIP] git-got-gut

commit 5f99db1202fbf09128b5098fd87ca9daead0b3df
Author: Szymon Kurek
Date:   Thu Jan 29 22:34:12 2026 +0100

    mds: [WIP] git-got-gut: reset

For me reflog is the last safety net - if I mess up rebases, resets, commits in order I would go back in time to place before I started to mess up. It’s also very convenient you don’t have to do anything in order to get this bookkeeping and all benefits that come from this.

Note: reflog is a LOCAL tracker of your changes - your peers or the remote does not know about this. Reflog also eventually expires, but I have never experienced a case where I would need to worry about the time of it - most commonly I reach for it when I messed up just now, or relatively not a long time ago.

wrapping up

People always say to keep your commits small and to commit often - but why does that matter? Hopefully after reading previous sections you’d know why, but it’s still convenient to not commit as often as people say. My main reason why is that modern IDEs, like VS Code, Zed or Cursor do have git client built-in. It’s very comfortable to just go ahead and preview files you’ve changed to have self-imposed code review and be aware of your own changes.

There is a catch though - you don’t have any baseline of when things started to not work as you’d expect, and that’s the case especially for the changes with a lot of boilerplate, and editing lots of files before seeing a change in the ui.

My advice on this, and something that I am still working on in my own setup, is to commit every time you have a meaningful / working change. Push it to the remote even - because no one cares, unless you actually open a pr. Before opening a pr you can squash your commits and nobody will know that you’ve changed one variable name 14 times because you didn’t know if it should be named isCorrectFilterApplied or isFilterCorrectlyApplied. Rewrite your history before the pr. Open branch with no changes if you are scared to do so - do everything you need to feel safe before pushing it to the remote. Your company won’t care about an extra branch opened, especially if you don’t push it to the remote (no one will track you down if you do it - unless you don’t open a PR, in most setups reviewers won’t be notified, look up CODEOWNERS file in your project).

Most importantly - do your own research on git commands, make them yours, feel good and safe when using this, experiment on your personal projects and custom branches - it’s not that hard. Be mindful of what might happen, paste it to LLM if you are not sure (please don’t paste any company secrets there).

Git is easy - own the process.