Skip to content

Commit 8cae19d

Browse files
peffgitster
authored andcommitted
for-each-ref: add "upstream" format field
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 <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 8db9a4b commit 8cae19d

File tree

3 files changed

+41
-0
lines changed

3 files changed

+41
-0
lines changed

Documentation/git-for-each-ref.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,11 @@ objectsize::
8585
objectname::
8686
The object name (aka SHA-1).
8787

88+
upstream::
89+
The name of a local ref which can be considered ``upstream''
90+
from the displayed ref. Respects `:short` in the same way as
91+
`refname` above.
92+
8893
In addition to the above, for commit and tag objects, the header
8994
field names (`tree`, `parent`, `object`, `type`, and `tag`) can
9095
be used to specify the value in the header field.

builtin-for-each-ref.c

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
#include "blob.h"
99
#include "quote.h"
1010
#include "parse-options.h"
11+
#include "remote.h"
1112

1213
/* Quoting styles */
1314
#define QUOTE_NONE 0
@@ -66,6 +67,7 @@ static struct {
6667
{ "subject" },
6768
{ "body" },
6869
{ "contents" },
70+
{ "upstream" },
6971
};
7072

7173
/*
@@ -682,6 +684,18 @@ static void populate_value(struct refinfo *ref)
682684

683685
if (!prefixcmp(name, "refname"))
684686
refname = ref->refname;
687+
else if(!prefixcmp(name, "upstream")) {
688+
struct branch *branch;
689+
/* only local branches may have an upstream */
690+
if (prefixcmp(ref->refname, "refs/heads/"))
691+
continue;
692+
branch = branch_get(ref->refname + 11);
693+
694+
if (!branch || !branch->merge || !branch->merge[0] ||
695+
!branch->merge[0]->dst)
696+
continue;
697+
refname = branch->merge[0]->dst;
698+
}
685699
else
686700
continue;
687701

t/t6300-for-each-ref.sh

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,13 @@ test_expect_success 'Create sample commit with known timestamp' '
2626
git tag -a -m "Tagging at $datestamp" testtag
2727
'
2828

29+
test_expect_success 'Create upstream config' '
30+
git update-ref refs/remotes/origin/master master &&
31+
git remote add origin nowhere &&
32+
git config branch.master.remote origin &&
33+
git config branch.master.merge refs/heads/master
34+
'
35+
2936
test_atom() {
3037
case "$1" in
3138
head) ref=refs/heads/master ;;
@@ -39,6 +46,7 @@ test_atom() {
3946
}
4047

4148
test_atom head refname refs/heads/master
49+
test_atom head upstream refs/remotes/origin/master
4250
test_atom head objecttype commit
4351
test_atom head objectsize 171
4452
test_atom head objectname 67a36f10722846e891fbada1ba48ed035de75581
@@ -68,6 +76,7 @@ test_atom head contents 'Initial
6876
'
6977

7078
test_atom tag refname refs/tags/testtag
79+
test_atom tag upstream ''
7180
test_atom tag objecttype tag
7281
test_atom tag objectsize 154
7382
test_atom tag objectname 98b46b1d36e5b07909de1b3886224e3e81e87322
@@ -203,6 +212,7 @@ test_expect_success 'Check format "rfc2822" date fields output' '
203212

204213
cat >expected <<\EOF
205214
refs/heads/master
215+
refs/remotes/origin/master
206216
refs/tags/testtag
207217
EOF
208218

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

215225
cat >expected <<\EOF
216226
refs/tags/testtag
227+
refs/remotes/origin/master
217228
refs/heads/master
218229
EOF
219230

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

225236
cat >expected <<\EOF
226237
'refs/heads/master'
238+
'refs/remotes/origin/master'
227239
'refs/tags/testtag'
228240
EOF
229241

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

245257
cat >expected <<\EOF
246258
"refs/heads/master"
259+
"refs/remotes/origin/master"
247260
"refs/tags/testtag"
248261
EOF
249262

@@ -273,6 +286,15 @@ test_expect_success 'Check short refname format' '
273286
test_cmp expected actual
274287
'
275288

289+
cat >expected <<EOF
290+
origin/master
291+
EOF
292+
293+
test_expect_success 'Check short upstream format' '
294+
git for-each-ref --format="%(upstream:short)" refs/heads >actual &&
295+
test_cmp expected actual
296+
'
297+
276298
test_expect_success 'Check for invalid refname format' '
277299
test_must_fail git for-each-ref --format="%(refname:INVALID)"
278300
'

0 commit comments

Comments
 (0)