TL;DR Feature branchesBranches are the way to go here.
Since I do not have collaborators in these projects, there is no external pressure to integrate more often or earlier.
Beware the logical inversion. Yes, having collaborators is a great incentive to commit frequently. No, not having any collaborators doesn't mean that you then shouldn't commit frequently.
There is more than one possible incentive to committing frequently.
- this led to huge working copies on my machine
- the burden to finally get all this stuff cleaned up and committed was getting large and larger
- I also cannot benefit from the advantages of VCS such as restoring a previous state of my work, ...
- [not] having a backup in the cloud in case my laptop gets lost, ...
These are 4 really good incentives to commit (and push) frequently, even if you have no collaborators.
I already considered committing my spikey changes to an auxiliary branch that is never merged into main
Yep, this is the way to go. It allows you to save your code on the server, without interfering with the original codebase.
a) by this I would lose an overview of all my changes in the spike (which I at the moment can retrieve with simple
git diff
resp. in the commit preview of my git client of choice)
You can compare between branches using git diff
.
Secondly, while this is off-label usage, I tend to open a pull request to review my changes between my feature branch and master. The nice thing is that it auto-updates when you commit, so it's rather easy to just open a PR and use it as an easy diff viewer.
b) I would have to spend double time on committing my changes into meaningful chunks.
Again, beware the logical inversion. Yes, it is good to structure your frequent commits into individually cohesive commits. No, the inability to make individually cohesive commits is not a reason to therefore refuse to commit frequently.
Especially during POCs (i.e. spikes), code changes are a bit hap-hazard and not quite as structured as normal development. That's perfectly fine.
Spikes are one of these things where there is justification to intentionally circumvent normal development practices in favor of simplifying the experimental phase.
This significantly lowers the administrative overhead during development, which is usually a time where you need your mental resources to focus purely on getting something to work (even if not efficiently or elegantly), but it comes at the cost of having to actively clean this up if you end up wanting to merge this into your main codebase (i.e. master branch).