Live data from Hacker News

Extremely Linear Git History

westling.dev

311–320 of 366 posts

Re: Extremely Linear Git History

#311

Earlier quoted context omitted.

> arguably I shouldn't have all these long-lived branches in the first place This is the problem here. If you have multiple long-lived branches, there's no technical solution to preventing rot -- you must actively keep them in sync. Regularly merging in main is the opposite of the proper solution. Constantly rebasing on top of main is the proper solution.

> This is the problem here. If you have multiple long-lived branches, there's no technical solution to preventing rot -- you must actively keep them in sync. Well, merge actually works much smoother and rebase gives a lot more grief, so the problem is with rebase. > Regularly merging in main is the opposite of the proper solution. Constantly rebasing on top of main is the proper solution. The "proper" solution is the…

Always surprising when folks are confused about how to collaborate on git branches... I'd expect the recursive solution to be more obvious!

> The "proper" solution is the one that allows me to get stuff done.

Yeah, but the stuff that needs to get done doesn't end with your commit, it starts there. Merge commits are prone to introduce unexpected and uncaught bugs: rebases just don't.

Re: Extremely Linear Git History

#312
post #277

Earlier quoted context omitted.

way easier to tell that you've messed up a rebase

it's actually way easier to accidentally mess up a rebase, especially if rearranging commits. I can recommend git diff @{1} post rebase I alias it to d-

First time I've seen aliases using other chars other than a-z; care to share your dotfiles?

It's a neat trick to explode your alias namespace, since you'll never see a tool published named `ls-` So you have reserved a huge "address block" for your personal aliases :)

Re: Extremely Linear Git History

#313
post #282

This is a fun idea, but it will mess with your GC heuristics. https://git-scm.com/docs/git-gc#_configuration Git does something called "packing" when it detects "approximately more than loose objects" in your .git/objects/ folder. The key word here is "approximately". It will guess how many total objects you have by looking in a few folders and assuming that the objects are uniformly distributed among them (these fol…

Could use little-endian numbers to avoid this: 0000, 1000, 2000, 3000, …, e000, f000, 0100, …

Re: Extremely Linear Git History

#314
post #277

Earlier quoted context omitted.

it's actually way easier to accidentally mess up a rebase, especially if rearranging commits. I can recommend git diff @{1} post rebase I alias it to d-

First time I've seen aliases using other chars other than a-z; care to share your dotfiles? It's a neat trick to explode your alias namespace, since you'll never see a tool published named `ls-` So you have reserved a huge "address block" for your personal aliases :)

[deleted]

Re: Extremely Linear Git History

#315

Earlier quoted context omitted.

> It's a hash of everything that goes into a commit, including the commit message ... and, very notably, the hash of the parent commit. That is also part of the commit, which means that changing a parent commit would also imply changing the hashes of all later commits. This is sort of the whole point of git/version control.

This might be a stupid question, but does anyone call git history a blockchain, then? A centralized blockchain, without proof of work or proof of anything really of course, but still, it sounds like the basic blockchain idea is there

Git branches form a https://en.wikipedia.org/wiki/Merkle_tree. Blockchain forks do also, but the goal is usually to ignore all but the longest.

Re: Extremely Linear Git History

#316
post #271
post #141

Earlier quoted context omitted.

Rebasing is a tool of last resort, when something has so fowled up the code that merging a large-scale refactor is even more time consuming. Rebasing takes longer and is actually more prone to error because of the clunky interface. There is absolutely nothing wrong with squashing commits in a feature branch and merging that into master/main. In fact, it's generally better for the health of the repo and the mental hea…

in my experience, rebase works great if the commits are structured and much more painful with lots of overlapping changes, say by continiusly doing _wip_ commits every hour

I certainly am not perfect to the degree that I make a single commit or a relatively small number of “structured commits” to any branch I’m working on. Neither is anybody else (regardless of whether they think they are). Anyone who tailors their commit structure around a poorly designed tool interface is just wasting their own time, and therefore the company’s, in my opinion.

Re: Extremely Linear Git History

#317
post #153

I fail to see the point of this, in fact, I think this is a fundamentally flawed approach to dealing with your revision history. The problem is that rebasing commits has the potential of screwing up the integrity of your commit history. How are you going to deal with non-trivial feature branches that need to be integrated into master? Squash them and commit? Good luck when you need to git bisect an issue. Or rebase a…

I think the fundamental misunderstanding people with your point of view have regarding linear commit histories is that it's not just about different VCS usage, the entire development process is changed.

When you are using linear histories and rebasing you don't do monolithic feature branches. You land smaller chunks and gate their functionality via some configuration variable. `if (useNewPath) { newPath(); } else { oldPath(); }` and all your new incremental features land in `newPath`. All tests pass on both code paths and nothing breaks. When the feature is fully done then you change the default configuration to move to the `newPath`.

> How are you going to deal with non-trivial feature branches that need to be integrated into master?

That's the point -- this isn't a thing in rebase workflows. That's a feature. You don't have to deal with megapatches for massive features. It's incrementally verified along the way and bisect works flawlessly.

Re: Extremely Linear Git History

#318
post #232
post #153

I fail to see the point of this, in fact, I think this is a fundamentally flawed approach to dealing with your revision history. The problem is that rebasing commits has the potential of screwing up the integrity of your commit history. How are you going to deal with non-trivial feature branches that need to be integrated into master? Squash them and commit? Good luck when you need to git bisect an issue. Or rebase a…

> I fail to see the point of this I'm pretty sure the point is that this is a one-person project and the author can play around. He's not suggesting your team of 100 people to adopt this for the development of your commercial product.

Quite the opposite. The largest companies just about all use linear commit histories.

Re: Extremely Linear Git History

#319
post #303
post #287

Earlier quoted context omitted.

(Not the person you replied to, but a passionate rebase-preferred) For me there are two reasons - one aesthetic, one practical. The aesthetic reason is that it tells a more coherent story. The codebase is a single entity, with a linear history. If I asked you "how old were you last year", and you asked "which me are you asking about?", I'd be confused. Similarly, if I want the answer to the question "what was the cod…

> what was the codebase like at this point in time // immediately prior to some point?", you shouldn't need to ask clarifying questions I would assume that such a question would talk only about the main branch. However, I will point out that "what was the state of feature X" is only answerable with a non-linear story. > The practical reason is that it discourages a bad-practice - long-lived branches. Wait, long-lived…

> long-lived branches are _bad_? Merging in partially-done features is _good_?

...uhhh, yes? I've never heard anything to the contrary. Can you explain why you think the opposite?

For long-lived branches: The longer a branch exists separately and diverges from main, the more pain you'll create when you try to merge it back in - both because of changes that someone else has made in the meantime (and so, conflicts you'll (possibly) have to resolve), and because you are introducing changes that someone else will have to resolve. The pain of resolving conflicts scales super-linearly - it's much better to resolve lots of small conflicts (ideally, so small that they can be algorithmically resolves) than to resolve one large one. Plus all the arguments from the point below...

For checking-in early and often: flip it around - what is _better_ about having the change only on your local repo, as opposed to pushed into the main codebase? If the code's checked in (but not operational - hidden behind a feature flag), then:

* your coworkers can _see_ that it exists and will not accidentally introduce incompatible changes, and will not start working on conflicting or overlapping work (yes, your work-planning system should also account for that - but extra safety never hurts!) * if you have introduced a broken dependency, or a performance black-hole (which might only be possible if you're running your code in "shadow mode", executing but not affecting the output until it's fully ready - which, again, is only possible if you check in early-and-often!), you can discover that breakage _early_ and start work on finding an alternative (or, if necessary, abandon the whole project if it's intractable) earlier than otherwise

In fact, to take your example - "sometimes you realize the way you are implementing it (or the whole feature) is a bad idea and all the work should be orphaned" - yep! This happens! This is not a counter-example to my claim! Orphaning an inactive "feature" that has been pushed to (but not fully activated in) production has no more impact than abandoning a local branch. Even orphaning a feature that has been partially activated is still fine, so long as it didn't result in irreversible long-term state-updates to application entities (e.g. if it added a "fooFeatureStatus" to all the users in your database, rolling it back will be tricky. But not impossible!). So there are very few (or no) downsides, and all the advantages I described above.

I do agree that API changes are the one exception to this rule - you should have those reasonably nailed down and certain before you make changes, since those affect your clients. But any purely-internal change which can be put behind a feature flag, on an inactive code path, in shadow mode, in canary/onebox testing, or any other kind of "safe to deploy in prod, but not _really_ affecting all of prod" - do it!

Re: Extremely Linear Git History

#320

Earlier quoted context omitted.

> This is the problem here. If you have multiple long-lived branches, there's no technical solution to preventing rot -- you must actively keep them in sync. Well, merge actually works much smoother and rebase gives a lot more grief, so the problem is with rebase. > Regularly merging in main is the opposite of the proper solution. Constantly rebasing on top of main is the proper solution. The "proper" solution is the…

Always surprising when folks are confused about how to collaborate on git branches... I'd expect the recursive solution to be more obvious! > The "proper" solution is the one that allows me to get stuff done. Yeah, but the stuff that needs to get done doesn't end with your commit, it starts there. Merge commits are prone to introduce unexpected and uncaught bugs: rebases just don't.

> Merge commits are prone to introduce unexpected and uncaught bugs: rebases just don't.

How so? If I make an error with a rebase then I risk losing my changes. You can fetch it from the local reflog, but that's not so easy. With a merge I have a merge commit which records what was merged.

Post reply on HN