Skip to content

Commit 8144049

Browse files
committed
Merge branch 'dj/fetch-all-tags' into maint
"git fetch --all", when passed "--no-tags", did not honor the "--no-tags" option while fetching from individual remotes (the same issue existed with "--tags", but combination "--all --tags" makes much less sense than "--all --no-tags"). * dj/fetch-all-tags: fetch --all: pass --tags/--no-tags through to each remote submodule: use argv_array instead of hand-building arrays fetch: use argv_array instead of hand-building arrays argv-array: fix bogus cast when freeing array argv-array: add pop function
2 parents f9db192 + 8556646 commit 8144049

File tree

7 files changed

+92
-39
lines changed

7 files changed

+92
-39
lines changed

Documentation/technical/api-argv-array.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,10 @@ Functions
4646
Format a string and push it onto the end of the array. This is a
4747
convenience wrapper combining `strbuf_addf` and `argv_array_push`.
4848

49+
`argv_array_pop`::
50+
Remove the final element from the array. If there are no
51+
elements in the array, do nothing.
52+
4953
`argv_array_clear`::
5054
Free all memory associated with the array and return it to the
5155
initial, empty state.

argv-array.c

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,12 +49,21 @@ void argv_array_pushl(struct argv_array *array, ...)
4949
va_end(ap);
5050
}
5151

52+
void argv_array_pop(struct argv_array *array)
53+
{
54+
if (!array->argc)
55+
return;
56+
free((char *)array->argv[array->argc - 1]);
57+
array->argv[array->argc - 1] = NULL;
58+
array->argc--;
59+
}
60+
5261
void argv_array_clear(struct argv_array *array)
5362
{
5463
if (array->argv != empty_argv) {
5564
int i;
5665
for (i = 0; i < array->argc; i++)
57-
free((char **)array->argv[i]);
66+
free((char *)array->argv[i]);
5867
free(array->argv);
5968
}
6069
argv_array_init(array);

argv-array.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ void argv_array_push(struct argv_array *, const char *);
1616
__attribute__((format (printf,2,3)))
1717
void argv_array_pushf(struct argv_array *, const char *fmt, ...);
1818
void argv_array_pushl(struct argv_array *, ...);
19+
void argv_array_pop(struct argv_array *);
1920
void argv_array_clear(struct argv_array *);
2021

2122
#endif /* ARGV_ARRAY_H */

builtin/fetch.c

Lines changed: 29 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#include "transport.h"
1515
#include "submodule.h"
1616
#include "connected.h"
17+
#include "argv-array.h"
1718

1819
static const char * const builtin_fetch_usage[] = {
1920
"git fetch [<options>] [<repository> [<refspec>...]]",
@@ -841,57 +842,62 @@ static int add_remote_or_group(const char *name, struct string_list *list)
841842
return 1;
842843
}
843844

844-
static void add_options_to_argv(int *argc, const char **argv)
845+
static void add_options_to_argv(struct argv_array *argv)
845846
{
846847
if (dry_run)
847-
argv[(*argc)++] = "--dry-run";
848+
argv_array_push(argv, "--dry-run");
848849
if (prune)
849-
argv[(*argc)++] = "--prune";
850+
argv_array_push(argv, "--prune");
850851
if (update_head_ok)
851-
argv[(*argc)++] = "--update-head-ok";
852+
argv_array_push(argv, "--update-head-ok");
852853
if (force)
853-
argv[(*argc)++] = "--force";
854+
argv_array_push(argv, "--force");
854855
if (keep)
855-
argv[(*argc)++] = "--keep";
856+
argv_array_push(argv, "--keep");
856857
if (recurse_submodules == RECURSE_SUBMODULES_ON)
857-
argv[(*argc)++] = "--recurse-submodules";
858+
argv_array_push(argv, "--recurse-submodules");
858859
else if (recurse_submodules == RECURSE_SUBMODULES_ON_DEMAND)
859-
argv[(*argc)++] = "--recurse-submodules=on-demand";
860+
argv_array_push(argv, "--recurse-submodules=on-demand");
861+
if (tags == TAGS_SET)
862+
argv_array_push(argv, "--tags");
863+
else if (tags == TAGS_UNSET)
864+
argv_array_push(argv, "--no-tags");
860865
if (verbosity >= 2)
861-
argv[(*argc)++] = "-v";
866+
argv_array_push(argv, "-v");
862867
if (verbosity >= 1)
863-
argv[(*argc)++] = "-v";
868+
argv_array_push(argv, "-v");
864869
else if (verbosity < 0)
865-
argv[(*argc)++] = "-q";
870+
argv_array_push(argv, "-q");
866871

867872
}
868873

869874
static int fetch_multiple(struct string_list *list)
870875
{
871876
int i, result = 0;
872-
const char *argv[12] = { "fetch", "--append" };
873-
int argc = 2;
874-
875-
add_options_to_argv(&argc, argv);
877+
struct argv_array argv = ARGV_ARRAY_INIT;
876878

877879
if (!append && !dry_run) {
878880
int errcode = truncate_fetch_head();
879881
if (errcode)
880882
return errcode;
881883
}
882884

885+
argv_array_pushl(&argv, "fetch", "--append", NULL);
886+
add_options_to_argv(&argv);
887+
883888
for (i = 0; i < list->nr; i++) {
884889
const char *name = list->items[i].string;
885-
argv[argc] = name;
886-
argv[argc + 1] = NULL;
890+
argv_array_push(&argv, name);
887891
if (verbosity >= 0)
888892
printf(_("Fetching %s\n"), name);
889-
if (run_command_v_opt(argv, RUN_GIT_CMD)) {
893+
if (run_command_v_opt(argv.argv, RUN_GIT_CMD)) {
890894
error(_("Could not fetch %s"), name);
891895
result = 1;
892896
}
897+
argv_array_pop(&argv);
893898
}
894899

900+
argv_array_clear(&argv);
895901
return result;
896902
}
897903

@@ -1007,13 +1013,14 @@ int cmd_fetch(int argc, const char **argv, const char *prefix)
10071013
}
10081014

10091015
if (!result && (recurse_submodules != RECURSE_SUBMODULES_OFF)) {
1010-
const char *options[10];
1011-
int num_options = 0;
1012-
add_options_to_argv(&num_options, options);
1013-
result = fetch_populated_submodules(num_options, options,
1016+
struct argv_array options = ARGV_ARRAY_INIT;
1017+
1018+
add_options_to_argv(&options);
1019+
result = fetch_populated_submodules(&options,
10141020
submodule_prefix,
10151021
recurse_submodules,
10161022
verbosity < 0);
1023+
argv_array_clear(&options);
10171024
}
10181025

10191026
/* All names were strdup()ed or strndup()ed */

submodule.c

Lines changed: 16 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -588,13 +588,13 @@ static void calculate_changed_submodule_paths(void)
588588
initialized_fetch_ref_tips = 0;
589589
}
590590

591-
int fetch_populated_submodules(int num_options, const char **options,
591+
int fetch_populated_submodules(const struct argv_array *options,
592592
const char *prefix, int command_line_option,
593593
int quiet)
594594
{
595-
int i, result = 0, argc = 0, default_argc;
595+
int i, result = 0;
596596
struct child_process cp;
597-
const char **argv;
597+
struct argv_array argv = ARGV_ARRAY_INIT;
598598
struct string_list_item *name_for_path;
599599
const char *work_tree = get_git_work_tree();
600600
if (!work_tree)
@@ -604,17 +604,13 @@ int fetch_populated_submodules(int num_options, const char **options,
604604
if (read_cache() < 0)
605605
die("index file corrupt");
606606

607-
/* 6: "fetch" (options) --recurse-submodules-default default "--submodule-prefix" prefix NULL */
608-
argv = xcalloc(num_options + 6, sizeof(const char *));
609-
argv[argc++] = "fetch";
610-
for (i = 0; i < num_options; i++)
611-
argv[argc++] = options[i];
612-
argv[argc++] = "--recurse-submodules-default";
613-
default_argc = argc++;
614-
argv[argc++] = "--submodule-prefix";
607+
argv_array_push(&argv, "fetch");
608+
for (i = 0; i < options->argc; i++)
609+
argv_array_push(&argv, options->argv[i]);
610+
argv_array_push(&argv, "--recurse-submodules-default");
611+
/* default value, "--submodule-prefix" and its value are added later */
615612

616613
memset(&cp, 0, sizeof(cp));
617-
cp.argv = argv;
618614
cp.env = local_repo_env;
619615
cp.git_cmd = 1;
620616
cp.no_stdin = 1;
@@ -674,16 +670,21 @@ int fetch_populated_submodules(int num_options, const char **options,
674670
if (!quiet)
675671
printf("Fetching submodule %s%s\n", prefix, ce->name);
676672
cp.dir = submodule_path.buf;
677-
argv[default_argc] = default_argv;
678-
argv[argc] = submodule_prefix.buf;
673+
argv_array_push(&argv, default_argv);
674+
argv_array_push(&argv, "--submodule-prefix");
675+
argv_array_push(&argv, submodule_prefix.buf);
676+
cp.argv = argv.argv;
679677
if (run_command(&cp))
680678
result = 1;
679+
argv_array_pop(&argv);
680+
argv_array_pop(&argv);
681+
argv_array_pop(&argv);
681682
}
682683
strbuf_release(&submodule_path);
683684
strbuf_release(&submodule_git_dir);
684685
strbuf_release(&submodule_prefix);
685686
}
686-
free(argv);
687+
argv_array_clear(&argv);
687688
out:
688689
string_list_clear(&changed_submodule_paths, 1);
689690
return result;

submodule.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
#define SUBMODULE_H
33

44
struct diff_options;
5+
struct argv_array;
56

67
enum {
78
RECURSE_SUBMODULES_ON_DEMAND = -1,
@@ -23,7 +24,7 @@ void show_submodule_summary(FILE *f, const char *path,
2324
const char *del, const char *add, const char *reset);
2425
void set_config_fetch_recurse_submodules(int value);
2526
void check_for_new_submodule_commits(unsigned char new_sha1[20]);
26-
int fetch_populated_submodules(int num_options, const char **options,
27+
int fetch_populated_submodules(const struct argv_array *options,
2728
const char *prefix, int command_line_option,
2829
int quiet);
2930
unsigned is_submodule_modified(const char *path, int ignore_untracked);

t/t5514-fetch-multiple.sh

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,4 +151,34 @@ test_expect_success 'git fetch --multiple (ignoring skipFetchAll)' '
151151
test_cmp ../expect output)
152152
'
153153

154+
test_expect_success 'git fetch --all --no-tags' '
155+
>expect &&
156+
git clone one test5 &&
157+
git clone test5 test6 &&
158+
(cd test5 && git tag test-tag) &&
159+
(
160+
cd test6 &&
161+
git fetch --all --no-tags &&
162+
git tag >output
163+
) &&
164+
test_cmp expect test6/output
165+
'
166+
167+
test_expect_success 'git fetch --all --tags' '
168+
echo test-tag >expect &&
169+
git clone one test7 &&
170+
git clone test7 test8 &&
171+
(
172+
cd test7 &&
173+
test_commit test-tag &&
174+
git reset --hard HEAD^
175+
) &&
176+
(
177+
cd test8 &&
178+
git fetch --all --tags &&
179+
git tag >output
180+
) &&
181+
test_cmp expect test8/output
182+
'
183+
154184
test_done

0 commit comments

Comments
 (0)