Skip to content

Commit

Permalink
for-each-ref: add "upstream" format field
Browse files Browse the repository at this point in the history
The logic for determining the upstream ref of a branch is
somewhat complex to perform in a shell script. This patch
provides a plumbing mechanism for scripts to access the C
logic used internally by git-status, git-branch, etc.

For example:

  $ git for-each-ref \
       --format='%(refname:short) %(upstream:short)' \
       refs/heads/
  master origin/master

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
  • Loading branch information
Jeff King authored and Junio C Hamano committed Apr 8, 2009
1 parent 8db9a4b commit 8cae19d
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 0 deletions.
5 changes: 5 additions & 0 deletions Documentation/git-for-each-ref.txt
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,11 @@ objectsize::
objectname::
The object name (aka SHA-1).

upstream::
The name of a local ref which can be considered ``upstream''
from the displayed ref. Respects `:short` in the same way as
`refname` above.

In addition to the above, for commit and tag objects, the header
field names (`tree`, `parent`, `object`, `type`, and `tag`) can
be used to specify the value in the header field.
Expand Down
14 changes: 14 additions & 0 deletions builtin-for-each-ref.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include "blob.h"
#include "quote.h"
#include "parse-options.h"
#include "remote.h"

/* Quoting styles */
#define QUOTE_NONE 0
Expand Down Expand Up @@ -66,6 +67,7 @@ static struct {
{ "subject" },
{ "body" },
{ "contents" },
{ "upstream" },
};

/*
Expand Down Expand Up @@ -682,6 +684,18 @@ static void populate_value(struct refinfo *ref)

if (!prefixcmp(name, "refname"))
refname = ref->refname;
else if(!prefixcmp(name, "upstream")) {
struct branch *branch;
/* only local branches may have an upstream */
if (prefixcmp(ref->refname, "refs/heads/"))
continue;
branch = branch_get(ref->refname + 11);

if (!branch || !branch->merge || !branch->merge[0] ||
!branch->merge[0]->dst)
continue;
refname = branch->merge[0]->dst;
}
else
continue;

Expand Down
22 changes: 22 additions & 0 deletions t/t6300-for-each-ref.sh
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,13 @@ test_expect_success 'Create sample commit with known timestamp' '
git tag -a -m "Tagging at $datestamp" testtag
'

test_expect_success 'Create upstream config' '
git update-ref refs/remotes/origin/master master &&
git remote add origin nowhere &&
git config branch.master.remote origin &&
git config branch.master.merge refs/heads/master
'

test_atom() {
case "$1" in
head) ref=refs/heads/master ;;
Expand All @@ -39,6 +46,7 @@ test_atom() {
}

test_atom head refname refs/heads/master
test_atom head upstream refs/remotes/origin/master
test_atom head objecttype commit
test_atom head objectsize 171
test_atom head objectname 67a36f10722846e891fbada1ba48ed035de75581
Expand Down Expand Up @@ -68,6 +76,7 @@ test_atom head contents 'Initial
'

test_atom tag refname refs/tags/testtag
test_atom tag upstream ''
test_atom tag objecttype tag
test_atom tag objectsize 154
test_atom tag objectname 98b46b1d36e5b07909de1b3886224e3e81e87322
Expand Down Expand Up @@ -203,6 +212,7 @@ test_expect_success 'Check format "rfc2822" date fields output' '

cat >expected <<\EOF
refs/heads/master
refs/remotes/origin/master
refs/tags/testtag
EOF

Expand All @@ -214,6 +224,7 @@ test_expect_success 'Verify ascending sort' '

cat >expected <<\EOF
refs/tags/testtag
refs/remotes/origin/master
refs/heads/master
EOF

Expand All @@ -224,6 +235,7 @@ test_expect_success 'Verify descending sort' '

cat >expected <<\EOF
'refs/heads/master'
'refs/remotes/origin/master'
'refs/tags/testtag'
EOF

Expand All @@ -244,6 +256,7 @@ test_expect_success 'Quoting style: python' '

cat >expected <<\EOF
"refs/heads/master"
"refs/remotes/origin/master"
"refs/tags/testtag"
EOF

Expand Down Expand Up @@ -273,6 +286,15 @@ test_expect_success 'Check short refname format' '
test_cmp expected actual
'

cat >expected <<EOF
origin/master
EOF

test_expect_success 'Check short upstream format' '
git for-each-ref --format="%(upstream:short)" refs/heads >actual &&
test_cmp expected actual
'

test_expect_success 'Check for invalid refname format' '
test_must_fail git for-each-ref --format="%(refname:INVALID)"
'
Expand Down

0 comments on commit 8cae19d

Please sign in to comment.