And that's one of the reasons why I advocate against merges in the codebase on every project I work for and in every HN thread where the topic of merges is mentioned.
That might reveal the depths of my ignorance of Git, but how do you manage moving changes from one branch to the other if you don't use merge? Edit: continuing to read the discussion, it seems it's rebase? I have some reading to do
i use rebase frequently, but i never remember which direction the operation goes in. do you need to checkout the source branch or target branch? truly, it is unknowable. my workflow is to type `man git rebase` and hit space to page through the manual until the first ascii tree surgery diagram appears. then i stare at it until i remember that i need to have checked out my feature branch and am meant to type `git rebase main`. i have trained myself to read the man page every time, perform the operation correctly, then immediately forget.
I use "branch.autosetuprebase=local" and/or --set-upstream-to ; then I can just type "git rebase" while on the thing I want rebased and not have to think about it. (Useful in the gerrit workflow which kind of forces you to have stacks of rebased changes)
The approach described on that site doesn't strictly rule out "git merge", but it emphasises short-lived branches and unidirectional commit flow. If you do things that way you find you just don't really need merges. The next step is to think "merges are rarely useful and sometimes dangerous, so let's just avoid them completely".
Gotta say, I find that horrifying. What about peer reviews? What about breaking up a change into smaller commits, none of which make sense until they're all together (changing the signature of a method, then changing the places that call that method, etc)?
It's worth noting that is mentions that work on a branch and the use of PRs are acceptable, but... the two statements appear to contradict each other. Why say "only do x" and "do thing that isn't x" on the same page?
I can’t find the quoted text in the parent post or article, but as someone who’s fought the short-lived branches crusade in the past (in favor of it) I’ll do my best to answer the criticism you raise :-)
> What about breaking up a change into smaller commits, none of which make sense until they're all together (changing the signature of a method, then changing the places that call that method, etc)?
The general-form solution to this is to make a three-part change: 1. add the new code, 2. migrate all the callers, 3. delete the old code in three separate PRs (or more, if migrating the callers takes several PRs, or some of the old code can be deleted earlier than the rest). I believe arbitrarily large changes can be made this way, and as your origination grows, eventually all large changes _have_ to be made this way.
Isn’t that a lot of extra work? IME it’s a lot less work (and risk!) than resolving a massive merge conflict.
The problems with long-lived branches all derive from the basic problem that eventually the complexity of maintaining two parallel implementations affects the work of everyone at the company.
New person joins before `Big_Refactoring` is merged? You’re either onboarding them twice into two branches, or they’re getting nothing done while they wait for the merge so they don’t have to learn a bunch of code that’s going away soon anyway.
Someone else wants to make a significant change? They either carefully patch each PR into both branches, or they decide “screw it” and do all their work in `Big_Refactoring` anyway, diverging the branches _even more_ and creating more risk in the ultimate merge and more of an incentive for others to start developing in `Big_Refactoring` and make the problem even worse. Soon the feature branch is a de facto main with failing tests while there’s incredible pressure to just ram the merge through so all these changes can go out.
The only way to make it work is to demand that only one person develop in `Big_Refactoring` and everybody else manually cherry-pick their changes into both branches (which quickly just means implementing them twice). IME everyone finds this so annoying that small branches, feature flags, and three-part changes (which makes code sharing between the old and new implementations much easier) become broadly preferred anyway.
As far as PRs, I can’t speak to the linked article, but everywhere I’ve worked that implemented short-lived branches still did PR review. But the PRs had to be small and quick to review (which IME actually helps catch bugs too)
> Isn’t that a lot of extra work? IME it’s a lot less work (and risk!) than resolving a massive merge conflict.
>
> The problems with long-lived branches all derive from the basic problem that eventually the complexity of maintaining two parallel implementations affects the work of everyone at the company.
This seems to imply that there's a choice between A) committing to the main branch, and B) long lived branches. I always work on branches, almost always with multiple commits, and then merge it into the main development branch once the feature is complete. I almost never have to deal with complicated merge conflicts.
That being said, you're talking about short lived branches. The article talked about committing directly in the main trunk/master branch; which is what horrified me.