I kid, I kid! But I do commit just to push a back up before getting on a train, or a convenient point to diff against as part of a refactor, etc.
They should all be a single commit by the end.
If squashing happens then all I can immediately say is "something in this 600 line changeset over 12 files for Feature X broke it". The bug report for that one is going to be more vague, get allocated more story points, and maybe stay in the backlog for several sprints (or forever).
If people are pushing their feature branches and not deleting them that makes life a bit better, but generally people who want their git history to be "clean" and squash commits also want to get rid of old branches.
Someone might say code review should have caught it. Code review almost never catches actual bugs. Or tests? Tests only test stuff that the author expected to break.
The main things I try to ensure are that every commit is small, every commit has a useful message, and no commits should break the build.
Personally, I prefer my coding to be free of such distractions, and to use SCM facilities as a scratchpad for fast iteration on the code (the ability to easily reverse changes etc); this results in many commits that don't make sense in the final pull request / code review.
The bulk of my PRs are still one small commit, but when a feature gets larger I find that "what's the next thing to try to solve the problem" isn't always the same question as "what will make this most readable for a reviewer." I tend to address presentation of the commits in the PR at about the same time I'm addressing readability of the resulting code, as they wind up being related concerns (though not exactly the same thing).
I can't think of any special tools you'd need for this? A git history visualizer with the ability to easily diff and squash ranges helps, but this is nothing special for pretty much any modern IDE. At the end of the day, you just look through the WIP branch history and identify chunks that span multiple commits but logically represent a single change towards some goal.
In my view, it is not subjective. All commits locally must pass unit, integration and e2e tests, and be locally tested by the developer, every...single...one.
I'll have to try it sometime, I have a feeling it wouldn't normally turn out too differently to what I end up with anyway. I do think all commits should build and run properly - otherwise git bisect and similar processes stop being useful.
WIP of a function/method, they could be squashed into a good commit that explains what and why. But some people implement a full feature, squash all of it into a single commit that simply says 'implemented Y'. But you loose context on why they modified the different functions/methods.
Yes, you can try to find it, but there's no context so you're just dealing with a huge block of code that modifies other things, doesn't just add new code.
You don't need to have things tidy, you know you can recover anything you do. So likewise when you're "done" you can squash and split them into changes that make more sense logically before pushing to some shared tree that someone else is going to have to reason about.
People who develop without tools like this tend to do it in a big flat directory and think about "commits" as something done every day or so. Once you get beyond that style, it feels really clumsy.
Which keeps context which is my point.
The other case that I see is squashing it all into one that simply says 'Implemented feature Y' which doesn't provide any context into why something was changed.
If you don't backup your code to remote even if it's not finished, you're taking serious risk.
Of course it's a branch other than master/main, even if it's on "remote".
The thing is, I do not always continue developing on a single/same system, so I do "transfer" commits. I push unfinished code to its own branch on remote, pull from other system and continue developing.
When the code completes and passes all the tests. I merge to either development to prepare for the next version, or to master if the utility is small enough.
The place where the development branch lives doesn't matter, and --amend ing a single commit during a feature development is not the most correct way either.
Oh, and I don't use GitHub for my own software. That part is over.
The drawback of one remote endpoint is that it becomes less obvious whose rules apply. You could argue that other people can mess up your remotes, but it isn't until you get to very large organisations or public development (e.g. FOSS) that you should need to deal with adversarial behavior.
I've had bosses who got angry that I force-pushed to my own remote branches because they liked to review code without being requested by pulling the branch, and after a force-push that doesn't work. But my defense was always: Let's establish a protocol on how to cooperate; there is surely some way we both get what we want, and that git supports.
I mostly avoid creating these kinds of conflicts when people's limited git experience would cause stress or unnecessary use of people's time fiddling with the history. Or if more than one person is doing stuff independent of one another.
I've had colleagues that frown on rebase, and people who can't not.
One of the beauties (and complexitties) of git is that it allows for this diversity of workflow.
At other time I make "transfer commits" since I'll continue development on another machine and need the latest snapshot of the code to continue.
Not all features fit into a single new function, we need to move mountains to rearrange stuff, and to keep code tidy.
As long as the commit messages are clear, and the code works at the end, it's alright.
Of course. But when modifying another, you can commit and say,
Implemented function X. Modified Y to accommodate this new argument that's used on X... and so on
>As long as the commit messages are clear, and the code works at the end, it's alright.
I'm fine if the commit messages are clear. The problem is when squashing, some people squash and don't keep commit them clear or some even squash into one that doesn't provide any insight or clarity, 'Implemented feature Y' and you get a diff of thousands of lines that touches everything
Sometimes I need to write "Implemented function X, but evaluates the result wrong possibly because of this. Fix this first, then continue".
> The problem is when squashing, some people squash...
A single commit touching whole codebase and only says "Bug fix" (or similar) is bad. I concur.
Also commit history should have enough granularity allowing bisection and partial rewind to understand problems and other side effects.
Code for function <B> has the skeleton. Still need to add <...>
If that's how a team develops PRs, then the commits are structurally suboptimal, and the problem is in the development practices.
Such team won't be able to efficiently bisect, independently of the repository structure.
I personally work with granular, self-standing commits, and with this workflow, non-squashed commits makes sense.
Obviously it's not possible to always have self-standing commits, but it is possible the vast majority of the times.
It takes a lot of practice and discipline, though, and if a team is not willing to put them, then of course, squashing in the only way that makes sense.
Edit: I strive to keep my feature branches both short (# of commits) and light (# of lines changed).
If the branch was squashed, bisecting will be less effective, compared to the same branch, merged without squashing (at the conditions of the commits being self-standing).