* [PATCH try2 7/8] push: add --set-publish option
2013-10-12 7:05 [PATCH try2 0/8] Introduce publish tracking branch Felipe Contreras
@ 2013-10-12 7:05 ` Felipe Contreras
2013-10-13 10:03 ` Eric Sunshine
2013-10-12 7:05 ` [PATCH try2 6/8] t: branch add publish branch tests Felipe Contreras
` (6 subsequent siblings)
7 siblings, 1 reply; 11+ messages in thread
From: Felipe Contreras @ 2013-10-12 7:05 UTC (permalink / raw)
To: git; +Cc: Matthieu Moy, Ramkumar Ramachandra, Felipe Contreras
To setup publish tracking branch, like 'git branch --set-publish'.
Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
---
Documentation/git-push.txt | 9 +++++-
builtin/push.c | 2 ++
t/t5529-push-publish.sh | 70 ++++++++++++++++++++++++++++++++++++++++++++++
transport.c | 28 +++++++++++++------
transport.h | 1 +
5 files changed, 100 insertions(+), 10 deletions(-)
create mode 100755 t/t5529-push-publish.sh
diff --git a/Documentation/git-push.txt b/Documentation/git-push.txt
index f7dfe48..6f3885d 100644
--- a/Documentation/git-push.txt
+++ b/Documentation/git-push.txt
@@ -10,7 +10,8 @@ SYNOPSIS
--------
[verse]
'git push' [--all | --mirror | --tags] [--follow-tags] [-n | --dry-run] [--receive-pack=<git-receive-pack>]
- [--repo=<repository>] [-f | --force] [--prune] [-v | --verbose] [-u | --set-upstream]
+ [--repo=<repository>] [-f | --force] [--prune] [-v | --verbose]
+ [-u | --set-upstream] [-p | --set-publish]
[--no-verify] [<repository> [<refspec>...]]
DESCRIPTION
@@ -171,6 +172,12 @@ useful if you write an alias or script around 'git push'.
linkgit:git-pull[1] and other commands. For more information,
see 'branch.<name>.merge' in linkgit:git-config[1].
+-p::
+--set-publish::
+ For every branch that is up to date or successfully pushed, add
+ publish branch tracking reference, used by argument-less
+ linkgit:git-pull[1] and other commands.
+
--[no-]thin::
These options are passed to linkgit:git-send-pack[1]. A thin transfer
significantly reduces the amount of sent data when the sender and
diff --git a/builtin/push.c b/builtin/push.c
index f2deddf..1c184b3 100644
--- a/builtin/push.c
+++ b/builtin/push.c
@@ -473,6 +473,8 @@ int cmd_push(int argc, const char **argv, const char *prefix)
OPT_STRING( 0 , "exec", &receivepack, "receive-pack", N_("receive pack program")),
OPT_BIT('u', "set-upstream", &flags, N_("set upstream for git pull/status"),
TRANSPORT_PUSH_SET_UPSTREAM),
+ OPT_BIT('p', "set-publish", &flags, N_("set publish for git pull/status"),
+ TRANSPORT_PUSH_SET_PUBLISH),
OPT_BOOL(0, "progress", &progress, N_("force progress reporting")),
OPT_BIT(0, "prune", &flags, N_("prune locally removed refs"),
TRANSPORT_PUSH_PRUNE),
diff --git a/t/t5529-push-publish.sh b/t/t5529-push-publish.sh
new file mode 100755
index 0000000..2037026
--- /dev/null
+++ b/t/t5529-push-publish.sh
@@ -0,0 +1,70 @@
+#!/bin/sh
+
+test_description='push with --set-publish'
+
+. ./test-lib.sh
+
+test_expect_success 'setup bare parent' '
+ git init --bare parent &&
+ git remote add publish parent
+'
+
+test_expect_success 'setup local commit' '
+ echo content >file &&
+ git add file &&
+ git commit -m one
+'
+
+check_config() {
+ (echo $2; echo $3) >expect.$1
+ (git config branch.$1.pushremote
+ git config branch.$1.push) >actual.$1
+ test_cmp expect.$1 actual.$1
+}
+
+test_expect_success 'push -p master:master' '
+ git push -p publish master:master &&
+ check_config master publish refs/heads/master
+'
+
+test_expect_success 'push -u master:other' '
+ git push -p publish master:other &&
+ check_config master publish refs/heads/other
+'
+
+test_expect_success 'push -p --dry-run master:otherX' '
+ git push -p --dry-run publish master:otherX &&
+ check_config master publish refs/heads/other
+'
+
+test_expect_success 'push -p master2:master2' '
+ git branch master2 &&
+ git push -p publish master2:master2 &&
+ check_config master2 publish refs/heads/master2
+'
+
+test_expect_success 'push -p master2:other2' '
+ git push -p publish master2:other2 &&
+ check_config master2 publish refs/heads/other2
+'
+
+test_expect_success 'push -p :master2' '
+ git push -p publish :master2 &&
+ check_config master2 publish refs/heads/other2
+'
+
+test_expect_success 'push -u --all' '
+ git branch all1 &&
+ git branch all2 &&
+ git push -p --all &&
+ check_config all1 publish refs/heads/all1 &&
+ check_config all2 publish refs/heads/all2
+'
+
+test_expect_success 'push -p HEAD' '
+ git checkout -b headbranch &&
+ git push -p publish HEAD &&
+ check_config headbranch publish refs/heads/headbranch
+'
+
+test_done
diff --git a/transport.c b/transport.c
index e15db98..d796732 100644
--- a/transport.c
+++ b/transport.c
@@ -140,8 +140,8 @@ static void insert_packed_refs(const char *packed_refs, struct ref **list)
}
}
-static void set_upstreams(struct transport *transport, struct ref *refs,
- int pretend)
+static void set_tracking(struct transport *transport, struct ref *refs,
+ int pretend, int publish)
{
struct ref *ref;
for (ref = refs; ref; ref = ref->next) {
@@ -176,12 +176,18 @@ static void set_upstreams(struct transport *transport, struct ref *refs,
if (!remotename || prefixcmp(remotename, "refs/heads/"))
continue;
- if (!pretend)
- install_branch_config(BRANCH_CONFIG_VERBOSE,
- localname + 11, transport->remote->name,
- remotename);
- else
- printf("Would set upstream of '%s' to '%s' of '%s'\n",
+ if (!pretend) {
+ if (publish)
+ install_branch_publish(localname + 11,
+ transport->remote->name,
+ remotename);
+ else
+ install_branch_config(BRANCH_CONFIG_VERBOSE,
+ localname + 11, transport->remote->name,
+ remotename);
+ } else
+ printf("Would set %s of '%s' to '%s' of '%s'\n",
+ publish ? "publish" : "upstream",
localname + 11, remotename + 11,
transport->remote->name);
}
@@ -1113,6 +1119,8 @@ int transport_push(struct transport *transport,
/* Maybe FIXME. But no important transport uses this case. */
if (flags & TRANSPORT_PUSH_SET_UPSTREAM)
die("This transport does not support using --set-upstream");
+ if (flags & TRANSPORT_PUSH_SET_PUBLISH)
+ die("This transport does not support using --set-publish");
return transport->push(transport, refspec_nr, refspec, flags);
} else if (transport->push_refs) {
@@ -1181,7 +1189,9 @@ int transport_push(struct transport *transport,
reject_reasons);
if (flags & TRANSPORT_PUSH_SET_UPSTREAM)
- set_upstreams(transport, remote_refs, pretend);
+ set_tracking(transport, remote_refs, pretend, 0);
+ if (flags & TRANSPORT_PUSH_SET_PUBLISH)
+ set_tracking(transport, remote_refs, pretend, 1);
if (!(flags & TRANSPORT_PUSH_DRY_RUN)) {
struct ref *ref;
diff --git a/transport.h b/transport.h
index ea70ea7..715e6d5 100644
--- a/transport.h
+++ b/transport.h
@@ -108,6 +108,7 @@ struct transport {
#define TRANSPORT_RECURSE_SUBMODULES_ON_DEMAND 256
#define TRANSPORT_PUSH_NO_HOOK 512
#define TRANSPORT_PUSH_FOLLOW_TAGS 1024
+#define TRANSPORT_PUSH_SET_PUBLISH 2048
#define TRANSPORT_SUMMARY_WIDTH (2 * DEFAULT_ABBREV + 3)
#define TRANSPORT_SUMMARY(x) (int)(TRANSPORT_SUMMARY_WIDTH + strlen(x) - gettext_width(x)), (x)
--
1.8.4-fc
^ permalink raw reply related [flat|nested] 11+ messages in thread
* Re: [PATCH try2 7/8] push: add --set-publish option
2013-10-12 7:05 ` [PATCH try2 7/8] push: add --set-publish option Felipe Contreras
@ 2013-10-13 10:03 ` Eric Sunshine
2013-10-13 10:15 ` Felipe Contreras
0 siblings, 1 reply; 11+ messages in thread
From: Eric Sunshine @ 2013-10-13 10:03 UTC (permalink / raw)
To: Felipe Contreras; +Cc: Git List, Matthieu Moy, Ramkumar Ramachandra
On Sat, Oct 12, 2013 at 3:05 AM, Felipe Contreras
<felipe.contreras@gmail.com> wrote:
> diff --git a/t/t5529-push-publish.sh b/t/t5529-push-publish.sh
> new file mode 100755
> index 0000000..2037026
> --- /dev/null
> +++ b/t/t5529-push-publish.sh
> @@ -0,0 +1,70 @@
> +#!/bin/sh
> +
> +test_description='push with --set-publish'
> +
> +. ./test-lib.sh
> +
> +test_expect_success 'setup bare parent' '
> + git init --bare parent &&
> + git remote add publish parent
> +'
> +
> +test_expect_success 'setup local commit' '
> + echo content >file &&
> + git add file &&
> + git commit -m one
> +'
> +
> +check_config() {
> + (echo $2; echo $3) >expect.$1
> + (git config branch.$1.pushremote
> + git config branch.$1.push) >actual.$1
> + test_cmp expect.$1 actual.$1
> +}
Do you want to maintain &&-chain in this test?
> +
> +test_expect_success 'push -p master:master' '
> + git push -p publish master:master &&
> + check_config master publish refs/heads/master
> +'
> +
> +test_expect_success 'push -u master:other' '
> + git push -p publish master:other &&
> + check_config master publish refs/heads/other
> +'
> +
> +test_expect_success 'push -p --dry-run master:otherX' '
> + git push -p --dry-run publish master:otherX &&
> + check_config master publish refs/heads/other
> +'
> +
> +test_expect_success 'push -p master2:master2' '
> + git branch master2 &&
> + git push -p publish master2:master2 &&
> + check_config master2 publish refs/heads/master2
> +'
> +
> +test_expect_success 'push -p master2:other2' '
> + git push -p publish master2:other2 &&
> + check_config master2 publish refs/heads/other2
> +'
> +
> +test_expect_success 'push -p :master2' '
> + git push -p publish :master2 &&
> + check_config master2 publish refs/heads/other2
> +'
> +
> +test_expect_success 'push -u --all' '
> + git branch all1 &&
> + git branch all2 &&
> + git push -p --all &&
> + check_config all1 publish refs/heads/all1 &&
> + check_config all2 publish refs/heads/all2
> +'
> +
> +test_expect_success 'push -p HEAD' '
> + git checkout -b headbranch &&
> + git push -p publish HEAD &&
> + check_config headbranch publish refs/heads/headbranch
> +'
> +
> +test_done
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH try2 7/8] push: add --set-publish option
2013-10-13 10:03 ` Eric Sunshine
@ 2013-10-13 10:15 ` Felipe Contreras
0 siblings, 0 replies; 11+ messages in thread
From: Felipe Contreras @ 2013-10-13 10:15 UTC (permalink / raw)
To: Eric Sunshine; +Cc: Git List, Matthieu Moy, Ramkumar Ramachandra
On Sun, Oct 13, 2013 at 5:03 AM, Eric Sunshine <sunshine@sunshineco.com> wrote:
> On Sat, Oct 12, 2013 at 3:05 AM, Felipe Contreras
> <felipe.contreras@gmail.com> wrote:
>> diff --git a/t/t5529-push-publish.sh b/t/t5529-push-publish.sh
>> new file mode 100755
>> index 0000000..2037026
>> --- /dev/null
>> +++ b/t/t5529-push-publish.sh
>> @@ -0,0 +1,70 @@
>> +#!/bin/sh
>> +
>> +test_description='push with --set-publish'
>> +
>> +. ./test-lib.sh
>> +
>> +test_expect_success 'setup bare parent' '
>> + git init --bare parent &&
>> + git remote add publish parent
>> +'
>> +
>> +test_expect_success 'setup local commit' '
>> + echo content >file &&
>> + git add file &&
>> + git commit -m one
>> +'
>> +
>> +check_config() {
>> + (echo $2; echo $3) >expect.$1
>> + (git config branch.$1.pushremote
>> + git config branch.$1.push) >actual.$1
>> + test_cmp expect.$1 actual.$1
>> +}
>
> Do you want to maintain &&-chain in this test?
As much as we want to do it in t/t5523-push-upstream.sh, which has
this exact function.
--
Felipe Contreras
^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH try2 6/8] t: branch add publish branch tests
2013-10-12 7:05 [PATCH try2 0/8] Introduce publish tracking branch Felipe Contreras
2013-10-12 7:05 ` [PATCH try2 7/8] push: add --set-publish option Felipe Contreras
@ 2013-10-12 7:05 ` Felipe Contreras
2013-10-12 7:05 ` [PATCH try2 4/8] Add concept of 'publish' branch Felipe Contreras
` (5 subsequent siblings)
7 siblings, 0 replies; 11+ messages in thread
From: Felipe Contreras @ 2013-10-12 7:05 UTC (permalink / raw)
To: git; +Cc: Matthieu Moy, Ramkumar Ramachandra, Felipe Contreras
Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
---
t/t3200-branch.sh | 76 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 76 insertions(+)
diff --git a/t/t3200-branch.sh b/t/t3200-branch.sh
index 44ec6a4..cd0b8e9 100755
--- a/t/t3200-branch.sh
+++ b/t/t3200-branch.sh
@@ -870,4 +870,80 @@ test_expect_success '--merged catches invalid object names' '
test_must_fail git branch --merged 0000000000000000000000000000000000000000
'
+test_expect_success '--set-publish-to fails on multiple branches' '
+ test_must_fail git branch --set-publish-to master a b c
+'
+
+test_expect_success '--set-publish-to fails on detached HEAD' '
+ test_when_finished "git checkout master" &&
+ git checkout master^{} &&
+ test_must_fail git branch --set-publish-to master
+'
+
+test_expect_success '--set-publish-to fails on a missing dst branch' '
+ test_must_fail git branch --set-publish-to master does-not-exist
+'
+
+test_expect_success '--set-publish-to fails on a missing src branch' '
+ test_must_fail git branch --set-publish-to does-not-exist master
+'
+
+test_expect_success '--set-publish-to fails on a non-ref' '
+ test_must_fail git branch --set-publish-to HEAD^{}
+'
+
+test_expect_success 'use --set-publish-to modify HEAD' '
+ git checkout master &&
+ test_config branch.master.pushremote foo &&
+ test_config branch.master.push foo &&
+ git branch -f test &&
+ git branch --set-publish-to test &&
+ test "$(git config branch.master.pushremote)" = "." &&
+ test "$(git config branch.master.push)" = "refs/heads/test"
+'
+
+test_expect_success 'use --set-publish-to modify a particular branch' '
+ git branch -f test &&
+ git branch -f test2 &&
+ git branch --set-publish-to test2 test &&
+ test "$(git config branch.test.pushremote)" = "." &&
+ test "$(git config branch.test.push)" = "refs/heads/test2"
+'
+
+test_expect_success '--unset-publish should fail if given a non-existent branch' '
+ test_must_fail git branch --unset-publish i-dont-exist
+'
+
+test_expect_success 'test --unset-publish on HEAD' '
+ git checkout master &&
+ git branch -f test &&
+ test_config branch.master.pushremote foo &&
+ test_config branch.master.push foo &&
+ git branch --set-publish-to test &&
+ git branch --unset-publish &&
+ test_must_fail git config branch.master.pushremote &&
+ test_must_fail git config branch.master.push &&
+ # fail for a branch without publish set
+ test_must_fail git branch --unset-publish
+'
+
+test_expect_success '--unset-publish should fail on multiple branches' '
+ test_must_fail git branch --unset-publish a b c
+'
+
+test_expect_success '--unset-publish should fail on detached HEAD' '
+ test_when_finished "git checkout -" &&
+ git checkout HEAD^{} &&
+ test_must_fail git branch --unset-publish
+'
+
+test_expect_success 'test --unset-publish on a particular branch' '
+ git branch -f test &&
+ git branch -f test2 &&
+ git branch --set-publish-to test2 test &&
+ git branch --unset-publish test &&
+ test_must_fail git config branch.test2.pushremote &&
+ test_must_fail git config branch.test2.push
+'
+
test_done
--
1.8.4-fc
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH try2 4/8] Add concept of 'publish' branch
2013-10-12 7:05 [PATCH try2 0/8] Introduce publish tracking branch Felipe Contreras
2013-10-12 7:05 ` [PATCH try2 7/8] push: add --set-publish option Felipe Contreras
2013-10-12 7:05 ` [PATCH try2 6/8] t: branch add publish branch tests Felipe Contreras
@ 2013-10-12 7:05 ` Felipe Contreras
2013-10-12 7:05 ` [PATCH try2 1/8] branch: trivial cleanup Felipe Contreras
` (4 subsequent siblings)
7 siblings, 0 replies; 11+ messages in thread
From: Felipe Contreras @ 2013-10-12 7:05 UTC (permalink / raw)
To: git; +Cc: Matthieu Moy, Ramkumar Ramachandra, Felipe Contreras
The upstream branch is:
branch.$name.remote
branch.$name.merge
The publish branch is:
branch.$name.pushremote
branch.$name.push
Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
---
builtin/push.c | 19 +++++++++++++++----
remote.c | 34 ++++++++++++++++++++++++++++------
remote.h | 4 ++++
3 files changed, 47 insertions(+), 10 deletions(-)
diff --git a/builtin/push.c b/builtin/push.c
index 5dc06a3..f2deddf 100644
--- a/builtin/push.c
+++ b/builtin/push.c
@@ -150,6 +150,20 @@ static void setup_push_current(struct remote *remote, struct branch *branch)
add_refspec(branch->name);
}
+static void setup_push_simple(struct remote *remote, struct branch *branch,
+ int triangular)
+{
+ if (branch->push_name) {
+ struct strbuf refspec = STRBUF_INIT;
+ strbuf_addf(&refspec, "%s:%s", branch->name, branch->push_name);
+ add_refspec(refspec.buf);
+ } else if (triangular) {
+ setup_push_current(remote, branch);
+ } else {
+ setup_push_upstream(remote, branch, triangular);
+ }
+}
+
static char warn_unspecified_push_default_msg[] =
N_("push.default is unset; its implicit value is changing in\n"
"Git 2.0 from 'matching' to 'simple'. To squelch this message\n"
@@ -210,10 +224,7 @@ static void setup_default_push_refspecs(struct remote *remote)
break;
case PUSH_DEFAULT_SIMPLE:
- if (triangular)
- setup_push_current(remote, get_current_branch(remote));
- else
- setup_push_upstream(remote, get_current_branch(remote), triangular);
+ setup_push_simple(remote, get_current_branch(remote), triangular);
break;
case PUSH_DEFAULT_UPSTREAM:
diff --git a/remote.c b/remote.c
index efcba93..04c7ed9 100644
--- a/remote.c
+++ b/remote.c
@@ -350,13 +350,17 @@ static int handle_config(const char *key, const char *value, void *cb)
explicit_default_remote_name = 1;
}
} else if (!strcmp(subkey, ".pushremote")) {
+ if (git_config_string(&branch->pushremote_name, key, value))
+ return -1;
if (branch == current_branch)
- if (git_config_string(&pushremote_name, key, value))
- return -1;
+ pushremote_name = xstrdup(branch->pushremote_name);
} else if (!strcmp(subkey, ".merge")) {
if (!value)
return config_error_nonbool(key);
add_merge(branch, xstrdup(value));
+ } else if (!strcmp(subkey, ".push")) {
+ if (git_config_string(&branch->push_name, key, value))
+ return -1;
}
return 0;
}
@@ -1492,6 +1496,14 @@ struct branch *branch_get(const char *name)
}
}
}
+ if (ret && ret->pushremote_name) {
+ struct remote *pushremote;
+ pushremote = pushremote_get(ret->pushremote_name);
+ ret->push.src = xstrdup(ret->push_name);
+ if (remote_find_tracking(pushremote, &ret->push)
+ && !strcmp(ret->pushremote_name, "."))
+ ret->push.dst = xstrdup(ret->push_name);
+ }
return ret;
}
@@ -1694,6 +1706,15 @@ int ref_newer(const unsigned char *new_sha1, const unsigned char *old_sha1)
return found;
}
+static char *get_base(struct branch *branch)
+{
+ if (branch->push.dst)
+ return branch->push.dst;
+ if (branch->merge && branch->merge[0] && branch->merge[0]->dst)
+ return branch->merge[0]->dst;
+ return NULL;
+}
+
/*
* Return true if there is anything to report, otherwise false.
*/
@@ -1710,15 +1731,16 @@ int stat_tracking_info(struct branch *branch, int *num_ours, int *num_theirs)
* Nothing to report unless we are marked to build on top of
* somebody else.
*/
- if (!branch ||
- !branch->merge || !branch->merge[0] || !branch->merge[0]->dst)
+ if (!branch)
+ return 0;
+ base = get_base(branch);
+ if (!base)
return 0;
/*
* If what we used to build on no longer exists, there is
* nothing to report.
*/
- base = branch->merge[0]->dst;
if (read_ref(base, sha1))
return 0;
theirs = lookup_commit_reference(sha1);
@@ -1781,7 +1803,7 @@ int format_tracking_info(struct branch *branch, struct strbuf *sb)
if (!stat_tracking_info(branch, &num_ours, &num_theirs))
return 0;
- base = branch->merge[0]->dst;
+ base = get_base(branch);
base = shorten_unambiguous_ref(base, 0);
if (!num_theirs) {
strbuf_addf(sb,
diff --git a/remote.h b/remote.h
index cf56724..79e5adf 100644
--- a/remote.h
+++ b/remote.h
@@ -138,6 +138,10 @@ struct branch {
struct refspec **merge;
int merge_nr;
int merge_alloc;
+
+ const char *pushremote_name;
+ const char *push_name;
+ struct refspec push;
};
struct branch *branch_get(const char *name);
--
1.8.4-fc
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH try2 1/8] branch: trivial cleanup
2013-10-12 7:05 [PATCH try2 0/8] Introduce publish tracking branch Felipe Contreras
` (2 preceding siblings ...)
2013-10-12 7:05 ` [PATCH try2 4/8] Add concept of 'publish' branch Felipe Contreras
@ 2013-10-12 7:05 ` Felipe Contreras
2013-10-12 7:05 ` [PATCH try2 2/8] branch: reorganize verbose options Felipe Contreras
` (3 subsequent siblings)
7 siblings, 0 replies; 11+ messages in thread
From: Felipe Contreras @ 2013-10-12 7:05 UTC (permalink / raw)
To: git; +Cc: Matthieu Moy, Ramkumar Ramachandra, Felipe Contreras
No functional changes.
Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
---
builtin/branch.c | 19 +++++++++----------
1 file changed, 9 insertions(+), 10 deletions(-)
diff --git a/builtin/branch.c b/builtin/branch.c
index 0836890..ac17b18 100644
--- a/builtin/branch.c
+++ b/builtin/branch.c
@@ -425,16 +425,15 @@ static void fill_tracking_info(struct strbuf *stat, const char *branch_name,
struct strbuf fancy = STRBUF_INIT;
if (!stat_tracking_info(branch, &ours, &theirs)) {
- if (branch && branch->merge && branch->merge[0]->dst &&
- show_upstream_ref) {
- ref = shorten_unambiguous_ref(branch->merge[0]->dst, 0);
- if (want_color(branch_use_color))
- strbuf_addf(stat, "[%s%s%s] ",
- branch_get_color(BRANCH_COLOR_UPSTREAM),
- ref, branch_get_color(BRANCH_COLOR_RESET));
- else
- strbuf_addf(stat, "[%s] ", ref);
- }
+ if (!branch || !branch->merge || !branch->merge[0]->dst || !show_upstream_ref)
+ return;
+ ref = shorten_unambiguous_ref(branch->merge[0]->dst, 0);
+ if (want_color(branch_use_color))
+ strbuf_addf(stat, "[%s%s%s] ",
+ branch_get_color(BRANCH_COLOR_UPSTREAM),
+ ref, branch_get_color(BRANCH_COLOR_RESET));
+ else
+ strbuf_addf(stat, "[%s] ", ref);
return;
}
--
1.8.4-fc
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH try2 2/8] branch: reorganize verbose options
2013-10-12 7:05 [PATCH try2 0/8] Introduce publish tracking branch Felipe Contreras
` (3 preceding siblings ...)
2013-10-12 7:05 ` [PATCH try2 1/8] branch: trivial cleanup Felipe Contreras
@ 2013-10-12 7:05 ` Felipe Contreras
2013-10-12 7:05 ` [PATCH try2 3/8] push: trivial reorganization Felipe Contreras
` (2 subsequent siblings)
7 siblings, 0 replies; 11+ messages in thread
From: Felipe Contreras @ 2013-10-12 7:05 UTC (permalink / raw)
To: git; +Cc: Matthieu Moy, Ramkumar Ramachandra, Felipe Contreras
Showing the upstream tracking branch is more important than how many
commits are ahead/behind, so now 'git branch -v' shows the upstream, but
not the tracking info, and 'git branch -vv' shows all information (as
before).
Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
---
builtin/branch.c | 22 ++++++++++------------
t/t6040-tracking-info.sh | 8 ++++----
2 files changed, 14 insertions(+), 16 deletions(-)
diff --git a/builtin/branch.c b/builtin/branch.c
index ac17b18..baa1d31 100644
--- a/builtin/branch.c
+++ b/builtin/branch.c
@@ -417,15 +417,15 @@ static int ref_cmp(const void *r1, const void *r2)
}
static void fill_tracking_info(struct strbuf *stat, const char *branch_name,
- int show_upstream_ref)
+ int show_tracking)
{
int ours, theirs;
char *ref = NULL;
struct branch *branch = branch_get(branch_name);
struct strbuf fancy = STRBUF_INIT;
- if (!stat_tracking_info(branch, &ours, &theirs)) {
- if (!branch || !branch->merge || !branch->merge[0]->dst || !show_upstream_ref)
+ if (!show_tracking || !stat_tracking_info(branch, &ours, &theirs)) {
+ if (!branch || !branch->merge || !branch->merge[0]->dst)
return;
ref = shorten_unambiguous_ref(branch->merge[0]->dst, 0);
if (want_color(branch_use_color))
@@ -437,15 +437,13 @@ static void fill_tracking_info(struct strbuf *stat, const char *branch_name,
return;
}
- if (show_upstream_ref) {
- ref = shorten_unambiguous_ref(branch->merge[0]->dst, 0);
- if (want_color(branch_use_color))
- strbuf_addf(&fancy, "%s%s%s",
- branch_get_color(BRANCH_COLOR_UPSTREAM),
- ref, branch_get_color(BRANCH_COLOR_RESET));
- else
- strbuf_addstr(&fancy, ref);
- }
+ ref = shorten_unambiguous_ref(branch->merge[0]->dst, 0);
+ if (want_color(branch_use_color))
+ strbuf_addf(&fancy, "%s%s%s",
+ branch_get_color(BRANCH_COLOR_UPSTREAM),
+ ref, branch_get_color(BRANCH_COLOR_RESET));
+ else
+ strbuf_addstr(&fancy, ref);
if (!ours) {
if (ref)
diff --git a/t/t6040-tracking-info.sh b/t/t6040-tracking-info.sh
index ec2b516..86e80eb 100755
--- a/t/t6040-tracking-info.sh
+++ b/t/t6040-tracking-info.sh
@@ -36,10 +36,10 @@ test_expect_success setup '
script='s/^..\(b.\)[ 0-9a-f]*\[\([^]]*\)\].*/\1 \2/p'
cat >expect <<\EOF
-b1 ahead 1, behind 1
-b2 ahead 1, behind 1
-b3 behind 1
-b4 ahead 2
+b1 origin/master
+b2 origin/master
+b3 origin/master
+b4 origin/master
EOF
test_expect_success 'branch -v' '
--
1.8.4-fc
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH try2 3/8] push: trivial reorganization
2013-10-12 7:05 [PATCH try2 0/8] Introduce publish tracking branch Felipe Contreras
` (4 preceding siblings ...)
2013-10-12 7:05 ` [PATCH try2 2/8] branch: reorganize verbose options Felipe Contreras
@ 2013-10-12 7:05 ` Felipe Contreras
2013-10-12 7:06 ` [PATCH try2 8/8] branch: display publish branch Felipe Contreras
2013-10-12 7:06 ` [PATCH try2 5/8] branch: allow configuring the " Felipe Contreras
7 siblings, 0 replies; 11+ messages in thread
From: Felipe Contreras @ 2013-10-12 7:05 UTC (permalink / raw)
To: git; +Cc: Matthieu Moy, Ramkumar Ramachandra, Felipe Contreras
Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
---
builtin/push.c | 35 +++++++++++++++++++----------------
1 file changed, 19 insertions(+), 16 deletions(-)
diff --git a/builtin/push.c b/builtin/push.c
index 04f0eaf..5dc06a3 100644
--- a/builtin/push.c
+++ b/builtin/push.c
@@ -113,20 +113,11 @@ static NORETURN int die_push_simple(struct branch *branch, struct remote *remote
remote->name, branch->name, advice_maybe);
}
-static const char message_detached_head_die[] =
- N_("You are not currently on a branch.\n"
- "To push the history leading to the current (detached HEAD)\n"
- "state now, use\n"
- "\n"
- " git push %s HEAD:<name-of-remote-branch>\n");
-
static void setup_push_upstream(struct remote *remote, struct branch *branch,
int triangular)
{
struct strbuf refspec = STRBUF_INIT;
- if (!branch)
- die(_(message_detached_head_die), remote->name);
if (!branch->merge_nr || !branch->merge || !branch->remote_name)
die(_("The current branch %s has no upstream branch.\n"
"To push the current branch and set the remote as upstream, use\n"
@@ -156,8 +147,6 @@ static void setup_push_upstream(struct remote *remote, struct branch *branch,
static void setup_push_current(struct remote *remote, struct branch *branch)
{
- if (!branch)
- die(_(message_detached_head_die), remote->name);
add_refspec(branch->name);
}
@@ -191,9 +180,23 @@ static int is_workflow_triangular(struct remote *remote)
return (fetch_remote && fetch_remote != remote);
}
-static void setup_default_push_refspecs(struct remote *remote)
+static const char message_detached_head_die[] =
+ N_("You are not currently on a branch.\n"
+ "To push the history leading to the current (detached HEAD)\n"
+ "state now, use\n"
+ "\n"
+ " git push %s HEAD:<name-of-remote-branch>\n");
+
+static struct branch *get_current_branch(struct remote *remote)
{
struct branch *branch = branch_get(NULL);
+ if (!branch)
+ die(_(message_detached_head_die), remote->name);
+ return branch;
+}
+
+static void setup_default_push_refspecs(struct remote *remote)
+{
int triangular = is_workflow_triangular(remote);
switch (push_default) {
@@ -208,17 +211,17 @@ static void setup_default_push_refspecs(struct remote *remote)
case PUSH_DEFAULT_SIMPLE:
if (triangular)
- setup_push_current(remote, branch);
+ setup_push_current(remote, get_current_branch(remote));
else
- setup_push_upstream(remote, branch, triangular);
+ setup_push_upstream(remote, get_current_branch(remote), triangular);
break;
case PUSH_DEFAULT_UPSTREAM:
- setup_push_upstream(remote, branch, triangular);
+ setup_push_upstream(remote, get_current_branch(remote), triangular);
break;
case PUSH_DEFAULT_CURRENT:
- setup_push_current(remote, branch);
+ setup_push_current(remote, get_current_branch(remote));
break;
case PUSH_DEFAULT_NOTHING:
--
1.8.4-fc
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH try2 8/8] branch: display publish branch
2013-10-12 7:05 [PATCH try2 0/8] Introduce publish tracking branch Felipe Contreras
` (5 preceding siblings ...)
2013-10-12 7:05 ` [PATCH try2 3/8] push: trivial reorganization Felipe Contreras
@ 2013-10-12 7:06 ` Felipe Contreras
2013-10-12 7:06 ` [PATCH try2 5/8] branch: allow configuring the " Felipe Contreras
7 siblings, 0 replies; 11+ messages in thread
From: Felipe Contreras @ 2013-10-12 7:06 UTC (permalink / raw)
To: git; +Cc: Matthieu Moy, Ramkumar Ramachandra, Felipe Contreras
Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
---
builtin/branch.c | 52 +++++++++++++++++++++++++++++++++++++++++++---------
1 file changed, 43 insertions(+), 9 deletions(-)
diff --git a/builtin/branch.c b/builtin/branch.c
index cf33e1c..9f15f7e 100644
--- a/builtin/branch.c
+++ b/builtin/branch.c
@@ -42,6 +42,7 @@ static char branch_colors[][COLOR_MAXLEN] = {
GIT_COLOR_NORMAL, /* LOCAL */
GIT_COLOR_GREEN, /* CURRENT */
GIT_COLOR_BLUE, /* UPSTREAM */
+ GIT_COLOR_YELLOW, /* PUBLISH */
};
enum color_branch {
BRANCH_COLOR_RESET = 0,
@@ -49,7 +50,8 @@ enum color_branch {
BRANCH_COLOR_REMOTE = 2,
BRANCH_COLOR_LOCAL = 3,
BRANCH_COLOR_CURRENT = 4,
- BRANCH_COLOR_UPSTREAM = 5
+ BRANCH_COLOR_UPSTREAM = 5,
+ BRANCH_COLOR_PUBLISH = 6
};
static enum merge_filter {
@@ -76,6 +78,8 @@ static int parse_branch_color_slot(const char *var, int ofs)
return BRANCH_COLOR_CURRENT;
if (!strcasecmp(var+ofs, "upstream"))
return BRANCH_COLOR_UPSTREAM;
+ if (!strcasecmp(var+ofs, "publish"))
+ return BRANCH_COLOR_PUBLISH;
return -1;
}
@@ -424,16 +428,35 @@ static void fill_tracking_info(struct strbuf *stat, const char *branch_name,
struct branch *branch = branch_get(branch_name);
struct strbuf fancy = STRBUF_INIT;
+ if (!branch)
+ return;
+
if (!show_tracking || !stat_tracking_info(branch, &ours, &theirs)) {
- if (!branch || !branch->merge || !branch->merge[0]->dst)
+ if (branch->merge && branch->merge[0]->dst) {
+ ref = shorten_unambiguous_ref(branch->merge[0]->dst, 0);
+ if (want_color(branch_use_color))
+ strbuf_addf(&fancy, "%s%s%s",
+ branch_get_color(BRANCH_COLOR_UPSTREAM),
+ ref, branch_get_color(BRANCH_COLOR_RESET));
+ else
+ strbuf_addstr(&fancy, ref);
+ }
+ if (branch->push.dst) {
+ ref = shorten_unambiguous_ref(branch->push.dst, 0);
+ if (fancy.len)
+ strbuf_addstr(&fancy, ", ");
+ if (want_color(branch_use_color))
+ strbuf_addf(&fancy, "%s%s%s",
+ branch_get_color(BRANCH_COLOR_PUBLISH),
+ ref, branch_get_color(BRANCH_COLOR_RESET));
+ else
+ strbuf_addstr(&fancy, ref);
+ }
+ if (!fancy.len)
return;
- ref = shorten_unambiguous_ref(branch->merge[0]->dst, 0);
- if (want_color(branch_use_color))
- strbuf_addf(stat, "[%s%s%s] ",
- branch_get_color(BRANCH_COLOR_UPSTREAM),
- ref, branch_get_color(BRANCH_COLOR_RESET));
- else
- strbuf_addf(stat, "[%s] ", ref);
+ strbuf_addf(stat, _("[%s]"), fancy.buf);
+ strbuf_release(&fancy);
+ strbuf_addch(stat, ' ');
return;
}
@@ -444,6 +467,17 @@ static void fill_tracking_info(struct strbuf *stat, const char *branch_name,
ref, branch_get_color(BRANCH_COLOR_RESET));
else
strbuf_addstr(&fancy, ref);
+ if (branch->push.dst) {
+ ref = shorten_unambiguous_ref(branch->push.dst, 0);
+ if (fancy.len)
+ strbuf_addstr(&fancy, ", ");
+ if (want_color(branch_use_color))
+ strbuf_addf(&fancy, "%s%s%s",
+ branch_get_color(BRANCH_COLOR_PUBLISH),
+ ref, branch_get_color(BRANCH_COLOR_RESET));
+ else
+ strbuf_addstr(&fancy, ref);
+ }
if (!ours) {
if (ref)
--
1.8.4-fc
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH try2 5/8] branch: allow configuring the publish branch
2013-10-12 7:05 [PATCH try2 0/8] Introduce publish tracking branch Felipe Contreras
` (6 preceding siblings ...)
2013-10-12 7:06 ` [PATCH try2 8/8] branch: display publish branch Felipe Contreras
@ 2013-10-12 7:06 ` Felipe Contreras
7 siblings, 0 replies; 11+ messages in thread
From: Felipe Contreras @ 2013-10-12 7:06 UTC (permalink / raw)
To: git; +Cc: Matthieu Moy, Ramkumar Ramachandra, Felipe Contreras
Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
---
Documentation/git-branch.txt | 11 +++++++++
branch.c | 43 ++++++++++++++++++++++++++++++++++
branch.h | 2 ++
builtin/branch.c | 56 ++++++++++++++++++++++++++++++++++++++++----
4 files changed, 108 insertions(+), 4 deletions(-)
diff --git a/Documentation/git-branch.txt b/Documentation/git-branch.txt
index b7cb625..1bf9b2a 100644
--- a/Documentation/git-branch.txt
+++ b/Documentation/git-branch.txt
@@ -14,7 +14,9 @@ SYNOPSIS
[(--merged | --no-merged | --contains) [<commit>]] [<pattern>...]
'git branch' [--set-upstream | --track | --no-track] [-l] [-f] <branchname> [<start-point>]
'git branch' (--set-upstream-to=<upstream> | -u <upstream>) [<branchname>]
+'git branch' (--set-publish-to=<publish> | -p <publish>) [<branchname>]
'git branch' --unset-upstream [<branchname>]
+'git branch' --unset-publish [<branchname>]
'git branch' (-m | -M) [<oldbranch>] <newbranch>
'git branch' (-d | -D) [-r] <branchname>...
'git branch' --edit-description [<branchname>]
@@ -189,6 +191,15 @@ start-point is either a local or remote-tracking branch.
Remove the upstream information for <branchname>. If no branch
is specified it defaults to the current branch.
+-p <publish>::
+--set-publish-to=<publish>::
+ Set up <branchname>'s publish tracking information. If no
+ <branchname> is specified, then it defaults to the current branch.
+
+--unset-publish::
+ Remove the publish information for <branchname>. If no branch
+ is specified it defaults to the current branch.
+
--edit-description::
Open an editor and edit the text to explain what the branch is
for, to be used by various other commands (e.g. `request-pull`).
diff --git a/branch.c b/branch.c
index c5c6984..02495e3 100644
--- a/branch.c
+++ b/branch.c
@@ -144,6 +144,49 @@ static int setup_tracking(const char *new_ref, const char *orig_ref,
return 0;
}
+void install_branch_publish(const char *name, const char *remote, const char *remote_ref)
+{
+ struct strbuf key = STRBUF_INIT;
+
+ if (!remote && !strcmp(name, remote_ref + 11) && !prefixcmp(remote_ref, "refs/heads")) {
+ warning(_("Not setting branch %s as its own publish branch."), name);
+ return;
+ }
+
+ strbuf_addf(&key, "branch.%s.pushremote", name);
+ git_config_set(key.buf, remote ? remote : ".");
+
+ strbuf_reset(&key);
+ strbuf_addf(&key, "branch.%s.push", name);
+ git_config_set(key.buf, remote_ref);
+
+ strbuf_release(&key);
+}
+
+int setup_publish(const char *name, const char *ref)
+{
+ struct tracking tracking;
+ const char *remote, *remote_ref;
+
+ memset(&tracking, 0, sizeof(tracking));
+ tracking.spec.dst = (char*)ref;
+ if (for_each_remote(find_tracked_branch, &tracking))
+ return 1;
+
+ if (tracking.matches > 1)
+ return error(_("Not tracking: ambiguous information for ref %s"),
+ ref);
+
+ remote = tracking.remote;
+ remote_ref = tracking.src ? tracking.src : ref;
+
+ install_branch_publish(name, remote, remote_ref);
+
+ free(tracking.src);
+
+ return 0;
+}
+
struct branch_desc_cb {
const char *config_name;
const char *value;
diff --git a/branch.h b/branch.h
index 64173ab..c9b6aa9 100644
--- a/branch.h
+++ b/branch.h
@@ -51,5 +51,7 @@ extern void install_branch_config(int flag, const char *local, const char *origi
* Read branch description
*/
extern int read_branch_desc(struct strbuf *, const char *branch_name);
+extern int setup_publish(const char *name, const char *ref);
+extern void install_branch_publish(const char *name, const char *remote, const char *remote_ref);
#endif
diff --git a/builtin/branch.c b/builtin/branch.c
index baa1d31..cf33e1c 100644
--- a/builtin/branch.c
+++ b/builtin/branch.c
@@ -778,8 +778,8 @@ int cmd_branch(int argc, const char **argv, const char *prefix)
int delete = 0, rename = 0, force_create = 0, list = 0;
int verbose = 0, abbrev = -1, detached = 0;
int reflog = 0, edit_description = 0;
- int quiet = 0, unset_upstream = 0;
- const char *new_upstream = NULL;
+ int quiet = 0, unset_upstream = 0, unset_publish = 0;
+ const char *new_upstream = NULL, *publish = NULL;
enum branch_track track;
int kinds = REF_LOCAL_BRANCH;
struct commit_list *with_commit = NULL;
@@ -794,7 +794,9 @@ int cmd_branch(int argc, const char **argv, const char *prefix)
OPT_SET_INT( 0, "set-upstream", &track, N_("change upstream info"),
BRANCH_TRACK_OVERRIDE),
OPT_STRING('u', "set-upstream-to", &new_upstream, "upstream", "change the upstream info"),
+ OPT_STRING('p', "set-publish-to", &publish, "publish", "change the publish info"),
OPT_BOOLEAN(0, "unset-upstream", &unset_upstream, "Unset the upstream info"),
+ OPT_BOOLEAN(0, "unset-publish", &unset_publish, "Unset the publish info"),
OPT__COLOR(&branch_use_color, N_("use colored output")),
OPT_SET_INT('r', "remotes", &kinds, N_("act on remote-tracking branches"),
REF_REMOTE_BRANCH),
@@ -863,13 +865,15 @@ int cmd_branch(int argc, const char **argv, const char *prefix)
argc = parse_options(argc, argv, prefix, options, builtin_branch_usage,
0);
- if (!delete && !rename && !edit_description && !new_upstream && !unset_upstream && argc == 0)
+ if (!delete && !rename && !edit_description && !new_upstream && !publish &&
+ !unset_upstream && !unset_publish && argc == 0)
list = 1;
if (with_commit || merge_filter != NO_FILTER)
list = 1;
- if (!!delete + !!rename + !!force_create + !!list + !!new_upstream + !!unset_upstream > 1)
+ if (!!delete + !!rename + !!force_create + !!list + !!new_upstream + !!publish +
+ !!unset_upstream + !! unset_publish > 1)
usage_with_options(builtin_branch_usage, options);
if (abbrev == -1)
@@ -975,6 +979,50 @@ int cmd_branch(int argc, const char **argv, const char *prefix)
strbuf_addf(&buf, "branch.%s.merge", branch->name);
git_config_set_multivar(buf.buf, NULL, NULL, 1);
strbuf_release(&buf);
+ } else if (publish) {
+ struct branch *branch = branch_get(argv[0]);
+ char *real_ref = NULL;
+ unsigned char sha1[20];
+
+ if (argc > 1)
+ die(_("too many branches to set new publish branch"));
+
+ if (!branch) {
+ if (!argc || !strcmp(argv[0], "HEAD"))
+ die(_("could not set publish branch of HEAD when "
+ "it does not point to any branch."));
+ die(_("no such branch '%s'"), argv[0]);
+ }
+
+ if (!ref_exists(branch->refname))
+ die(_("branch '%s' does not exist"), branch->name);
+
+ if (dwim_ref(publish, strlen(publish), sha1, &real_ref) != 1 ||
+ setup_publish(branch->name, real_ref))
+ die(_("Cannot setup publish branch to '%s'."), publish);
+ } else if (unset_publish) {
+ struct branch *branch = branch_get(argv[0]);
+ struct strbuf buf = STRBUF_INIT;
+
+ if (argc > 1)
+ die(_("too many branches to unset publish branch"));
+
+ if (!branch) {
+ if (!argc || !strcmp(argv[0], "HEAD"))
+ die(_("could not unset publish branch of HEAD when "
+ "it does not point to any branch."));
+ die(_("no such branch '%s'"), argv[0]);
+ }
+
+ if (!branch->push_name)
+ die(_("Branch '%s' has no publish information"), branch->name);
+
+ strbuf_addf(&buf, "branch.%s.pushremote", branch->name);
+ git_config_set_multivar(buf.buf, NULL, NULL, 1);
+ strbuf_reset(&buf);
+ strbuf_addf(&buf, "branch.%s.push", branch->name);
+ git_config_set_multivar(buf.buf, NULL, NULL, 1);
+ strbuf_release(&buf);
} else if (argc > 0 && argc <= 2) {
struct branch *branch = branch_get(argv[0]);
int branch_existed = 0, remote_tracking = 0;
--
1.8.4-fc
^ permalink raw reply related [flat|nested] 11+ messages in thread