Cleaning up your local commit history before pushing is the norm in any half serious project. Happy to see you introduced the concept to so many new people!
However (and feel free to ignore):
Using the git reset command for this purpose is like cutting your toenails with a lawnmower whilst blindfolded. This job would be so much faster, easier, and far less risky with git rebase instead. No thumping headache or teetering on the edge of insanity afterwards either!
Use fixup/amend commits to modify changes you've committed earlier (but have not yet pushed). These commits receive a special mark that Git will be looking for during a rebases with the autosquash option. Git will figure out how to get these changes in with the rest, and in such a way that no one will ever even know they happened.
No matter how bad or embarrassing your brainfarts ever get, Git will be there to help you cover up, forget, and move on. A friend like none other :)
Another one of rebase's neat tricks is its interactive option. It'll presents you with a list of your recent local commits and lets you rename/reorder/undo/or otherwise modify them as you see fit. All together in one go. Git will even warn you if your musical chairs session would result in conflicts - allowing you to abort, and puzzle some more to avoid unnecessary merge commits.
Just like that you're done, no weird out-of-branch experiences, no worries about rewriting history, caught up that old Git again, got your commit in a state that's actually somewhat presentable, and all that within a fraction of the time.
My first thought too was "why not rebase?" but, and maybe I'm just doing it wrong, I've always had trouble if I want to change a commit, or if I want to put only some of the changes from one commit into another. I like this reset approach as an option at least to get my commit history the way I want.
Absolutely do what works best for you. As long as your pushed changes fit the branching strategy you're golden. Well, and not waste too much time putting back together the history you *just fixed* of course 😉
I'll try to get you an example sometime next week. You might not sell on it, but at least you'll know how it works!
I didn't mention it the article, but I also use rebasing quite often! Especially to keep my branch up to date. You can also use interactive rebasing to achieve the same goal, it really just comes down to what works for you. Using rebase -i is helpful if you know that at least some of your commits can be left in tact, or don't need as much modifying. In fact, once you get comfortable enough with it, using rebase -i can be even faster than doing a full reset, because you're not having to re-write as many commits. 💪
That said, staying focused on development while also thinking about "Wait - should this work be in a separate commit?" requires some mental task-switching, which can be taxing on your working memory if you have an overactive neurodivergent brain like I do. I've found that the method described in the article frees up so much mental bandwidth because I can hyperfocus on one goal at a time, be that writing code, or organizing my commits.
If the goal is ultimately to have a sequence of clear, concise commits that are easy to review (or revert), then it really doesn't matter which method you choose. :)
If you start modifying commits during a rebase (which you likely will), then you run into the potential for conflicts, especially if you are reordering.
If you get into such situations and don't understand
$ git rebase --abort
Take smaller steps during the rebase. Move one commit (only a few commits back). Make only one change. Then rebase again for more changes.
Your bio checks out, good advice to take an incremental approach here!
Using fixup and amend commits won't eliminate these situations completely, but they'll definitely help towards keeping track of the commits without having to dive into their individual diffs.
Totally agree with that comment.
Notice some good stuff you may also use: git reset HEAD^ in order to reset last commit (useful to split commit in the middle of a rebase). Notice that some IDE will provide built-in tooling for that.
git push --force-with-lease instead of --force ; that's gonna check if anyone pushed in the meantime (it should not, but I consider it as a good practice since it will warn you)
I was debugging to find out why my Git deployment pipeline failed, so I had to make a lot of small tweaks to the pipeline script, commit, and push to see if the CI build is back working. Since frustration is rising, having quick feedback loop is very important, and so any extra cognitive load has to be reduced.
Composing a commit message required context switching between “problem-solving mode” and “reflecting-and-summarizing mode” which incurs significant load on my brain, so it has to be skipped. In the end my Git log looks like this (this is from an actual project):
In this case, to clean up the history, git reset would make it easier. I don’t think that git reset is dangerous or risky at all: It never touches the working directory, and if I messed up, git reflog always has my back. (git reset --hard, on the other hand, is a whole another story.)
This reached a state so far beyond a messy Git history, that it turned into a work of art. Linus Torvalds would be proud! 😅
I agree that the reset tool would have been a solid choice here. Comparing diffs/patches works well if you have only a few unknowns. Looks like you had slightly more to cover here..
For further actions, you may consider blocking this person and/or reporting abuse
We're a place where coders share, stay up-to-date and grow their careers.
Cleaning up your local commit history before pushing is the norm in any half serious project. Happy to see you introduced the concept to so many new people!
However (and feel free to ignore):
Using the
git reset
command for this purpose is like cutting your toenails with a lawnmower whilst blindfolded. This job would be so much faster, easier, and far less risky withgit rebase
instead. No thumping headache or teetering on the edge of insanity afterwards either!Use fixup/amend commits to modify changes you've committed earlier (but have not yet pushed). These commits receive a special mark that Git will be looking for during a rebases with the
autosquash
option. Git will figure out how to get these changes in with the rest, and in such a way that no one will ever even know they happened.No matter how bad or embarrassing your brainfarts ever get, Git will be there to help you cover up, forget, and move on. A friend like none other :)
Another one of rebase's neat tricks is its
interactive
option. It'll presents you with a list of your recent local commits and lets you rename/reorder/undo/or otherwise modify them as you see fit. All together in one go. Git will even warn you if your musical chairs session would result in conflicts - allowing you to abort, and puzzle some more to avoid unnecessary merge commits.Just like that you're done, no weird out-of-branch experiences, no worries about rewriting history, caught up that old Git again, got your commit in a state that's actually somewhat presentable, and all that within a fraction of the time.
Git Commit docs here: git-scm.com/docs/git-commit
Git Rebase docs here: git-scm.com/docs/git-rebase
Git grokking :)
My first thought too was "why not rebase?" but, and maybe I'm just doing it wrong, I've always had trouble if I want to change a commit, or if I want to put only some of the changes from one commit into another. I like this reset approach as an option at least to get my commit history the way I want.
Absolutely do what works best for you. As long as your pushed changes fit the branching strategy you're golden. Well, and not waste too much time putting back together the history you *just fixed* of course 😉
I'll try to get you an example sometime next week. You might not sell on it, but at least you'll know how it works!
Author here – hello! 👋
I didn't mention it the article, but I also use rebasing quite often! Especially to keep my branch up to date. You can also use interactive rebasing to achieve the same goal, it really just comes down to what works for you. Using
rebase -i
is helpful if you know that at least some of your commits can be left in tact, or don't need as much modifying. In fact, once you get comfortable enough with it, usingrebase -i
can be even faster than doing a fullreset
, because you're not having to re-write as many commits. 💪That said, staying focused on development while also thinking about "Wait - should this work be in a separate commit?" requires some mental task-switching, which can be taxing on your working memory if you have an overactive neurodivergent brain like I do. I've found that the method described in the article frees up so much mental bandwidth because I can hyperfocus on one goal at a time, be that writing code, or organizing my commits.
If the goal is ultimately to have a sequence of clear, concise commits that are easy to review (or revert), then it really doesn't matter which method you choose. :)
If you start modifying commits during a rebase (which you likely will), then you run into the potential for conflicts, especially if you are reordering.
If you get into such situations and don't understand
$ git rebase --abort
Take smaller steps during the rebase. Move one commit (only a few commits back). Make only one change. Then rebase again for more changes.
Your bio checks out, good advice to take an incremental approach here!
Using fixup and amend commits won't eliminate these situations completely, but they'll definitely help towards keeping track of the commits without having to dive into their individual diffs.
I agree. Rebase is better option!
Totally agree with that comment.
Notice some good stuff you may also use:
git reset HEAD^
in order to reset last commit (useful to split commit in the middle of a rebase). Notice that some IDE will provide built-in tooling for that.git push --force-with-lease
instead of--force
; that's gonna check if anyone pushed in the meantime (it should not, but I consider it as a good practice since it will warn you)git rebase
can save time in many situations, but it won’t help much if your rebase plan looks like this:Some real-world story…
I was debugging to find out why my Git deployment pipeline failed, so I had to make a lot of small tweaks to the pipeline script, commit, and push to see if the CI build is back working. Since frustration is rising, having quick feedback loop is very important, and so any extra cognitive load has to be reduced.
Composing a commit message required context switching between “problem-solving mode” and “reflecting-and-summarizing mode” which incurs significant load on my brain, so it has to be skipped. In the end my Git log looks like this (this is from an actual project):
In this case, to clean up the history,
git reset
would make it easier. I don’t think thatgit reset
is dangerous or risky at all: It never touches the working directory, and if I messed up,git reflog
always has my back. (git reset --hard
, on the other hand, is a whole another story.)This reached a state so far beyond a messy Git history, that it turned into a work of art. Linus Torvalds would be proud! 😅
I agree that the reset tool would have been a solid choice here. Comparing diffs/patches works well if you have only a few unknowns. Looks like you had slightly more to cover here..