Git – Should I commit every change before switching branches or is stashing the best option

gitversion control

I am new to git and am currently trying to learn as much as I can about it.

I think the concept of it is fantastic and extremely valuable to any developer's workflow.

I am a data scientist who programs in R, and due to the nature of my work, I work on several projects simultaneously for several people/departments.

I find that I often need to switch back and forth between said projects due to ad-hoc queries / people losing things / people urgently needing to know something, and as such it got me thinking what the best practice is around switching branches.

What lead me to ask this question was that I am finding (especially recently) that I tend to modify several files from several projects in a short amount of time (sometimes in 30 minutes I can modify files from six different projects), and then when I go to switch branches to work on something that I had scheduled to work on, I am presented with the problem of either stashing or committing my changes to the current branch before being allowed to switch.

The problem is that I only wish to commit some of those changes (usually just a single file) to the specific branch that I am currently working on, but of course I can't switch branches without either stashing – or discarding – my changes first.

As such, I want to know if it is good/best practice to immediately commit new changes on their respective branches as soon as I have finished with them and then switch back to my master/other-work branch immediately afterwards, or whether there is another way that typically works best for the majority of people.

My question is this: should I switch branches each time I am finished with a project / set of changes, even if I change just a single file, or should I be doing something else?

For example, if I am working on ProjectX and then somebody asks me to do something for them on ProjectY, should I switch from project-x-branch to project-y-branch, make the changes, commit them and switch back to project-x-branch and continue or is there a better way to handle such scenarios?

The idea I have in mind is so that when I check my working copy, there are only one or two files to commit to the branch that I am working on as opposed to several that aren't related to my current branch.

I appreciate that stashing is designed for this very purpose (at least I think that's what it is for – please correct me if I am wrong) but nevertheless I feel that it is better practice to (ideally) avoid stashing altogether.

I fully expect that committing and switching branches each time I am finished on an update/modification is a very simple and useful habit to adopt, but before I begin implementing said habit, I would really like to know if there might be a better way to handle this.

I have checked the potential duplicate of this question and it doesn't quite seem like the same problem because mine is not a case of experiencing bugs, but more a case of having to randomly change code from one or two projects (where I don't necessarily need to keep the changes) as they don't add value.
The changes are small, such as extracting some other piece of information instead of / in addition to what they were already extracting.

Best Answer

You should commit when ever your project compiles (and passes all UnitTests).

This way you'll commit every 2 minutes (in average). So you are only 2 minutes away from switching branch or leaving for home. This there is no nee to use the stash (most of the time).

This in best done in conjunction with TDD since this gives you two distinct events to commit: after you made the last (one and only failing) test "green" and after "refactoring", before writing the next test.


still I don't see the point of commiting that often, – Walfrat

The biggest benefit is when you rebase your changes to integrate with your upstream: git applies every commit in separation (unlike it does when "merging" where it only applies the resulting changes). This has some benefits:

  1. since the commits are (very) small there is a very low chance for conflicts.
  2. if there are conflicts its easy to find out what the result should be, since the changes are so small.
  3. you can verify your conflict resolution by running your unit tests before continuing the rebase.
  4. If you later have to find out when you introduced a certain behavior you can just search through your commit messages. The commit found only has the relevant changes. You don't need further investigation which changes in the commit are relevant.

in average I commit once or twice a day. I fail to see how I can perform meaningful commit on a lower scale. – Walfrat

When doing TDD the the end of the micro cycle is a somewhat "natural event" to commit:
You have your project in a deliverable state.

If there is a need to "rollback" you most likely want to return to such a state knowing that all features implemented so far really work. When doing TDD this typically is every 30 seconds, sometimes longer and about 2 minutes in average.

The commit message would describe the tests assumption on the production code it verifies.