Live data from Hacker News

Git Rebase for the Terrified

brethorsting.com

61–70 of 305 posts

Re: Git Rebase for the Terrified

#61
post #57

> I always use VS Code for this step. Its merge conflict UI is the clearest I’ve found: it shows “Accept Current Change,” “Accept Incoming Change,” “Accept Both Changes,” and “Compare Changes” buttons right above each conflict. I still get confused by vscode’s changing the terms used by Git. «Current» vs «incoming» are not clear, and can be understood to mean two different things. - Is “current” what is on the branch…

Git's "ours"/"theirs" terminology is often confusing to newcomers, especially when from a certain (incorrect, but fairly common) point of view their meaning may appear to be swapped between merge and rebase. I think in an attempt to make the terminology less confusing UIs tend to reinvent it, but they always fail miserably, ending up with the same problem, just with slightly different words.

This constant reinvention makes the situation even worse, because now the terminology is not only confusing, but also inconsistent across different tools.

Re: Git Rebase for the Terrified

#62
post #30

Earlier quoted context omitted.

> Just go back in time and get a snapshot of what the repo looked like 2 weeks ago. Ah. Except rebase. This is false. Any googling of "git undo rebase" will immediately point out that the git reflog stores all rebase history for convenient undoing. Shockingly, got being a VCS has version control for the... versions of things you create in it, not matter if via merge or rebase or cherry-pick or whatever. You can of co…

Up to a point - they are garbage collected, right? And anyway, I don't want to dig this deep in git internals. I just want my true history. Another way of looking at it is that given real history, you can always represent it more cleanly. But without it you can never really piece together what happened.

The reflog is not a git internal -- it is your local repository's "true history", including all operations that you ran.

The `git log` history that you push is just that curated specific view into what you did that you wish to share with others outside of your own local repository.

The reflog is to git what Ctrl+Z is to Microsoft Word. Saying you don't want to use the reflog to undo a rebase is a bit like saying you don't want to use Ctrl+Z to undo mistakes in Word.

(Of course the reflog is a bit more powerful of an undo tool than Ctrl+Z, as the reflog is append-only, so undoing something doesn't lose you the newer state, you can "undo the undo", while in Word, pressing Ctrl+Z and then typing something loses the tail of the history you undid.)

Indeed, like for Word, the undo history expires after a configurable time. The default is 90 days for reachable changes and 30 days for unreachable changes, which is usually enough to notice whether one messed up one's history and lost work. You can also set it to never expire.

It is fine for people to prefer merge over rebase histories to share the history of parallel work (if in turn they can live with the many drawbacks of not having linear history).

But it is misleading to suggest that rebase is more likely to lose work from interacting with it. Git is /designed/ to not lose any of your work on the history -- no matter the operation -- via the reflog.

Re: Git Rebase for the Terrified

#63
post #13

Maintaining linear history is arguably more work. But excessively non-linear history can be so confusing to reason over. Linear history is like reality: One past and many potential futures. With non-linear history, your past depends on "where you are". ----- M -----+--- P / ----- D ---+ Say I'm at commit P (for present). I got married at commit M and got a dog at commit D. So I got married first and got a Dog later,…

You omitted the merge commit. M is taken so let's go with R. You jump back to M to confirm that the symptoms really don't predate the marriage. Then you jump to R to reproduce and track down the underlying cause of the bad interaction. Had you simply rebased you would have lost the ability to separate the initial working implementation of D from the modifications required to reconcile it with M (and possibly others t…

> Had you simply rebased you would have lost the ability to separate the initial working implementation of D from the modifications required to reconcile it with M

I'd say: cleaning that up is an advantage. Why keep that around? It wouldn't be necessary if there was no update on the main branch in the meantime. With rebase you just pretend you started working after that update on main.

Re: Git Rebase for the Terrified

#64
post #26
post #11

Allow me (today) to be that person to propose checking out Jujutsu instead [0]. Not only it has a superpower of atomic commits (reviewers will love you, peers will hate 8 small PRs that are chained together ;-)) but it's also more consistent than git and works perfectly well as a drop-in replacement. In fact, I've been using Jujutsu for ~2 years as a drop-in and nobody complained (outside of the 8 small PRs chained t…

I think I'd love to use Jujutsu, but I enjoy Magit (for Emacs) too much to entertain the thought of switching :/. Besides, Magit rebasing is also pretty sweet.

Samesies - need a Majjit before I can consider trying it out.

Re: Git Rebase for the Terrified

#65
post #63

Earlier quoted context omitted.

You omitted the merge commit. M is taken so let's go with R. You jump back to M to confirm that the symptoms really don't predate the marriage. Then you jump to R to reproduce and track down the underlying cause of the bad interaction. Had you simply rebased you would have lost the ability to separate the initial working implementation of D from the modifications required to reconcile it with M (and possibly others t…

> Had you simply rebased you would have lost the ability to separate the initial working implementation of D from the modifications required to reconcile it with M I'd say: cleaning that up is an advantage. Why keep that around? It wouldn't be necessary if there was no update on the main branch in the meantime. With rebase you just pretend you started working after that update on main.

For the reason I stated that you quoted right there. Separating the potentially quite large set of changes of the initial (properly working) feature from the (hopefully not too large) set of changes reconciling that feature with the other (apparently incompatible in this example) feature. It provides yet another option for filtering the irrelevant from the relevant thus could prove quite useful at times.

Recall that the entire premise is that there's a bug (the allergy). So at some point a while back something went wrong and the developer didn't notice. Our goal is to pick up the pieces in this not-so-ideal situation.

What's the advantage of "cleaning up" here? Why pretend anything? In this context there shouldn't be a noticeable downside to having a few extra kilobytes of data hanging around. If you feel compelled to "clean up" in this scenario I'd argue that's a sign you should be refactoring your tools to be more ergonomic.

It might be worthwhile to consider the question, why have history in the first place? Why not periodically GC anything other than the N most recent commits behind the head of each branch and tag?

Re: Git Rebase for the Terrified

#66
post #54

I never understood why rebase is such a staple in the git world. For me "loosing" historical data, like on which branch my work was done is a real issue. In the same class, for commit to not have on which branch they were created as a metadata is a rel painpoint. It always a mess to find what commit were done for what global feature/bugfix in a global gitflow process... I'll probably be looking into adding an commit…

Which branch your work was done on is noise, not signal. There is absolutely zero signal lost by rebasing, and it prunes a lot of noise. If your branch somehow carries information, that information should be in your commit message.

I disagree, without this info, I can't easily tell if any commit is part of a feature or is a simple hotfix. I need to rely on the commiter to include the info in the commit message, which is almost always not the case.

Re: Git Rebase for the Terrified

#67
post #62

Earlier quoted context omitted.

Up to a point - they are garbage collected, right? And anyway, I don't want to dig this deep in git internals. I just want my true history. Another way of looking at it is that given real history, you can always represent it more cleanly. But without it you can never really piece together what happened.

The reflog is not a git internal -- it is your local repository's "true history", including all operations that you ran. The `git log` history that you push is just that curated specific view into what you did that you wish to share with others outside of your own local repository. The reflog is to git what Ctrl+Z is to Microsoft Word. Saying you don't want to use the reflog to undo a rebase is a bit like saying you…

But it's at best much harder to find stuff in the reflog than to simply use git's history browsing tools. "What's the state of my never-rebased branch at time X" is a trivial question to answer. Undoing a rebase, at best, involves some hard resets or juggling commit hashes.

None of it is impossible, but IMHO it's a lot of excitement of the wrong kind for essentially no reward.

Re: Git Rebase for the Terrified

#68
post #36

git rebase conflict resolution is a lot less scary with the zdiff3 merge.conflictStyle option. Also incremental rebasing with mergify/git-imerge/git-mergify-rebase/etc is really helpful for long-lived branches that aren't merged upstream. https://github.com/brooksdavis/mergify https://github.com/mhagger/git-imerge https://github.com/CTSRD-CHERI/git-mergify-rebase https://gist.github.com/nicowilliams/ea2fa2b445c2db50d…

So many people don’t know about git-absorb! It’s fantastic.

Re: Git Rebase for the Terrified

#70

I wish rebase was taught as the default - I blame the older inferior version control software. It’s honestly easier to reason about a rebase than a merge since it’s so linear. Understanding of local versus origin branch is also missing or mystical to a lot of people and it’s what gives you confidence to mess around and find things out

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…

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.
Post reply on HN