Skip to content

Commit c4a8354

Browse files
committed
Merge branch 'jk/at-push-sha1'
Introduce <branch>@{push} short-hand to denote the remote-tracking branch that tracks the branch at the remote the <branch> would be pushed to. * jk/at-push-sha1: for-each-ref: accept "%(push)" format for-each-ref: use skip_prefix instead of starts_with sha1_name: implement @{push} shorthand sha1_name: refactor interpret_upstream_mark sha1_name: refactor upstream_mark remote.c: add branch_get_push remote.c: return upstream name from stat_tracking_info remote.c: untangle error logic in branch_get_upstream remote.c: report specific errors from branch_get_upstream remote.c: introduce branch_get_upstream helper remote.c: hoist read_config into remote_get_1 remote.c: provide per-branch pushremote name remote.c: hoist branch.*.remote lookup out of remote_get_1 remote.c: drop "remote" pointer from "struct branch" remote.c: refactor setup of branch->merge list remote.c: drop default_remote_name variable
2 parents f86f31a + 29bc885 commit c4a8354

14 files changed

+424
-149
lines changed

Documentation/git-for-each-ref.txt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,12 @@ upstream::
9797
or "=" (in sync). Has no effect if the ref does not have
9898
tracking information associated with it.
9999

100+
push::
101+
The name of a local ref which represents the `@{push}` location
102+
for the displayed ref. Respects `:short`, `:track`, and
103+
`:trackshort` options as `upstream` does. Produces an empty
104+
string if no `@{push}` ref is configured.
105+
100106
HEAD::
101107
'*' if HEAD matches current ref (the checked out branch), ' '
102108
otherwise.

Documentation/revisions.txt

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,31 @@ some output processing may assume ref names in UTF-8.
9898
`branch.<name>.merge`). A missing branchname defaults to the
9999
current one.
100100

101+
'<branchname>@\{push\}', e.g. 'master@\{push\}', '@\{push\}'::
102+
The suffix '@\{push}' reports the branch "where we would push to" if
103+
`git push` were run while `branchname` was checked out (or the current
104+
'HEAD' if no branchname is specified). Since our push destination is
105+
in a remote repository, of course, we report the local tracking branch
106+
that corresponds to that branch (i.e., something in 'refs/remotes/').
107+
+
108+
Here's an example to make it more clear:
109+
+
110+
------------------------------
111+
$ git config push.default current
112+
$ git config remote.pushdefault myfork
113+
$ git checkout -b mybranch origin/master
114+
115+
$ git rev-parse --symbolic-full-name @{upstream}
116+
refs/remotes/origin/master
117+
118+
$ git rev-parse --symbolic-full-name @{push}
119+
refs/remotes/myfork/mybranch
120+
------------------------------
121+
+
122+
Note in the example that we set up a triangular workflow, where we pull
123+
from one location and push to another. In a non-triangular workflow,
124+
'@\{push}' is the same as '@\{upstream}', and there is no need for it.
125+
101126
'<rev>{caret}', e.g. 'HEAD{caret}, v1.5.1{caret}0'::
102127
A suffix '{caret}' to a revision parameter means the first parent of
103128
that commit object. '{caret}<n>' means the <n>th parent (i.e.

Documentation/technical/api-remote.txt

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -97,10 +97,6 @@ It contains:
9797

9898
The name of the remote listed in the configuration.
9999

100-
`remote`::
101-
102-
The struct remote for that remote.
103-
104100
`merge_name`::
105101

106102
An array of the "merge" lines in the configuration.

builtin/branch.c

Lines changed: 8 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -123,14 +123,12 @@ static int branch_merged(int kind, const char *name,
123123

124124
if (kind == REF_LOCAL_BRANCH) {
125125
struct branch *branch = branch_get(name);
126+
const char *upstream = branch_get_upstream(branch, NULL);
126127
unsigned char sha1[20];
127128

128-
if (branch &&
129-
branch->merge &&
130-
branch->merge[0] &&
131-
branch->merge[0]->dst &&
129+
if (upstream &&
132130
(reference_name = reference_name_to_free =
133-
resolve_refdup(branch->merge[0]->dst, RESOLVE_REF_READING,
131+
resolve_refdup(upstream, RESOLVE_REF_READING,
134132
sha1, NULL)) != NULL)
135133
reference_rev = lookup_commit_reference(sha1);
136134
}
@@ -427,25 +425,19 @@ static void fill_tracking_info(struct strbuf *stat, const char *branch_name,
427425
int ours, theirs;
428426
char *ref = NULL;
429427
struct branch *branch = branch_get(branch_name);
428+
const char *upstream;
430429
struct strbuf fancy = STRBUF_INIT;
431430
int upstream_is_gone = 0;
432431
int added_decoration = 1;
433432

434-
switch (stat_tracking_info(branch, &ours, &theirs)) {
435-
case 0:
436-
/* no base */
437-
return;
438-
case -1:
439-
/* with "gone" base */
433+
if (stat_tracking_info(branch, &ours, &theirs, &upstream) < 0) {
434+
if (!upstream)
435+
return;
440436
upstream_is_gone = 1;
441-
break;
442-
default:
443-
/* with base */
444-
break;
445437
}
446438

447439
if (show_upstream_ref) {
448-
ref = shorten_unambiguous_ref(branch->merge[0]->dst, 0);
440+
ref = shorten_unambiguous_ref(upstream, 0);
449441
if (want_color(branch_use_color))
450442
strbuf_addf(&fancy, "%s%s%s",
451443
branch_get_color(BRANCH_COLOR_UPSTREAM),

builtin/for-each-ref.c

Lines changed: 23 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ static struct {
7474
{ "contents:body" },
7575
{ "contents:signature" },
7676
{ "upstream" },
77+
{ "push" },
7778
{ "symref" },
7879
{ "flag" },
7980
{ "HEAD" },
@@ -659,15 +660,26 @@ static void populate_value(struct refinfo *ref)
659660
else if (starts_with(name, "symref"))
660661
refname = ref->symref ? ref->symref : "";
661662
else if (starts_with(name, "upstream")) {
663+
const char *branch_name;
662664
/* only local branches may have an upstream */
663-
if (!starts_with(ref->refname, "refs/heads/"))
665+
if (!skip_prefix(ref->refname, "refs/heads/",
666+
&branch_name))
664667
continue;
665-
branch = branch_get(ref->refname + 11);
668+
branch = branch_get(branch_name);
666669

667-
if (!branch || !branch->merge || !branch->merge[0] ||
668-
!branch->merge[0]->dst)
670+
refname = branch_get_upstream(branch, NULL);
671+
if (!refname)
672+
continue;
673+
} else if (starts_with(name, "push")) {
674+
const char *branch_name;
675+
if (!skip_prefix(ref->refname, "refs/heads/",
676+
&branch_name))
677+
continue;
678+
branch = branch_get(branch_name);
679+
680+
refname = branch_get_push(branch, NULL);
681+
if (!refname)
669682
continue;
670-
refname = branch->merge[0]->dst;
671683
} else if (starts_with(name, "color:")) {
672684
char color[COLOR_MAXLEN] = "";
673685

@@ -713,11 +725,12 @@ static void populate_value(struct refinfo *ref)
713725
refname = shorten_unambiguous_ref(refname,
714726
warn_ambiguous_refs);
715727
else if (!strcmp(formatp, "track") &&
716-
starts_with(name, "upstream")) {
728+
(starts_with(name, "upstream") ||
729+
starts_with(name, "push"))) {
717730
char buf[40];
718731

719732
if (stat_tracking_info(branch, &num_ours,
720-
&num_theirs) != 1)
733+
&num_theirs, NULL))
721734
continue;
722735

723736
if (!num_ours && !num_theirs)
@@ -735,11 +748,12 @@ static void populate_value(struct refinfo *ref)
735748
}
736749
continue;
737750
} else if (!strcmp(formatp, "trackshort") &&
738-
starts_with(name, "upstream")) {
751+
(starts_with(name, "upstream") ||
752+
starts_with(name, "push"))) {
739753
assert(branch);
740754

741755
if (stat_tracking_info(branch, &num_ours,
742-
&num_theirs) != 1)
756+
&num_theirs, NULL))
743757
continue;
744758

745759
if (!num_ours && !num_theirs)

builtin/log.c

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1632,16 +1632,13 @@ int cmd_cherry(int argc, const char **argv, const char *prefix)
16321632
break;
16331633
default:
16341634
current_branch = branch_get(NULL);
1635-
if (!current_branch || !current_branch->merge
1636-
|| !current_branch->merge[0]
1637-
|| !current_branch->merge[0]->dst) {
1635+
upstream = branch_get_upstream(current_branch, NULL);
1636+
if (!upstream) {
16381637
fprintf(stderr, _("Could not find a tracked"
16391638
" remote branch, please"
16401639
" specify <upstream> manually.\n"));
16411640
usage_with_options(cherry_usage, options);
16421641
}
1643-
1644-
upstream = current_branch->merge[0]->dst;
16451642
}
16461643

16471644
init_revisions(&revs, prefix);

builtin/merge.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -933,7 +933,7 @@ static int setup_with_upstream(const char ***argv)
933933

934934
if (!branch)
935935
die(_("No current branch."));
936-
if (!branch->remote)
936+
if (!branch->remote_name)
937937
die(_("No remote for the current branch."));
938938
if (!branch->merge_nr)
939939
die(_("No default upstream defined for the current branch."));

0 commit comments

Comments
 (0)