]> git.ipfire.org Git - thirdparty/git.git/commitdiff
fetch: optionally allow disabling FETCH_HEAD update
authorJunio C Hamano <gitster@pobox.com>
Tue, 18 Aug 2020 14:25:22 +0000 (14:25 +0000)
committerJunio C Hamano <gitster@pobox.com>
Tue, 18 Aug 2020 19:56:57 +0000 (12:56 -0700)
If you run fetch but record the result in remote-tracking branches,
and either if you do nothing with the fetched refs (e.g. you are
merely mirroring) or if you always work from the remote-tracking
refs (e.g. you fetch and then merge origin/branchname separately),
you can get away with having no FETCH_HEAD at all.

Teach "git fetch" a command line option "--[no-]write-fetch-head".
The default is to write FETCH_HEAD, and the option is primarily
meant to be used with the "--no-" prefix to override this default,
because there is no matching fetch.writeFetchHEAD configuration
variable to flip the default to off (in which case, the positive
form may become necessary to defeat it).

Note that under "--dry-run" mode, FETCH_HEAD is never written;
otherwise you'd see list of objects in the file that you do not
actually have.  Passing `--write-fetch-head` does not force `git
fetch` to write the file.

Signed-off-by: Derrick Stolee <dstolee@microsoft.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Documentation/fetch-options.txt
builtin/fetch.c
t/t5510-fetch.sh
t/t5521-pull-options.sh

index 6e2a160a47cb8c07a72600d2fc7ad404bf2bc1c1..07d06ff445caa87e3aa81653af779d1ccca44651 100644 (file)
@@ -64,6 +64,15 @@ documented in linkgit:git-config[1].
 --dry-run::
        Show what would be done, without making any changes.
 
+ifndef::git-pull[]
+--[no-]write-fetch-head::
+       Write the list of remote refs fetched in the `FETCH_HEAD`
+       file directly under `$GIT_DIR`.  This is the default.
+       Passing `--no-write-fetch-head` from the command line tells
+       Git not to write the file.  Under `--dry-run` option, the
+       file is never written.
+endif::git-pull[]
+
 -f::
 --force::
        When 'git fetch' is used with `<src>:<dst>` refspec it may
index c49f0e975203b039cbcf2ccab9860904f3f67e47..2eb8d6a5a5c015ad1530502bfd5db666d5d6b9e0 100644 (file)
@@ -56,6 +56,7 @@ static int prune_tags = -1; /* unspecified */
 #define PRUNE_TAGS_BY_DEFAULT 0 /* do we prune tags by default? */
 
 static int all, append, dry_run, force, keep, multiple, update_head_ok;
+static int write_fetch_head = 1;
 static int verbosity, deepen_relative, set_upstream;
 static int progress = -1;
 static int enable_auto_gc = 1;
@@ -162,6 +163,8 @@ static struct option builtin_fetch_options[] = {
                    PARSE_OPT_OPTARG, option_fetch_parse_recurse_submodules),
        OPT_BOOL(0, "dry-run", &dry_run,
                 N_("dry run")),
+       OPT_BOOL(0, "write-fetch-head", &write_fetch_head,
+                N_("write fetched references to the FETCH_HEAD file")),
        OPT_BOOL('k', "keep", &keep, N_("keep downloaded pack")),
        OPT_BOOL('u', "update-head-ok", &update_head_ok,
                    N_("allow updating of HEAD ref")),
@@ -893,7 +896,9 @@ static int store_updated_refs(const char *raw_url, const char *remote_name,
        const char *what, *kind;
        struct ref *rm;
        char *url;
-       const char *filename = dry_run ? "/dev/null" : git_path_fetch_head(the_repository);
+       const char *filename = (!write_fetch_head
+                               ? "/dev/null"
+                               : git_path_fetch_head(the_repository));
        int want_status;
        int summary_width = transport_summary_width(ref_map);
 
@@ -1327,7 +1332,7 @@ static int do_fetch(struct transport *transport,
        }
 
        /* if not appending, truncate FETCH_HEAD */
-       if (!append && !dry_run) {
+       if (!append && write_fetch_head) {
                retcode = truncate_fetch_head();
                if (retcode)
                        goto cleanup;
@@ -1594,7 +1599,7 @@ static int fetch_multiple(struct string_list *list, int max_children)
        int i, result = 0;
        struct strvec argv = STRVEC_INIT;
 
-       if (!append && !dry_run) {
+       if (!append && write_fetch_head) {
                int errcode = truncate_fetch_head();
                if (errcode)
                        return errcode;
@@ -1795,6 +1800,10 @@ int cmd_fetch(int argc, const char **argv, const char *prefix)
        if (depth || deepen_since || deepen_not.nr)
                deepen = 1;
 
+       /* FETCH_HEAD never gets updated in --dry-run mode */
+       if (dry_run)
+               write_fetch_head = 0;
+
        if (all) {
                if (argc == 1)
                        die(_("fetch --all does not take a repository argument"));
index 25695dfe2232ef3d1ce54ef0eedec2b9fe51b3da..2a1abe91f0fd34b7929aa636ab43542c6e45ea54 100755 (executable)
@@ -543,13 +543,24 @@ test_expect_success 'fetch into the current branch with --update-head-ok' '
 
 '
 
-test_expect_success 'fetch --dry-run' '
-
+test_expect_success 'fetch --dry-run does not touch FETCH_HEAD' '
        rm -f .git/FETCH_HEAD &&
        git fetch --dry-run . &&
        ! test -f .git/FETCH_HEAD
 '
 
+test_expect_success '--no-write-fetch-head does not touch FETCH_HEAD' '
+       rm -f .git/FETCH_HEAD &&
+       git fetch --no-write-fetch-head . &&
+       ! test -f .git/FETCH_HEAD
+'
+
+test_expect_success '--write-fetch-head gets defeated by --dry-run' '
+       rm -f .git/FETCH_HEAD &&
+       git fetch --dry-run --write-fetch-head . &&
+       ! test -f .git/FETCH_HEAD
+'
+
 test_expect_success "should be able to fetch with duplicate refspecs" '
        mkdir dups &&
        (
index 159afa7ac81396e1d9915335f030cd0fcc8b7b3f..db1a381cd91c3470b7007b747e3b3a82f4da162f 100755 (executable)
@@ -85,6 +85,13 @@ test_expect_success 'git pull --cleanup errors early on invalid argument' '
        test -s err)
 '
 
+test_expect_success 'git pull --no-write-fetch-head fails' '
+       mkdir clonedwfh &&
+       (cd clonedwfh && git init &&
+       test_expect_code 129 git pull --no-write-fetch-head "../parent" >out 2>err &&
+       test_must_be_empty out &&
+       test_i18ngrep "no-write-fetch-head" err)
+'
 
 test_expect_success 'git pull --force' '
        mkdir clonedoldstyle &&