-2

I've been having the problem that at the beginning of a new project, I'm likely to switch frequently between tasks in a way that (to me) doesn't seem very conducive to small single-concern commits. For example, for a full-stack project, I'll be implementing views, components, an api interface, project config files, a router, and stubs of backend api endpoints all at the same time. I find myself waiting until I have a somewhat working prototype before I even commit at all, which also feels wrong.

What are some strategies that can be used to bring some order to the chaos?

4
  • 4
    What actual, specific problem do you think you are solving with your use of git? "It's best practice to use source control" is not an actual, specific problem. Jan 16 at 16:25
  • Once I have things working, I will work on one task/commit at a time (feature, bugfix, prepare for release etc.), at which point source control solves lots of problems and contributes to my development in plenty of ways: Showing me a clean project history; letting me rollback if I change something and decide I don't like the change; making it easier to develop on multiple machines; letting me easily do releases at a specific version while continuing to develop; etc. I think I could learn from other folks' approach to starting a project though, because like I said, my approach feels chaotic. Jan 16 at 16:36
  • 2
    OK, let me rephrase: what actual specific problem do you think you are solving with git in the early stage of a project when you're not working on one task at a time? Jan 16 at 16:38
  • 1
    @Greg Burghardt already gave good advice, so I only throw in a comment: "Save points" is a good metaphor for commits in this early stage of a project. What I often do is, using a local git repo, work in the main branch until I find I have reached a reasonable state and squash everything together as one (initial) commit for the "outside world". After that initial phase one could think about (feature) branches and a more structured workflow. Don't let your assumptions on how to work with any VCR come into your way. Jan 17 at 11:16

4 Answers 4

13

There is a misconception that every commit must be perfect and working. I would argue that commits pushed to a shared branch should try to be working, but this may not be possible in 100% of situations.

If you are in the prototype stage, nothing is a shippable product. Instead, focus on discrete chunks of code that are good enough at the present moment. Commits become more like "save points" along a journey, in case you need to trace your steps backwards if your ideas do not pan out.

More important than when to commit is when to create, merge and switch branches. At this point, focus on one topic branch per major feature of the prototype. Commit as often as you want to your topic branch. Merge the topic branch into the main branch once the major feature is complete enough for the prototype.

As you make progress, consider rebasing and squashing your commits as a cleanup of your work-in-progress history. When merging the topic into the main branch, squashing commits at the time of merging will produce one clean commit.

You do not need to worry about "breaking the build" in the prototype stage. CI/CD pipelines are not typically set up until after there is a business commitment to the prototype, which likely includes assembling a small team to continue the work.

Rather than focusing on when to commit, always work in a topic branch. Never work on main/master. Commit whenever you feel like it and for any reason. Rebase and squash commits in order to clean up the branch history prior to merging into a main or other shared branch.

2

Every commit can be not

  • Finished
  • Full
  • Working

part of development process and you can have as many WIP-states in branches, as you want

"Branch per task" and "single objective per commit" are best practices from real life, in order to decrease future headaches around "WTF I done here?! And for why?"

2

The issue here seems to be a matter of having overly granular tasks. I conclude this based on the following things you mentioned:

I've been having the problem that at the beginning of a new project, I'm likely to switch frequently between tasks

For example, for a full-stack project, I'll be implementing views, components, an api interface, project config files, a router, and stubs of backend api endpoints all at the same time.

A task should not be limited to only changing views, or components, or an api interface, or ... A task should be defined by the current goal. That is vague, but that is by intention, to leave you leeway in how you define your task's scope.

Even in an established codebase, a single task may span all the way from the database model down to the web application view, e.g. if I need to adjust a field and how it is displayed.

For a new codebase, it is even more common that initial setup tasks span across multiple layers of your codebase.

The issue here is a self-imposed issue: you've set overly strict boundaries on what constitutes a task, and now you find yourself being blocked by these arbitrary boundaries.

The solution is to redefine your task more accurately. What are you trying to accomplish? For example, you might be making a /People api endpoint. That means that anything done to achieve that goal is part of the task. If you need to add/change "views, components, an api interface, project config files, a router, and stubs of backend api endpoints all at the same time", then so be it. It's part of the task, therefore it needs to be done to complete the task.


Whether or not you separate that task over multiple commits is up to you and wholly depends on ulterior reasons such as the time it takes to complete this task. For a task that only takes an hour or two, don't bother with multiple commits. For a task that spans days, be sure to check your code in regularly to avoid setbacks due to data loss.

This is why feature branches are so useful. Checking WIP code that doesn't fully work yet into a master branch would render the master branch broken, which is not good if you need to put the current task on hold (or if another colleague wants to work on another task). By working in a feature branch, you are able to check in broken code as much as you want without affecting the "main" codebase (on master) or affecting anyone else.

Overall, the only expectation of having working code on a feature branch is when you intend to merge it back into the master branch. Before then, it really doesn't matter.

Note for completion: the importance of only committing working code depends on whether the branch in question is shared. Generally speaking, each dev works on their own feature branch. If you're dealing with a situation where multiple devs share a feature branch, committing working code is more important. But in such a case, I would also recommend branching off from that shared branch anyway, which precludes the issue and again allows you to commit WIP code as you see fit.

1
  • @ChristopherShroba, while I think this answer and my answer are saying the same things overall, one particular part -- "The issue here is a self-imposed issue: you've set overly strict boundaries on what constitutes a task" -- is an important point to understand. Don't let "do source control" stand in your way at this point. It is in source control. That's half the battle. The other half is getting the POC working. Focus on that. Jan 19 at 12:16
0

If this is a new branch that must start and remain functional the entire time, then just get your code to a minimal working state, and simply start your first commit with all of your files and a message of "Initial commit". I find nothing wrong with that.

From there, you can work on your individual file changes with more bite-sized git commits.

2
  • The minimum doesn't have to be "working", but just "it compiles".
    – gnasher729
    Jan 17 at 11:29
  • @gnasher729 I agree. Jan 17 at 19:55

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.