summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFelipe Contreras <felipe.contreras@gmail.com>2014-04-20 14:45:06 -0500
committerJunio C Hamano <gitster@pobox.com>2014-04-21 11:46:17 -0700
commitd04e0c79c6fe44dec6db66fdcbf5e4ba4e8bac92 (patch)
treece2ec5c27bef8f818d483f93d3ce78e647ad6fe2
parent0794b01bf8d99b6ac9284cfb92f82ac0243c23a4 (diff)
downloadgit-fc/publish-vs-upstream.tar.gz
sha1_name: add support for @{publish} marksfc/publish-vs-upstream
Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
-rw-r--r--Documentation/revisions.txt4
-rw-r--r--sha1_name.c49
-rwxr-xr-xt/t1508-at-combinations.sh5
3 files changed, 40 insertions, 18 deletions
diff --git a/Documentation/revisions.txt b/Documentation/revisions.txt
index 5a286d0d61..fd01cb4fcc 100644
--- a/Documentation/revisions.txt
+++ b/Documentation/revisions.txt
@@ -96,6 +96,10 @@ some output processing may assume ref names in UTF-8.
refers to the branch that the branch specified by branchname is set to build on
top of. A missing branchname defaults to the current one.
+'<branchname>@\{publish\}', e.g. 'master@\{publish\}', '@\{p\}'::
+ The suffix '@\{publish\}' to a branchname refers to the remote branch to
+ push to. A missing branchname defaults to the current one.
+
'<rev>{caret}', e.g. 'HEAD{caret}, v1.5.1{caret}0'::
A suffix '{caret}' to a revision parameter means the first parent of
that commit object. '{caret}<n>' means the <n>th parent (i.e.
diff --git a/sha1_name.c b/sha1_name.c
index 45cfcfcab7..16bd8e0ef6 100644
--- a/sha1_name.c
+++ b/sha1_name.c
@@ -415,9 +415,9 @@ static int ambiguous_path(const char *path, int len)
return slash;
}
-static inline int upstream_mark(const char *string, int len)
+static inline int tracking_mark(const char *string, int len)
{
- const char *suffix[] = { "upstream", "u" };
+ const char *suffix[] = { "upstream", "u", "publish", "p" };
int i;
for (i = 0; i < ARRAY_SIZE(suffix); i++) {
@@ -475,7 +475,7 @@ static int get_sha1_basic(const char *str, int len, unsigned char *sha1)
nth_prior = 1;
continue;
}
- if (!upstream_mark(str + at + 2, len - at - 3)) {
+ if (!tracking_mark(str + at + 2, len - at - 3)) {
reflog_len = (len-1) - (at+2);
len = at;
}
@@ -1059,10 +1059,11 @@ static void set_shortened_ref(struct strbuf *buf, const char *ref)
free(s);
}
-static const char *get_upstream_branch(const char *name_buf, int len)
+static const char *get_tracking_branch(const char *name_buf, int len, char type)
{
char *name = xstrndup(name_buf, len);
struct branch *branch = branch_get(*name ? name : NULL);
+ char *tracking = NULL;
/*
* Upstream can be NULL only if branch refers to HEAD and HEAD
@@ -1070,23 +1071,35 @@ static const char *get_upstream_branch(const char *name_buf, int len)
*/
if (!branch)
die(_("HEAD does not point to a branch"));
- if (!branch->merge || !branch->merge[0]->dst) {
- if (!ref_exists(branch->refname))
- die(_("No such branch: '%s'"), name);
- if (!branch->merge) {
- die(_("No upstream configured for branch '%s'"),
- branch->name);
+ switch (type) {
+ case 'u':
+ if (!branch->merge || !branch->merge[0]->dst) {
+ if (!ref_exists(branch->refname))
+ die(_("No such branch: '%s'"), name);
+ if (!branch->merge) {
+ die(_("No upstream configured for branch '%s'"),
+ branch->name);
+ }
+ die(
+ _("Upstream branch '%s' not stored as a remote-tracking branch"),
+ branch->merge[0]->src);
+ }
+ tracking = branch->merge[0]->dst;
+ break;
+ case 'p':
+ if (!branch->push.dst) {
+ die(_("No publish configured for branch '%s'"),
+ branch->name);
}
- die(
- _("Upstream branch '%s' not stored as a remote-tracking branch"),
- branch->merge[0]->src);
+ tracking = branch->push.dst;
+ break;
}
free(name);
- return branch->merge[0]->dst;
+ return tracking;
}
-static int interpret_upstream_mark(const char *name, int namelen,
+static int interpret_tracking_mark(const char *name, int namelen,
int at, struct strbuf *buf)
{
int len;
@@ -1094,14 +1107,14 @@ static int interpret_upstream_mark(const char *name, int namelen,
if (name[at + 1] != '{' || name[namelen - 1] != '}')
return -1;
- len = upstream_mark(name + at + 2, namelen - at - 3);
+ len = tracking_mark(name + at + 2, namelen - at - 3);
if (!len)
return -1;
if (memchr(name, ':', at))
return -1;
- set_shortened_ref(buf, get_upstream_branch(name, at));
+ set_shortened_ref(buf, get_tracking_branch(name, at, name[at + 2]));
return len + at + 3;
}
@@ -1152,7 +1165,7 @@ int interpret_branch_name(const char *name, int namelen, struct strbuf *buf)
if (len > 0)
return reinterpret(name, namelen, len, buf);
- len = interpret_upstream_mark(name, namelen, at - name, buf);
+ len = interpret_tracking_mark(name, namelen, at - name, buf);
if (len > 0)
return len;
}
diff --git a/t/t1508-at-combinations.sh b/t/t1508-at-combinations.sh
index 078e1195df..f67aab3e69 100755
--- a/t/t1508-at-combinations.sh
+++ b/t/t1508-at-combinations.sh
@@ -32,6 +32,7 @@ fail() {
test_expect_success 'setup' '
test_commit master-one &&
test_commit master-two &&
+ git checkout -b publish-branch &&
git checkout -b upstream-branch &&
test_commit upstream-one &&
test_commit upstream-two &&
@@ -46,6 +47,7 @@ test_expect_success 'setup' '
test_commit new-two &&
git branch -u master old-branch &&
git branch -u upstream-branch new-branch
+ git branch -p publish-branch new-branch
'
check HEAD ref refs/heads/new-branch
@@ -61,8 +63,11 @@ check "HEAD@{u}" ref refs/heads/upstream-branch
check "@{u}@{1}" commit upstream-one
check "@{-1}@{u}" ref refs/heads/master
check "@{-1}@{u}@{1}" commit master-one
+check "@{p}" ref refs/heads/publish-branch
+check "HEAD@{p}" ref refs/heads/publish-branch
check "@" commit new-two
check "@@{u}" ref refs/heads/upstream-branch
+check "@@{p}" ref refs/heads/publish-branch
check "@@/at-test" ref refs/heads/@@/at-test
check "@/at-test" ref refs/heads/@/at-test
check "@at-test" ref refs/heads/@at-test