From 13e65fe6314bf44e64f22b9b66a4e5940adaa2e5 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Wed, 24 Feb 2010 10:22:05 -0800 Subject: [PATCH 1/3] t5521: fix and modernize All of these tests were bogus, as they created new directory and tried to run "git pull" without even running "git init" in there. They were mucking with the repository in $TEST_DIRECTORY. While fixing it, modernize the style not to chdir around outside of subshell. Otherwise a failed test will take us to an unexpected directory and we need to chdir back to the test directory in each test, which is ugly and error prone. Signed-off-by: Junio C Hamano --- t/t5521-pull-options.sh | 46 ++++++++++++++++++----------------------- 1 file changed, 20 insertions(+), 26 deletions(-) diff --git a/t/t5521-pull-options.sh b/t/t5521-pull-options.sh index 83e2e8ab80..c18d82973f 100755 --- a/t/t5521-pull-options.sh +++ b/t/t5521-pull-options.sh @@ -4,8 +4,6 @@ test_description='pull options' . ./test-lib.sh -D=`pwd` - test_expect_success 'setup' ' mkdir parent && (cd parent && git init && @@ -13,48 +11,44 @@ test_expect_success 'setup' ' git commit -m one) ' -cd "$D" - test_expect_success 'git pull -q' ' mkdir clonedq && - cd clonedq && - git pull -q "$D/parent" >out 2>err && - test ! -s out + (cd clonedq && git init && + git pull -q "../parent" >out 2>err && + test ! -s err && + test ! -s out) ' -cd "$D" - test_expect_success 'git pull' ' mkdir cloned && - cd cloned && - git pull "$D/parent" >out 2>err && - test -s out + (cd cloned && git init && + git pull "../parent" >out 2>err && + test -s err && + test ! -s out) ' -cd "$D" test_expect_success 'git pull -v' ' mkdir clonedv && - cd clonedv && - git pull -v "$D/parent" >out 2>err && - test -s out + (cd clonedv && git init && + git pull -v "../parent" >out 2>err && + test -s err && + test ! -s out) ' -cd "$D" - test_expect_success 'git pull -v -q' ' mkdir clonedvq && - cd clonedvq && - git pull -v -q "$D/parent" >out 2>err && - test ! -s out + (cd clonedvq && git init && + git pull -v -q "../parent" >out 2>err && + test ! -s out && + test ! -s err) ' -cd "$D" - test_expect_success 'git pull -q -v' ' mkdir clonedqv && - cd clonedqv && - git pull -q -v "$D/parent" >out 2>err && - test -s out + (cd clonedqv && git init && + git pull -q -v "../parent" >out 2>err && + test ! -s out && + test -s err) ' test_done From bba5322a71a3399a94f53e1dddf5bd66e493dfbc Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Wed, 24 Feb 2010 10:22:06 -0800 Subject: [PATCH 2/3] builtin-fetch --all/--multi: propagate options correctly When running a subfetch, the code propagated some options but not others. Propagate --force, --update-head-ok and --keep options as well. Signed-off-by: Junio C Hamano --- builtin-fetch.c | 9 ++++++++- t/t5521-pull-options.sh | 21 +++++++++++++++++++++ 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/builtin-fetch.c b/builtin-fetch.c index 8654fa7a2d..61b2e4060c 100644 --- a/builtin-fetch.c +++ b/builtin-fetch.c @@ -784,13 +784,19 @@ static int add_remote_or_group(const char *name, struct string_list *list) static int fetch_multiple(struct string_list *list) { int i, result = 0; - const char *argv[] = { "fetch", NULL, NULL, NULL, NULL, NULL, NULL }; + const char *argv[10] = { "fetch" }; int argc = 1; if (dry_run) argv[argc++] = "--dry-run"; if (prune) argv[argc++] = "--prune"; + if (update_head_ok) + argv[argc++] = "--update-head-ok"; + if (force) + argv[argc++] = "--force"; + if (keep) + argv[argc++] = "--keep"; if (verbosity >= 2) argv[argc++] = "-v"; if (verbosity >= 1) @@ -801,6 +807,7 @@ static int fetch_multiple(struct string_list *list) for (i = 0; i < list->nr; i++) { const char *name = list->items[i].string; argv[argc] = name; + argv[argc + 1] = NULL; if (verbosity >= 0) printf("Fetching %s\n", name); if (run_command_v_opt(argv, RUN_GIT_CMD)) { diff --git a/t/t5521-pull-options.sh b/t/t5521-pull-options.sh index c18d82973f..84059d82d5 100755 --- a/t/t5521-pull-options.sh +++ b/t/t5521-pull-options.sh @@ -51,4 +51,25 @@ test_expect_success 'git pull -q -v' ' test -s err) ' +test_expect_success 'git pull --force' ' + mkdir clonedoldstyle && + (cd clonedoldstyle && git init && + cat >>.git/config <<-\EOF && + [remote "one"] + url = ../parent + fetch = refs/heads/master:refs/heads/mirror + [remote "two"] + url = ../parent + fetch = refs/heads/master:refs/heads/origin + [branch "master"] + remote = two + merge = refs/heads/master + EOF + git pull two && + test_commit A && + git branch -f origin && + git pull --all --force + ) +' + test_done From e6cc51046f3669332f51a52a7de966d842b9d4e4 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Wed, 24 Feb 2010 11:02:05 -0800 Subject: [PATCH 3/3] fetch --all/--multiple: keep all the fetched branch information Since "git fetch" learned "--all" and "--multiple" options, it has become tempting for users to say "git pull --all". Even though it may fetch from remotes that do not need to be fetched from for merging with the current branch, it is handy. "git fetch" however clears the list of fetched branches every time it contacts a different remote. Unless the current branch is configured to merge with a branch from a remote that happens to be the last in the list of remotes that are contacted, "git pull" that fetches from multiple remotes will not be able to find the branch it should be merging with. Make "fetch" clear FETCH_HEAD (unless --append is given) and then append the list of branches fetched to it (even when --append is not given). That way, "pull" will be able to find the data for the branch being merged in FETCH_HEAD no matter where the remote appears in the list of remotes to be contacted by "git fetch". Reported-by: Michael Lukashov Signed-off-by: Junio C Hamano --- builtin-fetch.c | 29 ++++++++++++++++++++++------- t/t5521-pull-options.sh | 18 ++++++++++++++++++ 2 files changed, 40 insertions(+), 7 deletions(-) diff --git a/builtin-fetch.c b/builtin-fetch.c index 61b2e4060c..b059d652c6 100644 --- a/builtin-fetch.c +++ b/builtin-fetch.c @@ -651,6 +651,17 @@ static void check_not_current_branch(struct ref *ref_map) "of non-bare repository", current_branch->refname); } +static int truncate_fetch_head(void) +{ + char *filename = git_path("FETCH_HEAD"); + FILE *fp = fopen(filename, "w"); + + if (!fp) + return error("cannot open %s: %s\n", filename, strerror(errno)); + fclose(fp); + return 0; +} + static int do_fetch(struct transport *transport, struct refspec *refs, int ref_count) { @@ -672,11 +683,9 @@ static int do_fetch(struct transport *transport, /* if not appending, truncate FETCH_HEAD */ if (!append && !dry_run) { - char *filename = git_path("FETCH_HEAD"); - FILE *fp = fopen(filename, "w"); - if (!fp) - return error("cannot open %s: %s\n", filename, strerror(errno)); - fclose(fp); + int errcode = truncate_fetch_head(); + if (errcode) + return errcode; } ref_map = get_ref_map(transport, refs, ref_count, tags, &autotags); @@ -784,8 +793,8 @@ static int add_remote_or_group(const char *name, struct string_list *list) static int fetch_multiple(struct string_list *list) { int i, result = 0; - const char *argv[10] = { "fetch" }; - int argc = 1; + const char *argv[11] = { "fetch", "--append" }; + int argc = 2; if (dry_run) argv[argc++] = "--dry-run"; @@ -804,6 +813,12 @@ static int fetch_multiple(struct string_list *list) else if (verbosity < 0) argv[argc++] = "-q"; + if (!append && !dry_run) { + int errcode = truncate_fetch_head(); + if (errcode) + return errcode; + } + for (i = 0; i < list->nr; i++) { const char *name = list->items[i].string; argv[argc] = name; diff --git a/t/t5521-pull-options.sh b/t/t5521-pull-options.sh index 84059d82d5..1b06691bb4 100755 --- a/t/t5521-pull-options.sh +++ b/t/t5521-pull-options.sh @@ -72,4 +72,22 @@ test_expect_success 'git pull --force' ' ) ' +test_expect_success 'git pull --all' ' + mkdir clonedmulti && + (cd clonedmulti && git init && + cat >>.git/config <<-\EOF && + [remote "one"] + url = ../parent + fetch = refs/heads/*:refs/remotes/one/* + [remote "two"] + url = ../parent + fetch = refs/heads/*:refs/remotes/two/* + [branch "master"] + remote = one + merge = refs/heads/master + EOF + git pull --all + ) +' + test_done