3 ms·
> Since, for me, local branches are a massive part of why I prefer git, I'd be interested in examples of how to do the same thing in other VCSs. You simply com
by rbehrends 12y ago
> Since, for me, local branches are a massive part of why I prefer git, I'd be interested in examples of how to do the same thing in other VCSs.
You simply commit a new changeset based on the desired parent. The branch would be created implicitly by having a revision with two or more children. It does not have to carry a name; naming revisions (or sets of revisions) is an orthogonal concept for the purpose of navigating the revision DAG [1], whereas in Git branches have the additional purpose of keeping revisions from being GCed. Any revision that is not referenced by a ref (directly or indirectly) will eventually be GCed (once it is removed from the reflog and the grace period has expired).
> It doesn't make sense to me that they're a byproduct of having a garbage collector
It is a byproduct. Because if you did the above in Git (which Git won't let you without being explicit about it, but it's possible), then one or the other child would get GCed sooner or later. That's because there's only one HEAD commit, and that can prevent only one child from being GCed, so you have to create a ref to the other (generally via a branch) to keep it alive.
> since (1) git-stash exists [...] and (3) git-clean honestly seems tacked on rather than a core piece of the design.
This has nothing to do with git stash or git clean. I'm talking about one of Git's architectural principles, where the repository is essentially a purely [2] functional data structure and revisions that are not reachable from one of the roots (refs/branches) are subject to garbage collection.
[1] And if you look (aside from Mercurial) at Bazaar, Fossil, Monotone, or Veracity, you'll find that there are multiple ways to go about that.
[2] Well, not entirely pure, but close enough.
- imakesnowflakes 12y ago>whereas in Git branches have the additional purpose of keeping revisions from being GCed.. Not only that, but it is also used to decide what all commits to show to the user. In that way branch names act as little windows through which you can look at the DAG of history. Commits that you cannot see through this window does not really belong in the history according to git, and will be GC'ed. So if you make a commit on top of a revision that is not a branch head, then it becomes a DETACHED HEAD. Actually there is nothing 'detached' about it. It is linked to the parent commit just fine. But git just does not consider it part of the history unless you give it a name. Here you can see the problem with git naming. 'DETACHED HEAD'. If you understand a head revision as a last revision in a sequence of connected commits, how can there be a 'DETACHED HEAD' when a 'HEAD', by definition is part of a sequence of commits.. I wonder why someone would call it a 'DETACHED HEAD' instead of something like 'UNNAMED HEAD' or 'ANONYMOUS HEAD'....
- _ikke_ 12y agoBecause HEAD is in this case not 'attached' to a branch, which means there is no branch which can be advanced to keep track of the new commit.
- josteink 12y ago> You simply commit a new changeset based on the desired parent. The branch would be created implicitly by having a revision with two or more children. And then, how do you later track these commits? How do you change or merge branches if they have no names? Do you go around remembering revision-IDs? I'm not trying to be judgemental and say this is wrong or anything, but I'm curious how this works out in practice.
- rbehrends 12y agoFirst, let me note that neither Git nor Mercurial is my preferred VCS, so you'd ideally want to ask somebody else about common practices (my own preferences are naturally influenced by other VCSs). My own preferred approach is to use hg share, which allows me to have multiple checkouts of the same repository, each with a different current revision (HEAD in Git parlance). This is because when I'm doing some local branching, I generally like to have two different sets of files to work with (so as not having to rebuild when switching back and forth, being able to easily run side-by-side comparisons, etc.). This is sort of like Git's git-new-workdir, except that git-new-workdir isn't safe; it is also the default mode of operation of pretty much any DVCS other than Git and Mercurial. This, I note, is not necessarily what the majority of Mercurial users do -- especially since this feature first has to be switched on --, but is one of the major reasons why, if I have to pick either Git or Mercurial, I'll generally go with Mercurial. Multiple checkouts are simply too important a feature for me to want to deal with Git's workarounds; Mercurial's support of them is imperfect, but still better than what Git has. More commonly, in Mercurial you will simply not need to name temporary branches. You will have named branches for your major features etc., and you can use hg heads -r <branch> to list the 1-3 heads you may at any time have per major branch. This makes naming the heads sort of superfluous for typical development. Also, if you have only two heads in a branch, hg merge and hg rebase will automatically pick the other head to merge/rebase against. Alternatively, you can use bookmarks. Bookmarks are essentially like Git branches in that they are pointers to commits. Finally, there's also nothing inherently wrong with simply using named branches, even for temporary work. It's up to you or your organization whether you want persistent or temporary names for temporary work.