Skip to content

Commit

Permalink
Merge branch 'jk/at-push-sha1'
Browse files Browse the repository at this point in the history
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
  • Loading branch information
Junio C Hamano committed Jun 5, 2015
2 parents f86f31a + 29bc885 commit c4a8354
Show file tree
Hide file tree
Showing 14 changed files with 424 additions and 149 deletions.
6 changes: 6 additions & 0 deletions Documentation/git-for-each-ref.txt
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,12 @@ upstream::
or "=" (in sync). Has no effect if the ref does not have
tracking information associated with it.

push::
The name of a local ref which represents the `@{push}` location
for the displayed ref. Respects `:short`, `:track`, and
`:trackshort` options as `upstream` does. Produces an empty
string if no `@{push}` ref is configured.

HEAD::
'*' if HEAD matches current ref (the checked out branch), ' '
otherwise.
Expand Down
25 changes: 25 additions & 0 deletions Documentation/revisions.txt
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,31 @@ some output processing may assume ref names in UTF-8.
`branch.<name>.merge`). A missing branchname defaults to the
current one.

'<branchname>@\{push\}', e.g. 'master@\{push\}', '@\{push\}'::
The suffix '@\{push}' reports the branch "where we would push to" if
`git push` were run while `branchname` was checked out (or the current
'HEAD' if no branchname is specified). Since our push destination is
in a remote repository, of course, we report the local tracking branch
that corresponds to that branch (i.e., something in 'refs/remotes/').
+
Here's an example to make it more clear:
+
------------------------------
$ git config push.default current
$ git config remote.pushdefault myfork
$ git checkout -b mybranch origin/master

$ git rev-parse --symbolic-full-name @{upstream}
refs/remotes/origin/master

$ git rev-parse --symbolic-full-name @{push}
refs/remotes/myfork/mybranch
------------------------------
+
Note in the example that we set up a triangular workflow, where we pull
from one location and push to another. In a non-triangular workflow,
'@\{push}' is the same as '@\{upstream}', and there is no need for it.

'<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.
Expand Down
4 changes: 0 additions & 4 deletions Documentation/technical/api-remote.txt
Original file line number Diff line number Diff line change
Expand Up @@ -97,10 +97,6 @@ It contains:

The name of the remote listed in the configuration.

`remote`::

The struct remote for that remote.

`merge_name`::

An array of the "merge" lines in the configuration.
Expand Down
24 changes: 8 additions & 16 deletions builtin/branch.c
Original file line number Diff line number Diff line change
Expand Up @@ -123,14 +123,12 @@ static int branch_merged(int kind, const char *name,

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

if (branch &&
branch->merge &&
branch->merge[0] &&
branch->merge[0]->dst &&
if (upstream &&
(reference_name = reference_name_to_free =
resolve_refdup(branch->merge[0]->dst, RESOLVE_REF_READING,
resolve_refdup(upstream, RESOLVE_REF_READING,
sha1, NULL)) != NULL)
reference_rev = lookup_commit_reference(sha1);
}
Expand Down Expand Up @@ -427,25 +425,19 @@ static void fill_tracking_info(struct strbuf *stat, const char *branch_name,
int ours, theirs;
char *ref = NULL;
struct branch *branch = branch_get(branch_name);
const char *upstream;
struct strbuf fancy = STRBUF_INIT;
int upstream_is_gone = 0;
int added_decoration = 1;

switch (stat_tracking_info(branch, &ours, &theirs)) {
case 0:
/* no base */
return;
case -1:
/* with "gone" base */
if (stat_tracking_info(branch, &ours, &theirs, &upstream) < 0) {
if (!upstream)
return;
upstream_is_gone = 1;
break;
default:
/* with base */
break;
}

if (show_upstream_ref) {
ref = shorten_unambiguous_ref(branch->merge[0]->dst, 0);
ref = shorten_unambiguous_ref(upstream, 0);
if (want_color(branch_use_color))
strbuf_addf(&fancy, "%s%s%s",
branch_get_color(BRANCH_COLOR_UPSTREAM),
Expand Down
32 changes: 23 additions & 9 deletions builtin/for-each-ref.c
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ static struct {
{ "contents:body" },
{ "contents:signature" },
{ "upstream" },
{ "push" },
{ "symref" },
{ "flag" },
{ "HEAD" },
Expand Down Expand Up @@ -659,15 +660,26 @@ static void populate_value(struct refinfo *ref)
else if (starts_with(name, "symref"))
refname = ref->symref ? ref->symref : "";
else if (starts_with(name, "upstream")) {
const char *branch_name;
/* only local branches may have an upstream */
if (!starts_with(ref->refname, "refs/heads/"))
if (!skip_prefix(ref->refname, "refs/heads/",
&branch_name))
continue;
branch = branch_get(ref->refname + 11);
branch = branch_get(branch_name);

if (!branch || !branch->merge || !branch->merge[0] ||
!branch->merge[0]->dst)
refname = branch_get_upstream(branch, NULL);
if (!refname)
continue;
} else if (starts_with(name, "push")) {
const char *branch_name;
if (!skip_prefix(ref->refname, "refs/heads/",
&branch_name))
continue;
branch = branch_get(branch_name);

refname = branch_get_push(branch, NULL);
if (!refname)
continue;
refname = branch->merge[0]->dst;
} else if (starts_with(name, "color:")) {
char color[COLOR_MAXLEN] = "";

Expand Down Expand Up @@ -713,11 +725,12 @@ static void populate_value(struct refinfo *ref)
refname = shorten_unambiguous_ref(refname,
warn_ambiguous_refs);
else if (!strcmp(formatp, "track") &&
starts_with(name, "upstream")) {
(starts_with(name, "upstream") ||
starts_with(name, "push"))) {
char buf[40];

if (stat_tracking_info(branch, &num_ours,
&num_theirs) != 1)
&num_theirs, NULL))
continue;

if (!num_ours && !num_theirs)
Expand All @@ -735,11 +748,12 @@ static void populate_value(struct refinfo *ref)
}
continue;
} else if (!strcmp(formatp, "trackshort") &&
starts_with(name, "upstream")) {
(starts_with(name, "upstream") ||
starts_with(name, "push"))) {
assert(branch);

if (stat_tracking_info(branch, &num_ours,
&num_theirs) != 1)
&num_theirs, NULL))
continue;

if (!num_ours && !num_theirs)
Expand Down
7 changes: 2 additions & 5 deletions builtin/log.c
Original file line number Diff line number Diff line change
Expand Up @@ -1632,16 +1632,13 @@ int cmd_cherry(int argc, const char **argv, const char *prefix)
break;
default:
current_branch = branch_get(NULL);
if (!current_branch || !current_branch->merge
|| !current_branch->merge[0]
|| !current_branch->merge[0]->dst) {
upstream = branch_get_upstream(current_branch, NULL);
if (!upstream) {
fprintf(stderr, _("Could not find a tracked"
" remote branch, please"
" specify <upstream> manually.\n"));
usage_with_options(cherry_usage, options);
}

upstream = current_branch->merge[0]->dst;
}

init_revisions(&revs, prefix);
Expand Down
2 changes: 1 addition & 1 deletion builtin/merge.c
Original file line number Diff line number Diff line change
Expand Up @@ -933,7 +933,7 @@ static int setup_with_upstream(const char ***argv)

if (!branch)
die(_("No current branch."));
if (!branch->remote)
if (!branch->remote_name)
die(_("No remote for the current branch."));
if (!branch->merge_nr)
die(_("No default upstream defined for the current branch."));
Expand Down
Loading

0 comments on commit c4a8354

Please sign in to comment.