DEV Community

Cover image for Git Organized: A Better Git Flow
Annie Sexton for Render

Posted on • Originally published at render.com

Git Organized: A Better Git Flow

Imagine this: you've been paged to investigate a production incident, and after some digging, you identify the commit with the breaking code. You decide to revert the change:

$ git revert 1a2b3c
Enter fullscreen mode Exit fullscreen mode

Unfortunately, in doing so, a new bug is introduced! As it turns out, hidden in that old "broken" commit was some code that another part of the app depended upon, and when you reverted those lines, it left the site once again in a broken state. 🙃 Oh dear.

How can situations like this be avoided? To answer this question, we first need to examine how these types of commits come to be.

A Common Git Flow

Let's take a look at a common git flow when building a new feature:

  1. Create a new branch off of main.
  2. Create commits as you go to save your work and fix bugs you find along the way.
  3. When the feature is complete, make a pull request.
  4. Merge branch into main once PR is approved.

This flow might feel quite familiar to you, and that's fine. It's how many of us were taught to work with git. However, there are two problems with this approach. The first problem we've already discussed is that some commits may contain incomplete work when you simply commit as you go. This makes reverting quite risky.

The second problem is that it can make reviewing pull requests very tedious. For example, what if you've been asked to review a recent PR in which the author states that, on top of adding a new feature, they fixed an unrelated bug as well. The PR consists of changes across dozens of files. Looking at each commit individually does not illuminate which changes pertain to the bug fix and which are for the new feature. Additionally, you notice some changes that seem unrelated to anything in the description of the PR. Clearly, this will not be a quick review.

Now, as lovely as it would be for each commit to neatly relate to only one change, that's a tall order to fill when you're in the midst of development. Tangents and rewrites are just part of the process. Our work is rarely so linear, and our git commits tend to reflect this.

So how can we guarantee that our git history is tidy and easily reviewable while also accepting the somewhat tangential nature of development? By modifying this basic git flow just slightly, we can create a better process that accomplishes just this.

An Improved Git Flow

The following approach was inspired by my coworker, Dan Wendorf, whose git flow tends to revolve around one core principle: do the work first, clean up the commits later. The benefit of this flow is that it separates the engineering work from the commit writing. In the end, we'll be left with a sequence of commits that are logically grouped, each relating to one main change in the code, thus cleaning up our git history and paving the way for a quicker PR review.

We can break it down into three steps, as follows.

Step 1: Make your changes

The first step isn't too different than before. Start by creating a new branch and getting to work on making your changes. Don't worry too much about writing descriptive commit messages just yet, as these won't be included in your final PR. For now a simple, "work in progress" or "WIP" message will do, or something that will help you remember what was in that commit like "WIP: Started building new model". The purpose of these commits are to make sure you don't lose work and provide some general guideposts along the path of that work.

$ git checkout -b my-feature-branch

...make changes...

$ git commit -m"WIP"

...make more changes...

$ git commit -m"WIP"

...make even more changes...

$ git commit -m"WIP"
Enter fullscreen mode Exit fullscreen mode

In this step, it's okay to leave the codebase in a broken state or to commit half-baked features. This will all get cleaned up later.

Step 2: Reset

Once you've finished making your changes, it's time to prepare your work for some "git clean up." To do this, we'll run the following command:

$ git reset origin/main
Enter fullscreen mode Exit fullscreen mode

Without any extra arguments, git reset won't change the working tree, so your code won't change — all the work you've done will still be there. But because you've reset to an older commit, git status will show all the changes you've made since you started building your feature. It will look like you did all the work but never made any of those "WIP" commits earlier.

$ git reset origin/main
Unstaged changes after reset:
M       src/components/Footer/Footer.tsx
M       src/components/Nav/Nav.css
M       src/components/Nav/Nav.tsx
M       src/components/Posts/Post.tsx
M       src/components/Posts/PostList.tsx

$ git status
On branch feature-branch
Your branch is behind 'origin/feature-branch' by 3 commits, and can be fast-forwarded.
  (use "git pull" to update your local branch)

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
        modified:   src/components/Footer/Footer.tsx
        modified:   src/components/Nav/Nav.css
        modified:   src/components/Nav/Nav.tsx
        modified:   src/components/Posts/Post.tsx
        modified:   src/components/Posts/PostList.tsx
Enter fullscreen mode Exit fullscreen mode

In case you get in over your head here, don't worry — you can always bring back your original commits! Every commit you make lives in your .git folder, even after a reset. Even though it might seem like they've disappeared, they're still there, hiding.

If you want to go back to a commit where things weren't broken, git reflog will show you a timeline of every commit you've referenced in your local repository, even across branches. Run git reflog to find the commit you want to return to and then run git reset <commit-sha>. This command will point the HEAD of your current branch to that commit, and you're back in business!

From here, we're ready to start making our new commits.

Step 3: Create new, logically-grouped commits

Now, take a look at all the files you've changed. Are there any that you can logically group? For example, all the dependency updates or changes related to a particular model. There's no "right" way to group files, so use your best judgment here. Add these files to your staging area, and make a commit describing the changes.

$ git add src/components/Nav/Nav.css
$ git add src/components/Nav/Nav.tsx
$ git commit -m"Added new styles to navigation"

$ git add src/components/Posts/Post.tsx
$ git add src/components/Posts/PostList.tsx
$ git commit -m"Updated author images on posts"

$ git add src/components/Footer/Footer.tsx
$ git commit -m"Fixed responsive bug in footer"
Enter fullscreen mode Exit fullscreen mode

If you haven't changed many files, you might not need more than one commit, but we can often make our pull requests much easier to review by splitting up our changes into human-readable, easy-to-follow commits.

What if the same file contains multiple changes that should be grouped separately? It's possible to stage part of a file using git add --patch (or git add -p). Some code editors also provide a way to stage a range of changes rather than a whole file.

Be mindful of not leaving your codebase in a broken state during this step. Remember, a huge reason we're cleaning up our commits in the first place is so that nothing will break if we ever want to revert our changes. After making one of these new commits, you can git stash the rest of the unstaged changes and test that everything's still in working order. If you realize you should have included another file in that commit, you can git stash pop to bring back the other changes, git add the missing file, and perform a git commit --amend . This command will replace the last commit with a new one with the same description, including the old commit and the change you just made.

The Final Result

Once you've split your work into logically grouped commits, you're ready to create your pull request! The final result is a set of changes that your colleague can review one commit at a time in manageable chunks.

Logically-organized commits in a PR

The benefit of this git flow is that it allows for the fluidity of typical development while also providing some much-needed order to maintain the repository's history.

Discussion (49)

Collapse
pcjmfranken profile image
Peter Franken • Edited on

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
dtinth profile image
Thai Pangsakulyanont • Edited on

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 on

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

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
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
anniesexton profile image
Annie Sexton Author

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
pcjmfranken profile image
Peter Franken • Edited on

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
tretail profile image
tretail • Edited on

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
yendenikhil profile image
Nik

I agree. Rebase is better option!

Collapse
sargalias profile image
Spyros Argalias

Very nice post. I use this process as well.

The only step I sometimes do differently is: Before resetting my feature branch, I copy it. I branch off the latest commit of my feature branch into a "temp" branch. Then I follow your steps.

However, if I mess up my afterwards, I can just reset my feature branch again and fast-forward merge my temp branch into my feature branch, bringing it back to the original commits before I reset anything. This means I don't have to mess around with the reflog, which can be quite complicated.

Thanks and keep up the good work 👍

Collapse
elisboa profile image
Eduardo Lisboa

Instead of copying, you could make an empty commit (and tag it, maybe), so you would have the exact point-in-time where to go back if needed. Could be something like:

git commit --allow-empty -m"This is fine for now"
Enter fullscreen mode Exit fullscreen mode

Your branch-copy approach is interesting as well, because you can just checkout to the backup branch and go back to where you wanted.

Collapse
zalithka profile image
Andre Greeff

nice write up, it is a lot of reading though... lol. I follow a very similar process myself, adhering to the traditional "commit small, commit often" concept as closely as possible.

if I end up resolving unrelated bugs while working on a feature branch, I normally do the following (assuming a "single main branch" workflow, using a "fast-forward merge only" strategy with no merge commits):

  1. branch general-fixes from master
  2. cherry-pick "general fix" commits from feature-x
  3. rebase feature-x onto general-fixes to verify things
  4. merge general-fixes into master
  5. continue with feature-x..

quite often this happens multiple times a day, so it doesn't take long for it to become habitual.


..and I apologise ahead of time, but I just need to rant a little bit here: I really, really, really wish I could work with people that understand and appreciate Git. :(

one of my work colleagues is of the opinion that rebasing branches after cherry picking commits actually creates duplicate commits.. but he also manually synchronises entire folders of code between multiple projects, and refuses to use any code formatting tools.. so, meh. :insert_epic_facepalm:

Collapse
elisboa profile image
Eduardo Lisboa

I really understand your rant, since I always went through this. But I try to advocate for git and better git flows as much as possible.
I love to commit often, too. I am a branch addict and create sub branches for branches I'm working on, only to (try to) better organize my job. But this git reset approach really seems to work for me. Can't wait to try this soon!

As a branch addict, I always create WIP branches only to check them out later, some specific file that worked and so on. Again, with this git reset approach I believe this will not be necessary anymore.

Collapse
nftcryptomix profile image
nftcryptomix

I am learning to code and I think this post will be a great solution to future projects I am apart off, Thanks

Collapse
anniesexton profile image
Annie Sexton Author

Glad you found this helpful!

Collapse
mkultra329 profile image
Matt Kokidko

This is a really interesting approach which I hadn’t considered. Thank you. Reviewing some responses it seems that get shares a problem found in other tool advocate camps of righteous zealots suggesting there is one single right way to do things. One of my favorite things about get is there’s so many different ways to do things permitted by the many different commands available. This flow that you proposed is interesting and I could see it being useful but I don’t have to automatically jump on the bandwagon of saying this is how it ought to be done, nor do I think that you were suggesting so. Similar to the many commands that git offers, this workflow is one of many workflows that might make sense at any given point along side and with others at different times, in different branches, and in different projects.

Collapse
jingxue profile image
Jing Xue

If the goal is to end up with a series of well organized, self-contained, logically sensible commits, doing it while you are coding them, with fresh memory of what is for what, is still better than accumulating it all until the end, starting over and trying to sort through a big pile of changes.

Remember when you are wrapping up a feature branch, you have just gone through a lot of stress of coding, and are likely under a lot of pressure to deliver. At that point, I doubt many people would have the appetite to sort the 74 diff blocks in that one file into several separated commits. They would just lump them all up into one big commit.

Collapse
labspl profile image
Wojciech • Edited on

According to my, well-working, standards, my git-workflow is as follows ( lets take repoA as my project's repo, and local as local laptop/workplatform; )

git clone -C repoA
cd repoA
git checkout -b mychanges1
Enter fullscreen mode Exit fullscreen mode

Make changes, than

git test -S mychyanges1
git add .
git commit -m ""
git prepare
git push
Enter fullscreen mode Exit fullscreen mode
Collapse
markgoho profile image
Mark Goho

We squash merge PRs

Collapse
labspl profile image
Wojciech

why squashing merge PRs? Simply merging is perfectly fine.

Collapse
elisboa profile image
Eduardo Lisboa

Probably because he doesn't want to "pollute" the destination branch with all the detailed and sometimes maybe incomplete commits. So, only one commit containing all the previous commits as comments may be better for his needs :-)

Collapse
aamonster profile image
aamonster • Edited on

Terrible idea.
It can be used as "last chance" when you totally messed up your commits but you should never use it for normal process.
Just commit often (it's your branch after all) and use "git squash" or "git rebase -i" before creating pull request.
If you made mistake during squash/rebase – "git reflog -> git reset" and try again.

Collapse
shymi profile image
shymi • Edited on

I agree, that this approach has its place into the world as well as rebasing. In the previous company we had a huge repository with a lot of projects in it(yeah - "brilliant" idea, because the DevOps guys and gals couldn't fix their Jenkins jobs) and for the sake of easier traversing the history if needed we have agreed that a single commit should be for resolving a single story or fixing a single bug. And actually the whole process was build around - you are working on a single thing. Then in our case squashing multiple commits(rebasing doesn't byte too hars when you play with it several times) into a single one was the choice.

Oh, another neat command is pull --rebase which can get the latest state from the branch you want and push your commits infront of it. If done before merging - you will see(and hopefully properly resolve) all collisions and your changes will be on top of the main/dev/smthg else branch.

Collapse
mindplay profile image
Rasmus Schultz

This doesn't sound like it'll work.

If you fixed bugs while working on your feature, those bugs are most likely in the same files you were working on.

So you will end up committing unrelated changes this way. Honestly, if this is your strategy, you might as well not commit anything at all, and just commit everything when it's done. (and to be clear, I am not recommending that.)

Having that unrelated bugfix in a separate commit (like you probably had in the first place) you can cherry pick it to the main branch or a separate PR (depending on your workflow) before submitting your feature PR.

It's probably better to work on your commit discipline. Commit in small increments, commit when you're in a working state only, diff and review each change before you commit, and always use the commit log to describe "why" - the "what" is usually obvious from the diff.

Collapse
doncallisto profile image
Samuele Lilli

That's exactly how I work except for I tend to create what you describe as final commits along the way. With this in mind I can avoid to lose something on the way and produce working commits without including/excluding things that can become quite combersome to manage and group at the end.

Collapse
cray2015 profile image
cray2015

it's an opinion but don't u think it's a longer way of doing this. instead just squash the commits when u merge the PR. it will consolidate the commits into one single unit. ever u need to revert u can do it with just a single commit.

Collapse
daverooneyca profile image
Dave Rooney

This isn't a bad approach to dealing with the problem you describe - something broken in a different commit. I squash commits into a single one when merging to main so that if I need to revert, I'm reverting all of my work on that feature and not just one of several commits. I'm also in the rebase camp on this.

Collapse
eleloi profile image
eleloi

That's a very interesting point of view. I always had thought how difficult it is to structure a new project in your head before writing a single line. My head prefer to start writing and the structure simply shows up, surely because my lack of experience.
This method will help me a lot with that! thank you for sharing Annie

Collapse
mattkocaj profile image
matt kocaj

The solution to these two problems I’ve found, lies not with git savvy, but with a whole different philosophy to your code in master.

Everything in master goes to PROD.

and this is only possible with a feature toggle infrastructure. When you have this, a PR that is WIP can be merged with little to no side effects. This then leads to smaller PRs, smaller PR review burden, and much simpler git usage.

Collapse
jakecarpenter profile image
Jake Carpenter • Edited on

I’ll have to try this because I’ve never used reset that way. I suspect, like many other commenters, that it’s very unlikely my bug fix can be separated from the other changes I’ve already made.

This feels like a problem best solved without technology: write your thoughts on a post-it and come back to it later. I’ve pair programmed with some XP-experts and they were all very good at this.

Collapse
martinpham profile image
Martin Pham

Seems to be a nice approach to make cleaner commits :)

Collapse
regenhardt profile image
Marlon Regenhardt

This is exactly what we've been doing for years, can confirm it looks nice and works great.

Collapse
finau profile image
Finau Kaufusi

That's great article, I haven't test this workflow but my first impression is the use of "git reset origin/main" Assuming if your go-workers push number of commits to the origin/main repository. You pull often to update your local repository and avoid conflict.

I'm wondering if have multiple pull from "origin/main" during your work on your feature branch and then you run the "git reset origin/main" at the end of your work. Does it still have the same result you expected?

I haven't test, but I would like to see how your workflow works.

Collapse
rbseaver profile image
Rob Seaver (He/him)

This is a workflow I hadn't considered before. Typically, I'll go with an interactive rebase before preparing a PR, and other times I'll do an initial commit and just amend it every time I make changes. The latter has some pretty obvious downsides, unless you're working with a relatively small change. I'm going to give this a shot on my next feature branch and see how it goes. Thanks for sharing your wisdom!

Collapse
wurikiji profile image
Gihwan Oh

A great and simple guide to follow !

Collapse
bhupesh profile image
Bhupesh Varshney 👾

Nice share 🔥

A bit of a self plug, but i think it might help people
you can use ugit to undo git commands

github.com/Bhupesh-V/ugit

Collapse
kwstannard profile image
Kelly Stannard

To add onto the people saying to use fixup and squash, here is how to do it quickly and efficiently.

dev.to/kwstannard/how-to-plan-an-i...

Collapse
jessekphillips profile image
Jesse Phillips

This is definitely a tool to use for making better commits. I attempted to answer why go to all of this trouble.

Collapse
thomasjunkos profile image
Thomas Junkツ

And then there is git-scm.com/book/en/v2/Git-Tools-I... if you need more finegrained options which things add to which commits.

Collapse
priteshusadadiya profile image
Pritesh Usadadiya

Pingback :
This article was curated as a part of #42nd Issue of Software Testing Notes Newsletter.

Collapse
biffbaff64 profile image
Richard Ikin

Ever since I became se3mi-retired and a 'hobbyist developer' I've gotten rather lazy as far as git is concerned. I really need a kick and get things sorted out.

Collapse
darkwiiplayer profile image
DarkWiiPlayer

This is a terrible idea. At this point, you're losing many of the benefits of git because you're no longer committing your changes in logical groups as you write them, nor are you automatically making sure each commit represents a working state of your system by trying it out as you go.

Instead, you'll have to manually review your changes with a much higher chance to miss things, commit them and ideally stash all uncommitted changes to test the in-between state of your application.

Even worse, you're missing out on the accountability of commit timestamps, so you can no longer see when you made what changes.

And on top of all that you're now writing commit messages long after you made the corresponding changes, so you might be forgetting or misremembering important details that could be worth documenting.


As for the problems you list:

The first problem we've already discussed is that some commits may contain incomplete work when you simply commit as you go

That's just not true. If you use git properly, you won't be dealing with this problem. This only becomes an issue when you can't use git in the first place, in which case all the problems I've listed above will only be worse for you.

For example, what if you've been asked to review a recent PR in which the author states that, on top of adding a new feature, they fixed an unrelated bug as well [...] Looking at each commit individually does not illuminate which changes pertain to the bug fix and which are for the new feature

Once again, this is a purely made up issue. If a developer isn't capable of structuring their commits in a way that makes it clear what each of them does, then their problem goes far deeper than some fancy workflow and they should sit back down and actually learn how to use git. There's many good tutorials out there on how to make good commits.

Collapse
sargalias profile image
Spyros Argalias

They're good points, but I only half agree.

If you're great with git and this works for you, then by all means do it that way. The majority of the time, I create commits as I go as well.

But, even for me sometimes, I do work without git being top-of-mind. I do my work, do not bother with git and sort out my commits later. I find this practically essential when I'm trying stuff out because I don't know how to design the public interface of stuff, or implementation of stuff, right away. In cases like these, I'll just do my work, create temporary commits so I can reset if I screw up and clean up the commits at the end.

Another example is that, over time, I might do a small refactor on a commit I did previously. E.g. maybe I come back the day after and I think "damn that function doesn't make as much sense". I usually do interactive rebase with fixup commits for these things. However, if I did a lot of stuff like that, I find it faster to just reset and form my commits again.

Also, some developers don't care or don't know about version control. They might not create commits as they go. But maybe, they'll sort out the code in the end. Anything.

Long-story short: Do what works for you. I think what you described is good, possibly even the preferred way in a lot of cases. But there are more valid ways to get a good end result.

Collapse
darkwiiplayer profile image
DarkWiiPlayer

Another example is that, over time, I might do a small refactor on a commit I did previously

In those cases, I personally find interactive rebase more convenient than rebuilding the entire branch, but setting aside personal preferences, this is a more specific case and what works in those situations shouldn't necessarily be used as a general approach to using git.

some developers don't care or don't know about version control

A programmer not knowing their tools is not an excuse. This is hardly different from not indenting code to avoid having to learn an editor.

Do what works for you.

Yes, but with a big foot note. Personal projects are not the same as small team projects and neither are those the same as bigger team projects. Most software these days is a team effort and workflows that make it easier to make life harder for other developers won't make you many friends over time.

Thread Thread
sargalias profile image
Spyros Argalias

Fair enough. I think both points of view have valid points. In my experience, most developers don't value commit history very much.

In fact, I believe I do a very good job at it, but I don't value it super highly either. There are tons of things developers need to worry about that impact the business in different amounts. E.g. security, accessibility, knowing your framework, language, writing clean code, tests, etc.

All of those have a huge impact on the code. However, commit history has a minor impact. How often do you read the commit history? How often do bad commit messages affect you in your work? At least in my personal experience, the answer is very rarely. Also, in every codebase I've ever worked, the commits were awful.

For that reason, my point of view is that doing okay with your commits is better than doing nothing. I appreciate any commits that my coworkers create that are okay. They don't have to be perfect. Anything they use to achieve that is a good thing. A small tip doing your commits in the end is probably easier to learn and implement than "always do great commits as you work".

Having said that, I still agree that the method you're describing is preferable most of the time. But, it would require the developer to know git fairly well in my opinion, which might be a luxury considering everything else they have to learn.

Thread Thread
glaucoleme profile image
Glauco Leme

I totally agree with you that the perfection of git commits should not be prioritized over other more impactful skills, an average knowledge could be enough. Some branche organizations can even mitigate bad commits to pollute the main history of an project.

But the title of the article states that is "A Better Git Flow". It could be an alternative way of work, maybe easier for beginners. But better is quite questionable. I believe that rebase should be the way to go. Many beginners at git sees rebase as a monster, when IMO is just a good tool that requires time to understand.

Also, denying the importance of a good commit message only typing WIP, sounds like a nightmare to me. Checkout this pattern of committing, I really appreciate it.