Live data from Hacker News

GitButler now supports first class conflicts, making rebasing less annoying

blog.gitbutler.com

101–110 of 116 posts

Re: GitButler now supports first class conflicts, making rebasing less annoying

#101
post #79
post #56

Earlier quoted context omitted.

The fears are legitimate. Both rebase and force-push can lose data in some circumstances, which merge and push cannot. Yes, there are strategies which, if followed perfectly, allow one to avoid losing data when doing rebase and/or force-push. But those strategies are not simple to describe, especially to newcomers, and in practice people make mistakes; all else being equal, an inherently safe workflow is better.

> The fears are legitimate. They're really not. First of all, no data is really lost with Git. Commits can be recovered from the reflog if they haven't been garbage collected, and there are ways of recovering anything on GitHub as well[1], even if it technically shouldn't be the case. But this aside, data loss is circumstantial, like you say. I've heard the idea that force-pushing in general is harmful, when it's rea…

> First of all, no data is really lost with Git. Commits can be recovered from the reflog if they haven't been garbage collected

So no data is really lost except when it is.

> I've heard the idea that force-pushing in general is harmful, when it's really not if you're working solo or on an isolated branch. Rebasing and force-pushing are just different tools in the toolbox.

Like I said, there are specific circumstances where you can do it safely. But that's very different from being safe in general.

> This is why you see the person in the article claiming that they've always been a "merger", having a false dilemma between merging and rebasing, and describing their solution as "fearless". This line of thinking is also commonly associated with the command line and Linux itself, and is just harmful.

> Instead, users should be educated on what the software does, which does require having comprehensive UIs and documentation, and designing the software with sane defaults, fail-safes, and ways to undo any action.

Users can't and won't learn the full details of everything they use, especially "secondary" tools that they use to support their main workflow - and why should they, unless the benefits are large enough to justify that cost? Using a tool in a mode that is inherently safe rather than a mode that can cause data loss in some circumstances is a perfectly reasonable choice. "Fearless" and "dangerous" are perfectly reasonable ways to characterise this distinction.

Re: GitButler now supports first class conflicts, making rebasing less annoying

#102

Earlier quoted context omitted.

So here's the thing: if you are putting more work into rebasing but not getting anything more out of it, you are doing it wrong. You should always do the easiest thing that gets you what you want, otherwise you're just doing pointless work. If you and your colleagues are happy merging and you find that easier, that's what you should be doing. Rebasing supports a totally different workflow. With a rebase I can submit…

Doesn't the rebased commits example take longer to put together than the merge commits example (where you'd likely want to just squash the merge commits)? The merge version looks like the way code is actually written in practice to me, so doesn't the rebased version take extra time to create after you're done adding code? E.g. the "Add use case baz" rebase commit isn't likely to be a simple squashing of commits from…

Yeah, it takes longer, but with the right tools and practice it doesn't take much longer. The main thing is rebasing often, reordering commits, using commit --amend, fixup commits, git autofixup and rebase --autosquash. That and being determined to deliver rebased commits from the start.

I'm not saying that every single feature must be split into multiple commits. If it's one change then just keep amending that one change as you go. But quite often you'll identify standalone changes as you go, like refactors, little unrelated bugfixes you find as you go etc. When this happens I'll commit that unrelated change separately and rebase to reorder it so it comes first, then continue amending my feature commit.

The paradigm shift for a lot of people is not to think of git as tracking history. Nobody cares about that. It's useless to you and doubly useless for everyone else. Think instead about tracking changes. I don't need to know every key press, every dead end explored or what you did on Tuesday afternoon. I want to know what changes are being applied to the project.

Re: GitButler now supports first class conflicts, making rebasing less annoying

#103
post #98

Earlier quoted context omitted.

Yes but at that point you might as well squash down to one commit and rebase because now you're tracking "history" which is useless, rather than tracking changes/versions.

WTF? If you keep the original history and regularly merge master into feature branches you're tracking people's actual edits as they worked on their feature, which is the most useful thing to have when bisecting, but you're also staying close to mainline during development. It's the best of both worlds.

Yeah it's sure useful when I bisect and find that commit Joe Coder made at the end of the day called "End of day. Tests not passing".

Bisect only makes sense when commits are rebased into changes. The moment you bring in a regression you've fucked your ability to effectively bisect.

Re: GitButler now supports first class conflicts, making rebasing less annoying

#104
post #100
post #76

Earlier quoted context omitted.

Of course all your commits need to compile and pass tests. It didn't even occur to me that anybody would permit that in their CI. If you check in commits that don't compile then you can't use automatic bisection effectively (it still does work if that happens rarely, thanks to automatic `git bisect skip`). Of course every non-building commit will make bisecting a merge history a pain even more, not sure why you think…

> Of course all your commits need to compile and pass tests. > It didn't even occur to me that anybody would permit that in their CI. How do you enforce it? Are you saying you make your CI compile and run tests for every single commit on a feature branch before allowing it to be merged? That takes a lot of time if you're doing the kind of small commits that make bisection most effective. > Of course every non-buildin…

Not OP, but:

> How do you enforce it?

I don't think you can. You just rely on the the developer to only create compiling commits (if possible). Also, code review might catch these.

> Because with rebase you're much more likely to get a long chain of commits that don't compile

After a rebase you try to compile the code and it will fail due to the renamed function. Then you fix the function name and move this change into the commit that started using this function (perhaps employing a fixup commit). Now, all following commits compile because they have the fixed call site, and previous commits compile as well because the call wasn't there yet.

Re: GitButler now supports first class conflicts, making rebasing less annoying

#105
post #98

Earlier quoted context omitted.

WTF? If you keep the original history and regularly merge master into feature branches you're tracking people's actual edits as they worked on their feature, which is the most useful thing to have when bisecting, but you're also staying close to mainline during development. It's the best of both worlds.

Yeah it's sure useful when I bisect and find that commit Joe Coder made at the end of the day called "End of day. Tests not passing". Bisect only makes sense when commits are rebased into changes. The moment you bring in a regression you've fucked your ability to effectively bisect.

> Yeah it's sure useful when I bisect and find that commit Joe Coder made at the end of the day called "End of day. Tests not passing".

So your automated bisect tells you to look at two whole commits instead of one. Big deal.

If you keep history as-is, most commits will compile and pass tests because coders tend to compile and run tests as part of their work cycle (and the occasional isolated non-compiling or non-test-passing commit isn't a problem for a bisect). If you rebase you will end up with long chains of commits that don't compile unless you have some additional mechanism to prevent that.

Re: GitButler now supports first class conflicts, making rebasing less annoying

#106
post #104
post #100

Earlier quoted context omitted.

> Of course all your commits need to compile and pass tests. > It didn't even occur to me that anybody would permit that in their CI. How do you enforce it? Are you saying you make your CI compile and run tests for every single commit on a feature branch before allowing it to be merged? That takes a lot of time if you're doing the kind of small commits that make bisection most effective. > Of course every non-buildin…

Not OP, but: > How do you enforce it? I don't think you can. You just rely on the the developer to only create compiling commits (if possible). Also, code review might catch these. > Because with rebase you're much more likely to get a long chain of commits that don't compile After a rebase you try to compile the code and it will fail due to the renamed function. Then you fix the function name and move this change in…

> I don't think you can. You just rely on the the developer to only create compiling commits (if possible).

Right. But there's a natural incentive to create compiling commits as you work (because when you're working on something you at least occasionally compile your code and run tests). There's much less incentive to go back and check after a rebase.

> Also, code review might catch these.

Pretty unlikely - usually people just review the overall diff, not the individual commits, and even if they do, the commits make sense visually whether they compile or not.

> Then you fix the function name and move this change into the commit that started using this function (perhaps employing a fixup commit).

If you are disciplined enough to notice and do this right, sure. But it's extra work that eats into you discipline budget.

Re: GitButler now supports first class conflicts, making rebasing less annoying

#107

Serious question: how many times the pain of going through rebases rather than merges made a difference, or even better, really paid off in engineering terms? To me it's virtually zero in seven years but it might be due to the teams and projects I've been involved with.

Maybe it’s just the codebases I work on, but I’ve never found rebasing to be particularly painful. No more painful than merges anyway. Both have the potential for conflicts and those conflicts are resolved in a similar way. I’m genuinely curious what pain you’re referring to here that would make it not worth using rebase vs merge commits.

Re: GitButler now supports first class conflicts, making rebasing less annoying

#108

Earlier quoted context omitted.

Doesn't the rebased commits example take longer to put together than the merge commits example (where you'd likely want to just squash the merge commits)? The merge version looks like the way code is actually written in practice to me, so doesn't the rebased version take extra time to create after you're done adding code? E.g. the "Add use case baz" rebase commit isn't likely to be a simple squashing of commits from…

Yeah, it takes longer, but with the right tools and practice it doesn't take much longer. The main thing is rebasing often, reordering commits, using commit --amend, fixup commits, git autofixup and rebase --autosquash. That and being determined to deliver rebased commits from the start. I'm not saying that every single feature must be split into multiple commits. If it's one change then just keep amending that one c…

> Yeah, it takes longer, but with the right tools and practice it doesn't take much longer.

Maybe it depends on the kind of feature as well? I do the rebase with clean separate commits approach when it's easy, where reordering and squashing commits doesn't create tricky conflicts.

But for more exploratory stuff like UI/UX changes where I'm moving blocks of the UI around, and making changes in multiple files to add plumbing to get data where it needs to go, and changing it after demoing and getting feedback, it can get really messy with lots of dead-ends you backtrack out of later.

For that kind of work, it's probably easier to start again in a new branch, figure out some logical way to group the changes, then copy in code snippets from the other branch rather than rebasing? I can't see how this would be worth the effort in most cases though. The more granular commits helps figuring out where a bug got introduced, but then I don't think this happens often and when it does it's usually pretty obvious which lines of code caused the bug even in a large commit e.g. if dates are now being formatted weirdly, look for changes to code that does stuff with dates.

Re: GitButler now supports first class conflicts, making rebasing less annoying

#109
post #78

Earlier quoted context omitted.

I didn't have to use git bisect. I looked at commit history directly and guessed what caused the regression. As we all test different parts of the microprocessor and the tagging system reflected those parts, I could rule stuff out by looking at git log --oneline. The commit messages were also required to be high quality and I could get a gut feeling about what stuff a commit would touch without looking at the code. >…

> the merge commit also wouldn't be tested Why wouldn't it? This is the "not rocket science" rule of software engineering: every commit must pass the tests. There's no special exception for merge commits. https://graydon2.dreamwidth.org/1597.html

The CI tests could take hours because of compilation time + waiting for hardware. Trivial rebases without conflicts got exempt from additional testing, because by the time the test finished, someone else would've submitted to main. Merge commits likely wouldn't be tested in an alternative workflow either.

Not a case of the company being too cheap to spend the money, because there literally aren't enough engineering prototypes in the world to satisfy our CI needs for testing on them.

Re: GitButler now supports first class conflicts, making rebasing less annoying

#110
post #64

Earlier quoted context omitted.

merge feature branches when reintegrating main, squash merge onto the main branch when you’re finished - best of both worlds imo I never need to rebase, or unfuck a botched rebase or go reflog diving - and the commit history is linear where it matters.

Makes the history less useful for bisection - you'll always land on a squash merge rather than the specific commit that caused the problem.

In practice that's never been a problem for me. Work is delivered in functional units and segmented "sections" of code are basically useless on their own for the purpose of debugging.
Post reply on HN