3 ms·
Can you elaborate on what you mean by immutable history, and how git lacks it?
by jjnoakes 10y ago
Can you elaborate on what you mean by immutable history, and how git lacks it?
- lucideer 10y agoIn git you can edit past commits and rebase, which completely destroys historical data and traces of the rebase. This can be very useful, e.g. for keeping a frequently-committed-to branch "clean" and informative by squashing commits, for removing accidentally committed sensitive credentials, etc. Mercurial, on the other hand, is architecturally set up in a way that considers the repo history to be a somewhat "sacred" truthful account. You still get the same flexibility as git if/when you need the above mutability: it's not 100% immutable, it supports local rebases, and also global mutablity via "phases" - see Marcin's post on this. In an absolute worst case scenario you can also coordinate reclones of a repo of course, but generally speaking the point is that immutability is "on by default".
- jjnoakes 10y agoI'm sorry, I still don't see the distinction. It sounds like in both systems the default is immutability, with commands to override that if necessary. And by the way, doesn't git rebase not mutate history? I believe it creates a parallel history (and updates the branch and head refs to point to the new history) but the old history still exists in git's storage and can be recovered (until you GC your storage).
- jordigh 10y agoIn git, you `git rebase` any commit will always do whatever you tell it to do. In Mercurial, `hg rebase` will abort if you're trying to make it do something to public commits. Public commits are commits that have been shared on a publishing server. The contrast with draft commits, which are commits that have not been shared or only shared on a non-publishing server. If you really want to edit public commits, you have to manually force them back to the draft phase before you can rebase or rewrite them.
- jjnoakes 10y agoIf you "git push" after rebasing published commits, you get an error, unless you use "--force" or you pull and merge manually before hand. So I'm still not sure the distinction you are making between which one is "immutable" and which one isn't.
- jordigh 10y agoPhases catch this problem early before `git push`. You don't want to run into the problem too late. Then you'll be faced with the decision to throw out your work because you accidentally rewrote something that should not have been rewritten. Or you'll have to decide at the last minute that you really did mean to make problems for everyone else. Btw, with Mercurial Evolve, there's no need to force-push, as Evolve will propagate meta-history to other users that indicates what commits replace which ones.
- jjnoakes 10y agoOk so it has nothing to do with immutability, it's just one warns earlier than the other. Thanks for clarifying.
- jordigh 10y agoIt is about immutability. No Mercurial command (histedit, rebase, uncommit, amend) will allow you to change an immutable (public) commit unless you first force it back into the draft phase. You can say that because you can always force public commits into drafts that they're not really immutable, but that's a bit of a perversion of what Mercurial's phase system is intended to do.
- jjnoakes 10y agoAnd no git command lets you change what public history looks like unless you --force the push. So the check is in a different place. That doesn't seem to me to imply that Mercurial's history is "immutable" and git's is "mutable", especially since those words have precise meanings, and even WITH the --force, git doesn't change anything in the history, it just writes out a new history and updates the branch ref to point to the new history. The only thing mutated (in both systems) is the ref to the branch head, right? So aside from warnings and errors being in different places (both before publish time), what is the difference between the two that leads you to argue that one is immutable and one isn't?