Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

The end result of a git rebase is arguably superior. However, I don't do it, because the process of running git rebase is a complete hassle. git merge is one-shot, whereas git rebase replays commits one-by-one.

Replaying commits one-by-one is like a history quiz. It forces me to remember what was going on a week ago when I did commit #23 out of 45. I'm grateful that git stores that history for me when I need it, but I don't want it to force me to interact with the history. I've long since expelled it from my brain, so that I can focus on the current state of the codebase. "5 commits ago, did you mean to do that, or can we take this other change?" I don't care, I don't want to think about it.

Of course, this issue can be reduced by the "squash first, then rebase" approach. Or judicious use of "git commit --amend --no-edit" to reduce the number of commits in my branch, therefore making the rebase less of a hassle. That's fine. But what if I didn't do that? I don't want my tools to judge me for my workflow. A user-friendly tool should non-judgmentally accommodate whatever convenient workflow I adopted in the past.

Git says, "oops, you screwed up by creating 50 lazy commits, now you need to put in 20 minutes figuring out how to cleverly combine them into 3 commits, before you can pull from main!" then I'm going to respond, "screw you, I will do the next-best easier alternative". I don't have time for the judgement.



> "oops, you screwed up by creating 50 lazy commits, now you need to put in 20 minutes figuring out how to cleverly combine them into 3 commits, before you can pull from main!"

You can also just squash them into 1, which will always work with no effort.


Then is not rebase your problem, but all your other practices. Long lived feature branches with lot's of unorganized commits with low cohesion.

Sometimes it's ok to work like this, but you asking git not being judgamental is like saying your roomba should accomodate to you didin't asking you to empty it's dust bag.


You can make long lived feature branches work with rebase, you just have to regularly rebase along the way.

I had a branch that lived for more than a year, ended up with 800+ commits on it. I rebased along the way, and the predictably the final merge was smooth and easy.


Adding to your comment, I've found that frequent squashing of commits on the feature branch makes rebasing considerably easier - you only have to deal with conflicts on one commit.

And of course, making it easier to rebase makes it more likely I will do it frequently.


I don’t see how rebase frequency changes the problem of getting conflicts with some random commit within your long-lived branch, when doing a rebase.

I rebase often myself, but I don’t understand the logic here.


1) because git rerere remembers the resolutions to the ..

2) small conflicts when rebasing the long lived branch on the main branch

if instead I delayed any rebasing until the long lived branch was done, I'd have no idea of the scale of the conflicts, and the task could be very, very different.

Granted, in some cases there would be no or very few conflicts, and then both approaches (long-lived branch with or without rebases along the way) would be similar.


If you do a single rebase at the end, there is nothing to remember, you just get the same accumulated conflicts you also collectively get with frequent rebases. Hence I don’t understand the benefit of the latter in terms of avoiding conflicts.


You don't see a difference between dealing with conflicts within a few days of you doing the work that led to them (or someone else), and doing them all at once, perhaps months later?


This.

"If you do a single rebase at the end, there is nothing to remember, you just get the same accumulated conflicts you also collectively get with frequent rebases."

There is _everything_ to remember. You no longer have the context of what commits (on both sides) actually caused the conflicts, you just have the tip of your branch diffed against the tip of main.

"Hence I don’t understand the benefit of the latter in terms of avoiding conflicts."

You don't avoid conflicts, but you move them from the future to the present. If main is changing frequently, the conflicts are going be unavoidable. Why would you want to wait to resolve them all at once at the very end? When you could be resolving them as they happen, with all the context of the surrounding commits readily at hand. Letting the conflicts accumulate to be dealt with at the end with very little context just sounds terrifyingly inefficient.


If you rebase form main often, it keeps the difference to main quite small, so that when it comes time to do the final merge to main, it's either able to be fast-forwarded (keep it linear, good job!), or at least a very low risk of being conflicted (some people like merge commits, but at least your incoming branch will be linear). Because even though you might have commits that are a year old, initially branched from main from a year ago, their "base" has gradually become whatever main is _now_.

It's just like doing merges _from_ main during the lifetime of the branch. If you don't do any, you'll likely have lots of conflicts on the final merge. If you do it a lot, the final merge will go smooth, but your history will be pretzels all the way down.

In other words, frequent rebasing from main moves any conflicts from the future to "right now", but keeps the history nice and linear, on both sides!


> Long lived feature branches

I always do long lived feature branches, and rarely have issues. When I hear people complain about it, I question their workflow/competence.

Lots of commits is good. The thing I liked about mercurial is you could squash, while still keeping the individual commits. And this is also why I like jj - you get to keep the individual commits while eliminating the noise it produces.

Lots of commits isn't inherently bad. Git is.


While it is a bit of a pain, it can be made a lot easier with the --keep-base option. This article is a great example https://adamj.eu/tech/2022/03/25/how-to-squash-and-rebase-a-... of how to make rebasing with merge conflicts significantly easier. Like you said though, it's not super user-friendly but at least there are options out there.


>Replaying commits one-by-one is like a history quiz. It forces me to remember what was going on a week ago when I did commit #23 out of 45.

While I agree this is a rather severe downside of rebase... if you structure your commits into isolated goals, this can actually be a very good thing. Which is (unsurprisingly) what many rebasers recommend doing - make your history describe your changes as the story you want to tell, not how you actually got there.

You don't have to remember commit #23 out of 45 if your commit is "renamed X to Y and updated callers" - it's in the commit message. And your conflict set now only contains things that you have to rename, not all renames and reorders and value changes everything else that might happen to be nearby. Rebase conflicts can sometimes be significantly smaller and clearer than merge conflicts, though you have to deal with multiple instead of just one.


This seems crazy to me as a self-admitted addict of “git commit --amend --no-edit && git push --force-with-lease”.

I don’t think the tool is judgmental. It’s finicky. It requires more from its user than most tools do. Including bending over to make your workflow compliant with its needs.


A merge can have you doing a history quiz as well. Conflicts can occur in merges just as easily as rebases. Trouble with trying to resolve conflicts after a big merge is that now you have to keep the entire history in your head, because you don't have the context of which commit the change happened in. With rebase you'd be right there in the flow of commits when resolving conflicts.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: