"checkout A...B" switches to the merge base between A and B

When flipping commits around on topic branches, I often end up doing
this sequence:

 * Run "log --oneline next..jc/frotz" to find out the first commit
   on 'jc/frotz' branch not yet merged to 'next';

 * Run "checkout $that_commit^" to detach HEAD to the parent of it;

 * Rebuild the series on top of that commit; and

 * "show-branch jc/frotz HEAD" and "diff jc/frotz HEAD" to verify.

Introduce a new syntax to "git checkout" to name the commit to switch to,
to make the first two steps easier.  When the branch to switch to is
specified as A...B (you can omit either A or B but not both, and HEAD
is used instead of the omitted side), the merge base between these two
commits are computed, and if there is one unique one, we detach the HEAD
at that commit.

With this, I can say "checkout next...jc/frotz".

Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
Junio C Hamano
2009-10-18 12:34:56 -07:00
parent 46148dd7ea
commit 619a644d6d
4 changed files with 74 additions and 3 deletions

View File

@ -794,6 +794,48 @@ release_return:
return retval;
}
int get_sha1_mb(const char *name, unsigned char *sha1)
{
struct commit *one, *two;
struct commit_list *mbs;
unsigned char sha1_tmp[20];
const char *dots;
int st;
dots = strstr(name, "...");
if (!dots)
return get_sha1(name, sha1);
if (dots == name)
st = get_sha1("HEAD", sha1_tmp);
else {
struct strbuf sb;
strbuf_init(&sb, dots - name);
strbuf_add(&sb, name, dots - name);
st = get_sha1(sb.buf, sha1_tmp);
strbuf_release(&sb);
}
if (st)
return st;
one = lookup_commit_reference_gently(sha1_tmp, 0);
if (!one)
return -1;
if (get_sha1(dots[3] ? (dots + 3) : "HEAD", sha1_tmp))
return -1;
two = lookup_commit_reference_gently(sha1_tmp, 0);
if (!two)
return -1;
mbs = get_merge_bases(one, two, 1);
if (!mbs || mbs->next)
st = -1;
else {
st = 0;
hashcpy(sha1, mbs->item->object.sha1);
}
free_commit_list(mbs);
return st;
}
/*
* This is like "get_sha1_basic()", except it allows "sha1 expressions",
* notably "xyz^" for "parent of xyz"