Skip to content

Commit e61e0cc

Browse files
jaysoffiangitster
authored andcommitted
builtin-remote: teach show to display remote HEAD
This is in preparation for teaching remote how to set refs/remotes/<remote>/HEAD to match what HEAD is set to at <remote>, but is useful in its own right. Signed-off-by: Jay Soffian <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 3bd9256 commit e61e0cc

File tree

2 files changed

+59
-7
lines changed

2 files changed

+59
-7
lines changed

builtin-remote.c

Lines changed: 49 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@ static const char * const builtin_remote_usage[] = {
1818
NULL
1919
};
2020

21+
#define GET_REF_STATES (1<<0)
22+
#define GET_HEAD_NAMES (1<<1)
23+
2124
static int verbose;
2225

2326
static int show_all(void);
@@ -210,7 +213,7 @@ static void read_branches(void)
210213

211214
struct ref_states {
212215
struct remote *remote;
213-
struct string_list new, stale, tracked;
216+
struct string_list new, stale, tracked, heads;
214217
};
215218

216219
static int handle_one_branch(const char *refname,
@@ -264,6 +267,28 @@ static int get_ref_states(const struct ref *remote_refs, struct ref_states *stat
264267
return 0;
265268
}
266269

270+
static int get_head_names(const struct ref *remote_refs, struct ref_states *states)
271+
{
272+
struct ref *ref, *matches;
273+
struct ref *fetch_map = NULL, **fetch_map_tail = &fetch_map;
274+
struct refspec refspec;
275+
276+
refspec.force = 0;
277+
refspec.pattern = 1;
278+
refspec.src = refspec.dst = "refs/heads/";
279+
states->heads.strdup_strings = 1;
280+
get_fetch_map(remote_refs, &refspec, &fetch_map_tail, 0);
281+
matches = guess_remote_head(find_ref_by_name(remote_refs, "HEAD"),
282+
fetch_map, 1);
283+
for(ref = matches; ref; ref = ref->next)
284+
string_list_append(abbrev_branch(ref->name), &states->heads);
285+
286+
free_refs(fetch_map);
287+
free_refs(matches);
288+
289+
return 0;
290+
}
291+
267292
struct known_remote {
268293
struct known_remote *next;
269294
struct remote *remote;
@@ -630,6 +655,7 @@ static void free_remote_ref_states(struct ref_states *states)
630655
string_list_clear(&states->new, 0);
631656
string_list_clear(&states->stale, 0);
632657
string_list_clear(&states->tracked, 0);
658+
string_list_clear(&states->heads, 0);
633659
}
634660

635661
static int append_ref_to_tracked_list(const char *refname,
@@ -668,7 +694,10 @@ static int get_remote_ref_states(const char *name,
668694
remote_refs = transport_get_remote_refs(transport);
669695
transport_disconnect(transport);
670696

671-
get_ref_states(remote_refs, states);
697+
if (query & GET_REF_STATES)
698+
get_ref_states(remote_refs, states);
699+
if (query & GET_HEAD_NAMES)
700+
get_head_names(remote_refs, states);
672701
} else {
673702
for_each_ref(append_ref_to_tracked_list, states);
674703
sort_string_list(&states->tracked);
@@ -679,7 +708,7 @@ static int get_remote_ref_states(const char *name,
679708

680709
static int show(int argc, const char **argv)
681710
{
682-
int no_query = 0, result = 0;
711+
int no_query = 0, result = 0, query_flag = 0;
683712
struct option options[] = {
684713
OPT_GROUP("show specific options"),
685714
OPT_BOOLEAN('n', NULL, &no_query, "do not query remotes"),
@@ -692,15 +721,30 @@ static int show(int argc, const char **argv)
692721
if (argc < 1)
693722
return show_all();
694723

724+
if (!no_query)
725+
query_flag = (GET_REF_STATES | GET_HEAD_NAMES);
726+
695727
memset(&states, 0, sizeof(states));
696728
for (; argc; argc--, argv++) {
697729
int i;
698730

699-
get_remote_ref_states(*argv, &states, !no_query);
731+
get_remote_ref_states(*argv, &states, query_flag);
700732

701733
printf("* remote %s\n URL: %s\n", *argv,
702734
states.remote->url_nr > 0 ?
703735
states.remote->url[0] : "(no URL)");
736+
if (no_query)
737+
printf(" HEAD branch: (not queried)\n");
738+
else if (!states.heads.nr)
739+
printf(" HEAD branch: (unknown)\n");
740+
else if (states.heads.nr == 1)
741+
printf(" HEAD branch: %s\n", states.heads.items[0].string);
742+
else {
743+
printf(" HEAD branch (remote HEAD is ambiguous,"
744+
" may be one of the following):\n");
745+
for (i = 0; i < states.heads.nr; i++)
746+
printf(" %s\n", states.heads.items[i].string);
747+
}
704748

705749
for (i = 0; i < branch_list.nr; i++) {
706750
struct string_list_item *branch = branch_list.items + i;
@@ -772,7 +816,7 @@ static int prune(int argc, const char **argv)
772816
for (; argc; argc--, argv++) {
773817
int i;
774818

775-
get_remote_ref_states(*argv, &states, 1);
819+
get_remote_ref_states(*argv, &states, GET_REF_STATES);
776820

777821
if (states.stale.nr) {
778822
printf("Pruning %s\n", *argv);

t/t5505-remote.sh

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,7 @@ EOF
136136
cat > test/expect << EOF
137137
* remote origin
138138
URL: $(pwd)/one
139+
HEAD branch: master
139140
Remote branch merged with 'git pull' while on branch master
140141
master
141142
New remote branch (next fetch will store in remotes/origin)
@@ -146,6 +147,11 @@ cat > test/expect << EOF
146147
Local branches pushed with 'git push'
147148
master:upstream
148149
+refs/tags/lastbackup
150+
* remote two
151+
URL: ../two
152+
HEAD branch (remote HEAD is ambiguous, may be one of the following):
153+
another
154+
master
149155
EOF
150156

151157
test_expect_success 'show' '
@@ -154,6 +160,7 @@ test_expect_success 'show' '
154160
refs/heads/master:refs/heads/upstream &&
155161
git fetch &&
156162
git branch -d -r origin/master &&
163+
git config --add remote.two.url ../two &&
157164
(cd ../one &&
158165
echo 1 > file &&
159166
test_tick &&
@@ -162,13 +169,14 @@ test_expect_success 'show' '
162169
refs/heads/master:refs/heads/upstream &&
163170
git config --add remote.origin.push \
164171
+refs/tags/lastbackup &&
165-
git remote show origin > output &&
172+
git remote show origin two > output &&
166173
test_cmp expect output)
167174
'
168175

169176
cat > test/expect << EOF
170177
* remote origin
171178
URL: $(pwd)/one
179+
HEAD branch: (not queried)
172180
Remote branch merged with 'git pull' while on branch master
173181
master
174182
Tracked remote branches
@@ -343,7 +351,7 @@ test_expect_success '"remote show" does not show symbolic refs' '
343351
git clone one three &&
344352
(cd three &&
345353
git remote show origin > output &&
346-
! grep HEAD < output &&
354+
! grep "^ *HEAD$" < output &&
347355
! grep -i stale < output)
348356
349357
'

0 commit comments

Comments
 (0)