author | Junio C Hamano <gitster@pobox.com> | |
Sat, 23 Jan 2010 00:08:13 +0000 (16:08 -0800) | ||
committer | Junio C Hamano <gitster@pobox.com> | |
Sat, 23 Jan 2010 00:08:13 +0000 (16:08 -0800) |
* js/refer-upstream:
Teach @{upstream} syntax to strbuf_branchanme()
t1506: more test for @{upstream} syntax
Introduce <branch>@{upstream} notation
Teach @{upstream} syntax to strbuf_branchanme()
t1506: more test for @{upstream} syntax
Introduce <branch>@{upstream} notation
1 | 2 | |||
---|---|---|---|---|
Documentation/git-rev-parse.txt | patch | | diff1 | | diff2 | | blob | history |
sha1_name.c | patch | | diff1 | | diff2 | | blob | history |
diff --cc Documentation/git-rev-parse.txt
Simple merge
diff --cc sha1_name.c
index 1739e9e61240c33a1e2bf110bbeeee111c380716,2376c6d8f453793872718082654745acd4144519..9215ad1d050c427b67124f4c5ca76e60e8e022f0
--- 1/sha1_name.c
--- 2/sha1_name.c
+++ b/sha1_name.c
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 reads short-hand syntax that not only evaluates to a commit
+ * object name, but also can act as if the end user spelled the name
+ * of the branch from the command line.
+ *
+ * - "@{-N}" finds the name of the Nth previous branch we were on, and
+ * places the name of the branch in the given buf and returns the
+ * number of characters parsed if successful.
+ *
+ * - "<branch>@{upstream}" finds the name of the other ref that
+ * <branch> is configured to merge with (missing <branch> defaults
+ * to the current branch), and places the name of the branch in the
+ * given buf and returns the number of characters parsed if
+ * successful.
+ *
+ * If the input is not of the accepted format, it returns a negative
+ * number to signal an error.
+ *
+ * If the input was ok but there are not N branch switches in the
+ * reflog, it returns 0.
+ */
+ int interpret_branch_name(const char *name, struct strbuf *buf)
+ {
+ char *cp;
+ struct branch *upstream;
+ int namelen = strlen(name);
+ int len = interpret_nth_prior_checkout(name, buf);
+ int tmp_len;
+
+ if (!len)
+ return len; /* syntax Ok, not enough switches */
+ if (0 < len)
+ return len; /* consumed from the front */
+ cp = strchr(name, '@');
+ if (!cp)
+ return -1;
+ tmp_len = upstream_mark(cp, namelen - (cp - name));
+ if (!tmp_len)
+ return -1;
+ len = cp + tmp_len - name;
+ cp = xstrndup(name, cp - name);
+ upstream = branch_get(*cp ? cp : NULL);
+ if (!upstream
+ || !upstream->merge
+ || !upstream->merge[0]->dst)
+ return error("No upstream branch found for '%s'", cp);
+ free(cp);
+ cp = shorten_unambiguous_ref(upstream->merge[0]->dst, 0);
+ strbuf_reset(buf);
+ strbuf_addstr(buf, cp);
+ free(cp);
+ return len;
+ }
+
/*
* This is like "get_sha1_basic()", except it allows "sha1 expressions",
* notably "xyz^" for "parent of xyz"