@matheusbsbs / matheus-bagliano / commits / e61e0cc6b7
Fork 0

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 <jaysoffian@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Jay Soffian committed Feb 25, 2009 at 03:32 UTC e61e0cc6b7061d7e791e1c9722b9c4a6d85d629c
2 files changed +59 -7
builtin-remote.c
+49 -5
@@ -18,6 +18,9 @@ static const char * const builtin_remote_usage[] = {
18 NULL
19 };
20
21 +#define GET_REF_STATES (1<<0)
22 +#define GET_HEAD_NAMES (1<<1)
23 +
24 static int verbose;
25
26 static int show_all(void);
@@ -210,7 +213,7 @@ static void read_branches(void)
213
214 struct ref_states {
215 struct remote *remote;
213 - struct string_list new, stale, tracked;
216 + struct string_list new, stale, tracked, heads;
217 };
218
219 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
267 return 0;
268 }
269
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 +
292 struct known_remote {
293 struct known_remote *next;
294 struct remote *remote;
@@ -630,6 +655,7 @@ static void free_remote_ref_states(struct ref_states *states)
655 string_list_clear(&states->new, 0);
656 string_list_clear(&states->stale, 0);
657 string_list_clear(&states->tracked, 0);
658 + string_list_clear(&states->heads, 0);
659 }
660
661 static int append_ref_to_tracked_list(const char *refname,
@@ -668,7 +694,10 @@ static int get_remote_ref_states(const char *name,
694 remote_refs = transport_get_remote_refs(transport);
695 transport_disconnect(transport);
696
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);
701 } else {
702 for_each_ref(append_ref_to_tracked_list, states);
703 sort_string_list(&states->tracked);
@@ -679,7 +708,7 @@ static int get_remote_ref_states(const char *name,
708
709 static int show(int argc, const char **argv)
710 {
682 - int no_query = 0, result = 0;
711 + int no_query = 0, result = 0, query_flag = 0;
712 struct option options[] = {
713 OPT_GROUP("show specific options"),
714 OPT_BOOLEAN('n', NULL, &no_query, "do not query remotes"),
@@ -692,15 +721,30 @@ static int show(int argc, const char **argv)
721 if (argc < 1)
722 return show_all();
723
724 + if (!no_query)
725 + query_flag = (GET_REF_STATES | GET_HEAD_NAMES);
726 +
727 memset(&states, 0, sizeof(states));
728 for (; argc; argc--, argv++) {
729 int i;
730
699 - get_remote_ref_states(*argv, &states, !no_query);
731 + get_remote_ref_states(*argv, &states, query_flag);
732
733 printf("* remote %s\n URL: %s\n", *argv,
734 states.remote->url_nr > 0 ?
735 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 + }
748
749 for (i = 0; i < branch_list.nr; i++) {
750 struct string_list_item *branch = branch_list.items + i;
@@ -772,7 +816,7 @@ static int prune(int argc, const char **argv)
816 for (; argc; argc--, argv++) {
817 int i;
818
775 - get_remote_ref_states(*argv, &states, 1);
819 + get_remote_ref_states(*argv, &states, GET_REF_STATES);
820
821 if (states.stale.nr) {
822 printf("Pruning %s\n", *argv);
t/t5505-remote.sh
+10 -2
@@ -136,6 +136,7 @@ EOF
136 cat > test/expect << EOF
137 * remote origin
138 URL: $(pwd)/one
139 + HEAD branch: master
140 Remote branch merged with 'git pull' while on branch master
141 master
142 New remote branch (next fetch will store in remotes/origin)
@@ -146,6 +147,11 @@ cat > test/expect << EOF
147 Local branches pushed with 'git push'
148 master:upstream
149 +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
155 EOF
156
157 test_expect_success 'show' '
@@ -154,6 +160,7 @@ test_expect_success 'show' '
160 refs/heads/master:refs/heads/upstream &&
161 git fetch &&
162 git branch -d -r origin/master &&
163 + git config --add remote.two.url ../two &&
164 (cd ../one &&
165 echo 1 > file &&
166 test_tick &&
@@ -162,13 +169,14 @@ test_expect_success 'show' '
169 refs/heads/master:refs/heads/upstream &&
170 git config --add remote.origin.push \
171 +refs/tags/lastbackup &&
165 - git remote show origin > output &&
172 + git remote show origin two > output &&
173 test_cmp expect output)
174 '
175
176 cat > test/expect << EOF
177 * remote origin
178 URL: $(pwd)/one
179 + HEAD branch: (not queried)
180 Remote branch merged with 'git pull' while on branch master
181 master
182 Tracked remote branches
@@ -343,7 +351,7 @@ test_expect_success '"remote show" does not show symbolic refs' '
351 git clone one three &&
352 (cd three &&
353 git remote show origin > output &&
346 - ! grep HEAD < output &&
354 + ! grep "^ *HEAD$" < output &&
355 ! grep -i stale < output)
356
357 '