@matheusbsbs / matheus-bagliano / commits / 7ecbbf877c
Fork 0

builtin-remote: new show output style

The existing output of "git remote show <remote>" is too verbose for the information it provides. This patch teaches it to provide more information in less space. The output for push refspecs is addressed in the next patch. Before the patch: $ git remote show origin * remote origin URL: git://git.kernel.org/pub/scm/git/git.git HEAD branch: master Remote branch merged with 'git pull' while on branch master master Remote branch merged with 'git pull' while on branch next next Remote branches merged with 'git pull' while on branch octopus foo bar baz frotz New remote branch (next fetch will store in remotes/origin) html Stale tracking branch (use 'git remote prune') bogus Tracked remote branches maint man master next pu todo After this patch: $ git remote show origin * remote origin URL: git://git.kernel.org/pub/scm/git/git.git HEAD branch: master Remote branches: bogus stale (use 'git remote prune' to remove) html new (next fetch will store in remotes/origin) maint tracked man tracked master tracked next tracked pu tracked todo tracked Local branches configured for 'git pull': master rebases onto remote master next rebases onto remote next octopus merges with remote foo and with remote bar and with remote baz and with remote frotz $ git remote show origin -n * remote origin URL: git://git.kernel.org/pub/scm/git/git.git HEAD branch: (not queried) Remote branches: (status not queried) bogus maint man master next pu todo Local branches configured for 'git pull': master rebases onto remote master next rebases onto remote next octopus merges with remote foo and with remote bar and with remote baz and with remote frotz 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 7ecbbf877c9a0716ccccd25609b01023eecd27c0
2 files changed +159 -61
builtin-remote.c
+138 -44
@@ -149,6 +149,7 @@ static int add(int argc, const char **argv)
149 struct branch_info {
150 char *remote_name;
151 struct string_list merge;
152 + int rebase;
153 };
154
155 static struct string_list branch_list;
@@ -165,10 +166,11 @@ static const char *abbrev_ref(const char *name, const char *prefix)
166 static int config_read_branches(const char *key, const char *value, void *cb)
167 {
168 if (!prefixcmp(key, "branch.")) {
169 + const char *orig_key = key;
170 char *name;
171 struct string_list_item *item;
172 struct branch_info *info;
171 - enum { REMOTE, MERGE } type;
173 + enum { REMOTE, MERGE, REBASE } type;
174
175 key += 7;
176 if (!postfixcmp(key, ".remote")) {
@@ -177,6 +179,9 @@ static int config_read_branches(const char *key, const char *value, void *cb)
179 } else if (!postfixcmp(key, ".merge")) {
180 name = xstrndup(key, strlen(key) - 6);
181 type = MERGE;
182 + } else if (!postfixcmp(key, ".rebase")) {
183 + name = xstrndup(key, strlen(key) - 7);
184 + type = REBASE;
185 } else
186 return 0;
187
@@ -187,9 +192,9 @@ static int config_read_branches(const char *key, const char *value, void *cb)
192 info = item->util;
193 if (type == REMOTE) {
194 if (info->remote_name)
190 - warning("more than one branch.%s", key);
195 + warning("more than one %s", orig_key);
196 info->remote_name = xstrdup(value);
192 - } else {
197 + } else if (type == MERGE) {
198 char *space = strchr(value, ' ');
199 value = abbrev_branch(value);
200 while (space) {
@@ -200,7 +205,8 @@ static int config_read_branches(const char *key, const char *value, void *cb)
205 space = strchr(value, ' ');
206 }
207 string_list_append(xstrdup(value), &info->merge);
203 - }
208 + } else
209 + info->rebase = git_config_bool(orig_key, value);
210 }
211 return 0;
212 }
@@ -215,6 +221,7 @@ static void read_branches(void)
221 struct ref_states {
222 struct remote *remote;
223 struct string_list new, stale, tracked, heads;
224 + int queried;
225 };
226
227 static int handle_one_branch(const char *refname,
@@ -637,20 +644,6 @@ static int rm(int argc, const char **argv)
644 return result;
645 }
646
640 -static void show_list(const char *title, struct string_list *list,
641 - const char *extra_arg)
642 -{
643 - int i;
644 -
645 - if (!list->nr)
646 - return;
647 -
648 - printf(title, list->nr > 1 ? "es" : "", extra_arg);
649 - printf("\n");
650 - for (i = 0; i < list->nr; i++)
651 - printf(" %s\n", list->items[i].string);
652 -}
653 -
647 static void free_remote_ref_states(struct ref_states *states)
648 {
649 string_list_clear(&states->new, 0);
@@ -695,6 +688,7 @@ static int get_remote_ref_states(const char *name,
688 remote_refs = transport_get_remote_refs(transport);
689 transport_disconnect(transport);
690
691 + states->queried = 1;
692 if (query & GET_REF_STATES)
693 get_ref_states(remote_refs, states);
694 if (query & GET_HEAD_NAMES)
@@ -707,6 +701,104 @@ static int get_remote_ref_states(const char *name,
701 return 0;
702 }
703
704 +struct show_info {
705 + struct string_list *list;
706 + struct ref_states *states;
707 + int width;
708 + int any_rebase;
709 +};
710 +
711 +int add_remote_to_show_info(struct string_list_item *item, void *cb_data)
712 +{
713 + struct show_info *info = cb_data;
714 + int n = strlen(item->string);
715 + if (n > info->width)
716 + info->width = n;
717 + string_list_insert(item->string, info->list);
718 + return 0;
719 +}
720 +
721 +int show_remote_info_item(struct string_list_item *item, void *cb_data)
722 +{
723 + struct show_info *info = cb_data;
724 + struct ref_states *states = info->states;
725 + const char *name = item->string;
726 +
727 + if (states->queried) {
728 + const char *fmt = "%s";
729 + const char *arg = "";
730 + if (string_list_has_string(&states->new, name)) {
731 + fmt = " new (next fetch will store in remotes/%s)";
732 + arg = states->remote->name;
733 + } else if (string_list_has_string(&states->tracked, name))
734 + arg = " tracked";
735 + else if (string_list_has_string(&states->stale, name))
736 + arg = " stale (use 'git remote prune' to remove)";
737 + else
738 + arg = " ???";
739 + printf(" %-*s", info->width, name);
740 + printf(fmt, arg);
741 + printf("\n");
742 + } else
743 + printf(" %s\n", name);
744 +
745 + return 0;
746 +}
747 +
748 +int add_local_to_show_info(struct string_list_item *branch_item, void *cb_data)
749 +{
750 + struct show_info *show_info = cb_data;
751 + struct ref_states *states = show_info->states;
752 + struct branch_info *branch_info = branch_item->util;
753 + struct string_list_item *item;
754 + int n;
755 +
756 + if (!branch_info->merge.nr || !branch_info->remote_name ||
757 + strcmp(states->remote->name, branch_info->remote_name))
758 + return 0;
759 + if ((n = strlen(branch_item->string)) > show_info->width)
760 + show_info->width = n;
761 + if (branch_info->rebase)
762 + show_info->any_rebase = 1;
763 +
764 + item = string_list_insert(branch_item->string, show_info->list);
765 + item->util = branch_info;
766 +
767 + return 0;
768 +}
769 +
770 +int show_local_info_item(struct string_list_item *item, void *cb_data)
771 +{
772 + struct show_info *show_info = cb_data;
773 + struct branch_info *branch_info = item->util;
774 + struct string_list *merge = &branch_info->merge;
775 + const char *also;
776 + int i;
777 +
778 + if (branch_info->rebase && branch_info->merge.nr > 1) {
779 + error("invalid branch.%s.merge; cannot rebase onto > 1 branch",
780 + item->string);
781 + return 0;
782 + }
783 +
784 + printf(" %-*s ", show_info->width, item->string);
785 + if (branch_info->rebase) {
786 + printf("rebases onto remote %s\n", merge->items[0].string);
787 + return 0;
788 + } else if (show_info->any_rebase) {
789 + printf(" merges with remote %s\n", merge->items[0].string);
790 + also = " and with remote";
791 + } else {
792 + printf("merges with remote %s\n", merge->items[0].string);
793 + also = " and with remote";
794 + }
795 + for (i = 1; i < merge->nr; i++)
796 + printf(" %-*s %s %s\n", show_info->width, "", also,
797 + merge->items[i].string);
798 +
799 + return 0;
800 +}
801 +
802 static int show(int argc, const char **argv)
803 {
804 int no_query = 0, result = 0, query_flag = 0;
@@ -716,6 +808,8 @@ static int show(int argc, const char **argv)
808 OPT_END()
809 };
810 struct ref_states states;
811 + struct string_list info_list = { NULL, 0, 0, 0 };
812 + struct show_info info;
813
814 argc = parse_options(argc, argv, options, builtin_remote_usage, 0);
815
@@ -726,6 +820,9 @@ static int show(int argc, const char **argv)
820 query_flag = (GET_REF_STATES | GET_HEAD_NAMES);
821
822 memset(&states, 0, sizeof(states));
823 + memset(&info, 0, sizeof(info));
824 + info.states = &states;
825 + info.list = &info_list;
826 for (; argc; argc--, argv++) {
827 int i;
828
@@ -747,32 +844,29 @@ static int show(int argc, const char **argv)
844 printf(" %s\n", states.heads.items[i].string);
845 }
846
750 - for (i = 0; i < branch_list.nr; i++) {
751 - struct string_list_item *branch = branch_list.items + i;
752 - struct branch_info *info = branch->util;
753 - int j;
754 -
755 - if (!info->merge.nr || strcmp(*argv, info->remote_name))
756 - continue;
757 - printf(" Remote branch%s merged with 'git pull' "
758 - "while on branch %s\n ",
759 - info->merge.nr > 1 ? "es" : "",
760 - branch->string);
761 - for (j = 0; j < info->merge.nr; j++)
762 - printf(" %s", info->merge.items[j].string);
763 - printf("\n");
764 - }
765 -
766 - if (!no_query) {
767 - show_list(" New remote branch%s (next fetch "
768 - "will store in remotes/%s)",
769 - &states.new, states.remote->name);
770 - show_list(" Stale tracking branch%s (use 'git remote "
771 - "prune')", &states.stale, "");
772 - }
773 -
774 - show_list(" Tracked remote branch%s", &states.tracked, "");
775 -
847 + /* remote branch info */
848 + info.width = 0;
849 + for_each_string_list(add_remote_to_show_info, &states.new, &info);
850 + for_each_string_list(add_remote_to_show_info, &states.tracked, &info);
851 + for_each_string_list(add_remote_to_show_info, &states.stale, &info);
852 + if (info.list->nr)
853 + printf(" Remote branch%s:%s\n",
854 + info.list->nr > 1 ? "es" : "",
855 + no_query ? " (status not queried)" : "");
856 + for_each_string_list(show_remote_info_item, info.list, &info);
857 + string_list_clear(info.list, 0);
858 +
859 + /* git pull info */
860 + info.width = 0;
861 + info.any_rebase = 0;
862 + for_each_string_list(add_local_to_show_info, &branch_list, &info);
863 + if (info.list->nr)
864 + printf(" Local branch%s configured for 'git pull':\n",
865 + info.list->nr > 1 ? "es" : "");
866 + for_each_string_list(show_local_info_item, info.list, &info);
867 + string_list_clear(info.list, 0);
868 +
869 + /* git push info */
870 if (states.remote->push_refspec_nr) {
871 printf(" Local branch%s pushed with 'git push'\n",
872 states.remote->push_refspec_nr > 1 ?
t/t5505-remote.sh
+21 -17
@@ -28,7 +28,7 @@ tokens_match () {
28 }
29
30 check_remote_track () {
31 - actual=$(git remote show "$1" | sed -e '1,/Tracked/d') &&
31 + actual=$(git remote show "$1" | sed -ne 's|^ \(.*\) tracked$|\1|p')
32 shift &&
33 tokens_match "$*" "$actual"
34 }
@@ -137,13 +137,15 @@ 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)
143 - master
144 - Tracked remote branches
145 - master
146 - side
140 + Remote branches:
141 + master new (next fetch will store in remotes/origin)
142 + side tracked
143 + Local branches configured for 'git pull':
144 + master merges with remote master
145 + octopus merges with remote topic-a
146 + and with remote topic-b
147 + and with remote topic-c
148 + rebase rebases onto remote master
149 Local branches pushed with 'git push'
150 master:upstream
151 +refs/tags/lastbackup
@@ -156,20 +158,22 @@ EOF
158
159 test_expect_success 'show' '
160 (cd test &&
159 - git config --add remote.origin.fetch \
160 - refs/heads/master:refs/heads/upstream &&
161 + git config --add remote.origin.fetch refs/heads/master:refs/heads/upstream &&
162 git fetch &&
163 + git branch --track octopus origin/master &&
164 + git branch --track rebase origin/master &&
165 git branch -d -r origin/master &&
166 git config --add remote.two.url ../two &&
167 + git config branch.rebase.rebase true &&
168 + git config branch.octopus.merge "topic-a topic-b topic-c" &&
169 (cd ../one &&
170 echo 1 > file &&
171 test_tick &&
172 git commit -m update file) &&
168 - git config remote.origin.push \
169 - refs/heads/master:refs/heads/upstream &&
170 - git config --add remote.origin.push \
171 - +refs/tags/lastbackup &&
173 + git config remote.origin.push refs/heads/master:refs/heads/upstream &&
174 + git config --add remote.origin.push +refs/tags/lastbackup &&
175 git remote show origin two > output &&
176 + git branch -d rebase octopus &&
177 test_cmp expect output)
178 '
179
@@ -177,11 +181,11 @@ cat > test/expect << EOF
181 * remote origin
182 URL: $(pwd)/one
183 HEAD branch: (not queried)
180 - Remote branch merged with 'git pull' while on branch master
181 - master
182 - Tracked remote branches
184 + Remote branches: (status not queried)
185 master
186 side
187 + Local branch configured for 'git pull':
188 + master merges with remote master
189 Local branches pushed with 'git push'
190 master:upstream
191 +refs/tags/lastbackup