Subject: Re: More Beginning Git Questions

From: Jakub Narebski <[email-masked]>
Date: Sun, 25 Sep 2011 13:58:18 -0700 (PDT)

tactical <[email-masked]> writes:
> Jakub Narebski wrote:
> 
> > With merging into branch with uncomitted changes your fairly well
> > understood 3-way merge (sometimes virtual 3-way merge in the case of
> > multiple common ancestors) would turn into 4-way merge.
> 
> I don't see why it would be a four-way merge rather than a three-way merge.

You have four version: "base" (ancestor version), "theirs"
(branch/clone being merged), "ours" (comitted changes on current
branch) and "new" (uncomitted changes on current branch).

Unless Mercurial does 3-way merge of "new", "theirs" and "base"...
with transaction based atomicity (saving "new" before attempting
merge) they can do that.

With Git you have additional complication: the index state.

> > Even if you
> > can automate it somehow (I do wonder how Mercurial manages that),
> > there could be problem resolving conflicts, unless you happen to touch
> > different parts of file.
> 
> This behaviour is by design in Mercurial.  It's simple, and it works.  I've
> never had a problem with resolving conflicts here, and I don't see why I
> ever would.

It if really is 3-way merge, you wouldn't.  If it isn't (e.g. it is
3-way merge + applying patch, like merge + stash apply in git), then
there are [nasty] corner cases.
 
Anyway I hope that Mercurial does test this feature extensively.

[...]
> > What you use uncomitted changes for, I would use is a separate branch,
> > and keep it rebasing (something like using 'mq' in Mercurial).
> 
> Yes, but, as I mentioned, rebasing is less flexible.  A rebase here is
> effectively a merge and a commit in one step, whereas my approach separates
> the merge and the commit.

Errr... what?  You first commit your changes, then keep it rebasing to
keep them up to date on top of fresh version.
 
> > > Another example of this is the lack of support for anonymous branching as
> > > part of a normal workflow in Git.  Anonymous branching is very powerful and
> > > very simple.  I use it all the time in Mercurial.
> > 
> > What do you use anonymous branching for?
> 
> Anonymous branching is great for minor divergence that isn't really
> significant enough to deserve a name.  It's also great for branches that
> *are* significant enough to deserve a name, but where you want to defer
> naming the branch right up until you merge it into another branch.  At that
> point you can 'name' the branch in the commit message.

I think you can use detached HEAD for that, at least when working on
one issue at a time (you have to name branch when switching to some
other work).

> (Of course, you
> could also create a Mercurial bookmark at that point, and then you'd
> essentially have a "Git branch".)

Except for the fact that AFAIK Mercurial bookmarks have single global
namespace for branch (bookmark) names, while Git uses more flexible
but less newbie-user-friendly branch to remote-tracking branch name
mapping via "refspec".
 
> > Note that with Git by default pushing "matching" branches, you can
> > create private local-only branches.  The have to have _some_ name
> > (even if it is 'foo/temp'), but I think that it makes them perhaps
> > more work to create, but easier to use (to switch branches)... and for
> > single anonymous branch you can always use "detached HEAD".
> 
> From what I read, detached heads are subject to garbage collection.
 
No, HEAD is protected against garbage collecting.  To be sure you
should name a branch when switching branches, though reflog would
protect you for 30 days (by default) even if you don't do that.

-- 
Jakub Narębski