4 ms·
I've come to the conclusion that git got branches right. The idea of permanent metadata for branches is appealing, but repository-wide single namespace is bit o
by jurip 11y ago
I've come to the conclusion that git got branches right. The idea of permanent metadata for branches is appealing, but repository-wide single namespace is bit of a PITA in some circumstance. Mercurial's bookmarks are the same as git's branches, but Bitbucket support is lacking.
The other big thing git has is startup speed. Python is slow. Something like chg helps, but it's a workaround.
- ArneBab 11y agoI only see startup problems with hg when on the university cluster, where the filesystem is slow when accessing many files (metadata access). Startup speed for hg is on my machine below 100ms, less than the time most people need to type a single letter.
- rbehrends 11y agoI am not really happy with either Git's or Mercurial's solution. Git's branches introduce too much fragility in the system for end user consumption (because branches are responsible for both naming and keeping commits alive) and do not allow you to describe sets of commits (nor is there an alternative feature for that), Mercurial's branches are too permanent in that they cannot even be renamed (well, there's an extension for that, but that's not without issues). Mercurial bookmarks still do not allow you to label sets of commits, but at least aren't responsible for the liveness of a commit. In practice, I like both Fossil's and Bazaar's model better.
- Skinney 11y agoWhat do you mean by a "set of commits". Why not just have topic branches? Branches isn't the only thing that keeps commits alive, you also got the reflog and tags. I have a hard time understanding why you would want to keep something alive that isn't reachable from the history.
- rbehrends 11y agoBranches as sets of commits are useful for understanding history. I.e., which commits conceptually belong together and with a quick descriptor of what their purpose and/or who their primary author is (or whatever else your chosen policy for naming them is). That branches are not the only refs that keep commits alive is irrelevant, because the other refs by themselves are not sufficient; not every commit is reachable from a tag and reflog entries expire. Branches remain a necessary ingredient. Git needs this because it requires a named head for each commit because (1) it has a garbage collector and (2) it doesn't allow for multiple checkouts. In version control systems with multiple checkouts, a new branch will typically end up in a checkout of its own. Because there's no GC, it will not spontaneously disappear, and because each checkout keeps track of its own head, there's no need to name it. Git branches are an artifact of Git's odd architectural choices. But my bigger point is not about wanting to keep something alive that isn't part of the history, but that branches may not always accurately reflect what's part of the history (because Git allows you to alter them, and that's often even part of the normal workflow, e.g. deleting a temporary branch once you don't need it anymore). This usually does reflect human error, but, well, a major point of using a VCS is to protect against the results of human error. If you messed up your branches, then you can lose data either because (1) it eventually gets garbage-collected [1] or (2) it doesn't get pushed anymore and some day your computer or hard drive breaks. This is what I meant by Git introducing fragility. [1] Yes, once the grace period expires and it disappears from the reflog, but that only makes it less likely, not impossible, especially for stuff that sees only intermittent work.
- Skinney 11y agoWell, you can set the expiration period for the reflog. If I remember correctly you can set it to "never". You can also disable alteration and removal of branches on a remote git repo. It's really all about knowing your tools. Then again, in my experience, if you manage to remove data or alter data which should not be removed or altered, and don't pick up on that before after the reflog expiration period, then you have bigger problems.
- rbehrends 11y ago> Well, you can set the expiration period for the reflog Much easier, you can turn off garbage collection (if you set the expiration time on the reflog, you have to make sure to set gc.reflogexpireunreachable, not just gc.reflogexpire). This is indeed what I do whenever I work with Git as the frontend (though not when I uses Git programmatically as basically a versioned DB backend). But that's not about me. I'm fully conversant in Git, up to and including having hacked Git repositories using dulwich. It's about users in general, all of whom have to deal with this. Of course, this has its own problems, because lots of Git usage patterns have evolved around creating garbage and then throwing it away rather than having an explicit and safe delete operation that is rarely used (or at least to hide revisions rather than to delete them), and because it may not be possible on hosted repositories, such as on GitHub (Bitbucket allows you to prevent force pushes to master branches, GitHub doesn't [1]). And even when you've made it safe, you still cannot have unnamed branches or multiple checkouts [2]. The more general problem is that Git's GC is not a user interface design decision. Git having a GC is ultimately a result of it being easier to hack together your own transactions without using an actual DB backend such as SQLite when you use (mostly) functional data structures with a GC. While this makes Git a fairly robust versioned database, these and other implementation decisions spilling over into user space is something that has plagued Git for a long time: for full proficiency with Git you need a fairly deep understanding of implementation details. > Then again, in my experience, if you manage to remove data or alter data which should not be removed or altered, and don't pick up on that before after the reflog expiration period, then you have bigger problems. This can easily happen on branches that see only intermittent changes or on personal repositories. Git was originally designed for being heavily distributed work, and it shows; it's relatively safe when commits are regularly mirrored to a network of contributors, not so much when they don't. And, again, this is a problem that should not even exist. One of the primary tenets of source control management -- a major reason why we even have it -- is to protect developers against their mistakes. In particular, there are many cases where VCSs are being used by non-technical people (such as technical writers working on documentation) and they cannot be expected to have a deep technical understanding of the tools they are using. VCS tools must therefore be error-resistant. [1] GitHub in many ways is still shockingly primitive, such as how it still doesn't support attaching files to issues. Referencing gists via URL is a sort-of workaround, but even that becomes painful with binary files. But that's another story. [2] The reason for the latter is subtle, but basically boils down that the GC either needs to have global knowledge of all checkouts in order to trace checkout-local refs such as HEAD properly (which may be lost by a simple mv) or that multiple checkouts that use the same branch can get in a battle over who gets to point it to which commit (e.g., commit to master in two checkouts, and only one commit operation can "win", because master cannot point to two commits at once).