DEV Community

Discussion on: Git Organized: A Better Git Flow

Collapse
 
pcjmfranken profile image
Peter Franken • Edited

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.

Git Commit docs here: git-scm.com/docs/git-commit
Git Rebase docs here: git-scm.com/docs/git-rebase

Git grokking :)

Collapse
 
jdhines profile image
orangehat

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.

Collapse
 
pcjmfranken profile image
Peter Franken • Edited

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!

Collapse
 
anniesexton profile image
Annie Sexton

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, 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. :)

Collapse
 
jessekphillips profile image
Jesse Phillips

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.

Thread Thread
 
pcjmfranken profile image
Peter Franken

Telling people what to do because I am right.

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.

Collapse
 
yendenikhil profile image
Nik

I agree. Rebase is better option!

Collapse
 
tretail profile image
tretail • Edited

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)

Collapse
 
dtinth profile image
Thai Pangsakulyanont • Edited

git rebase can save time in many situations, but it won’t help much if your rebase plan looks like this:

pick a13aedb WIP
pick 05c5074 WIP
pick 07ed6f9 WIP
pick cf7c940 WIP
pick 07cf7ac WIP
pick 3cbc714 WIP
pick 04afd95 WIP
pick 001d2ad WIP
pick bf91864 WIP
Enter fullscreen mode Exit fullscreen mode

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):

pick 58c7be6 ???
pick bda7e36 ??????????
pick 4412ae7 ??????
pick bff35c2 ??????????????????????????????
pick 4d96836 ????????????????????
pick 939938f ???????
pick b173851 ..........
pick bd7b3aa ?????
pick 5f427c3 eee
Enter fullscreen mode Exit fullscreen mode

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.)

Collapse
 
pcjmfranken profile image
Peter Franken • Edited

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..