* [RFC/PATCH] fetch: make --prune configurable @ 2013-07-08 12:56 Michael Schubert 2013-07-08 18:36 ` Junio C Hamano ` (2 more replies) 0 siblings, 3 replies; 5+ messages in thread From: Michael Schubert @ 2013-07-08 12:56 UTC (permalink / raw) To: git; +Cc: Michael Schubert $gmane/201715 brought up the idea to fetch --prune by default. Since --prune is a "potentially destructive operation" (Git doesn't keep reflogs for deleted references yet), we don't want to prune without users consent. To accommodate users who want to either prune always or when fetching from a particular remote, add two new configuration variables "fetch.prune" and "remote.<name>.prune": - "fetch.prune" allows to enable prune for all fetch operations. - "remote.<name>.prune" allows to change the behaviour per remote. Signed-off-by: Michael Schubert <mschub@elegosoft.com> --- http://thread.gmane.org/gmane.comp.version-control.git/201715 Documentation/config.txt | 9 +++++++++ builtin/fetch.c | 28 +++++++++++++++++++++++++--- remote.c | 2 ++ remote.h | 1 + t/t5510-fetch.sh | 38 ++++++++++++++++++++++++++++++++++++++ 5 files changed, 75 insertions(+), 3 deletions(-) diff --git a/Documentation/config.txt b/Documentation/config.txt index b4d4887..74e8026 100644 --- a/Documentation/config.txt +++ b/Documentation/config.txt @@ -1067,6 +1067,10 @@ fetch.unpackLimit:: especially on slow filesystems. If not set, the value of `transfer.unpackLimit` is used instead. +fetch.prune:: + If true, fetch will automatically behave as if the `--prune` + option was given on the command line. + format.attach:: Enable multipart/mixed attachments as the default for 'format-patch'. The value can also be a double quoted string @@ -2010,6 +2014,11 @@ remote.<name>.vcs:: Setting this to a value <vcs> will cause Git to interact with the remote with the git-remote-<vcs> helper. +remote.<name>.prune:: + When set to true, fetching from this remote by default will also + remove any remote-tracking branches which no longer exist on the + remote (as if the `--prune` option was give on the command line). + remotes.<group>:: The list of remotes which are fetched by "git remote update <group>". See linkgit:git-remote[1]. diff --git a/builtin/fetch.c b/builtin/fetch.c index d784b2e..3953317 100644 --- a/builtin/fetch.c +++ b/builtin/fetch.c @@ -30,7 +30,14 @@ enum { TAGS_SET = 2 }; -static int all, append, dry_run, force, keep, multiple, prune, update_head_ok, verbosity; +enum { + PRUNE_UNSET = 0, + PRUNE_DEFAULT = 1, + PRUNE_FORCE = 2 +}; + +static int prune = PRUNE_DEFAULT; +static int all, append, dry_run, force, keep, multiple, update_head_ok, verbosity; static int progress = -1, recurse_submodules = RECURSE_SUBMODULES_DEFAULT; static int tags = TAGS_DEFAULT, unshallow; static const char *depth; @@ -54,6 +61,17 @@ static int option_parse_recurse_submodules(const struct option *opt, return 0; } +static int git_fetch_config(const char *k, const char *v, void *cb) +{ + if (!strcmp(k, "fetch.prune")) { + int boolval = git_config_bool(k, v); + if (boolval) + prune = PRUNE_FORCE; + return 0; + } + return git_default_config(k, v, cb); +} + static struct option builtin_fetch_options[] = { OPT__VERBOSITY(&verbosity), OPT_BOOLEAN(0, "all", &all, @@ -770,7 +788,7 @@ static int do_fetch(struct transport *transport, retcode = 1; goto cleanup; } - if (prune) { + if (prune == PRUNE_FORCE || (transport->remote->prune && prune)) { /* If --tags was specified, pretend the user gave us the canonical tags refspec */ if (tags == TAGS_SET) { const char *tags_str = "refs/tags/*:refs/tags/*"; @@ -882,8 +900,10 @@ static void add_options_to_argv(struct argv_array *argv) { if (dry_run) argv_array_push(argv, "--dry-run"); - if (prune) + if (prune == PRUNE_FORCE) argv_array_push(argv, "--prune"); + else if (prune == PRUNE_UNSET) + argv_array_push(argv, "--no-prune"); if (update_head_ok) argv_array_push(argv, "--update-head-ok"); if (force) @@ -1007,6 +1027,8 @@ int cmd_fetch(int argc, const char **argv, const char *prefix) for (i = 1; i < argc; i++) strbuf_addf(&default_rla, " %s", argv[i]); + git_config(git_fetch_config, NULL); + argc = parse_options(argc, argv, prefix, builtin_fetch_options, builtin_fetch_usage, 0); diff --git a/remote.c b/remote.c index 6f57830..e6f2acb 100644 --- a/remote.c +++ b/remote.c @@ -404,6 +404,8 @@ static int handle_config(const char *key, const char *value, void *cb) remote->skip_default_update = git_config_bool(key, value); else if (!strcmp(subkey, ".skipfetchall")) remote->skip_default_update = git_config_bool(key, value); + else if (!strcmp(subkey, ".prune")) + remote->prune = git_config_bool(key, value); else if (!strcmp(subkey, ".url")) { const char *v; if (git_config_string(&v, key, value)) diff --git a/remote.h b/remote.h index cf56724..4db3498 100644 --- a/remote.h +++ b/remote.h @@ -40,6 +40,7 @@ struct remote { int fetch_tags; int skip_default_update; int mirror; + int prune; const char *receivepack; const char *uploadpack; diff --git a/t/t5510-fetch.sh b/t/t5510-fetch.sh index fde6891..f3d63ca 100755 --- a/t/t5510-fetch.sh +++ b/t/t5510-fetch.sh @@ -497,6 +497,44 @@ test_expect_success "should be able to fetch with duplicate refspecs" ' ) ' +test_expect_success 'fetch should prune when fetch.prune is true' ' + cd "$D" && + git branch somebranch && + ( + cd one && + git fetch && + test -f .git/refs/remotes/origin/somebranch + ) && + git branch -d somebranch && + ( + cd one && + git config fetch.prune true && + git fetch --no-prune && + test -f .git/refs/remotes/origin/somebranch && + git fetch && + ! test -f .git/refs/remotes/origin/somebranch + ) +' + +test_expect_success 'fetch should prune when remote.<name>.prune is true' ' + cd "$D" && + git branch somebranch && + ( + cd one && + git fetch && + test -f .git/refs/remotes/origin/somebranch + ) && + git branch -d somebranch && + ( + cd one && + git config remote.origin.prune true && + git fetch --no-prune && + test -f .git/refs/remotes/origin/somebranch && + git fetch && + ! test -f .git/refs/remotes/origin/somebranch + ) +' + test_expect_success 'all boundary commits are excluded' ' test_commit base && test_commit oneside && -- 1.8.3.2.734.gbcd3b20 ^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [RFC/PATCH] fetch: make --prune configurable 2013-07-08 12:56 [RFC/PATCH] fetch: make --prune configurable Michael Schubert @ 2013-07-08 18:36 ` Junio C Hamano 2013-07-12 22:38 ` Junio C Hamano 2013-07-08 19:01 ` John Keeping 2013-07-09 3:50 ` Jeff King 2 siblings, 1 reply; 5+ messages in thread From: Junio C Hamano @ 2013-07-08 18:36 UTC (permalink / raw) To: Michael Schubert; +Cc: git Michael Schubert <mschub@elegosoft.com> writes: > $gmane/201715 brought up the idea to fetch --prune by default. When you can summarize it in a few lines, e.g. Without "git fetch --prune", remote-tracking branches for a branch the other side already has removed will stay forever. Some people want to always run "git fetch --prune". please refrain from forcing people to go to the web while reading logs. > Since --prune is a "potentially destructive operation" (Git doesn't > keep reflogs for deleted references yet), we don't want to prune > without users consent. > > To accommodate users who want to either prune always or when fetching > from a particular remote, add two new configuration variables > "fetch.prune" and "remote.<name>.prune": > > - "fetch.prune" allows to enable prune for all fetch operations. > > - "remote.<name>.prune" allows to change the behaviour per remote. > Add: "git fetch --no-prune" from the command line will defeat the configured default for safety. (I didn't check if your patch already does so, though). Other than that, the log message looks good. Thanks for starting to work on this. > diff --git a/Documentation/config.txt b/Documentation/config.txt > index b4d4887..74e8026 100644 > --- a/Documentation/config.txt > +++ b/Documentation/config.txt > @@ -1067,6 +1067,10 @@ fetch.unpackLimit:: > especially on slow filesystems. If not set, the value of > `transfer.unpackLimit` is used instead. > > +fetch.prune:: > + If true, fetch will automatically behave as if the `--prune` > + option was given on the command line. > + > format.attach:: > Enable multipart/mixed attachments as the default for > 'format-patch'. The value can also be a double quoted string > @@ -2010,6 +2014,11 @@ remote.<name>.vcs:: > Setting this to a value <vcs> will cause Git to interact with > the remote with the git-remote-<vcs> helper. > > +remote.<name>.prune:: > + When set to true, fetching from this remote by default will also > + remove any remote-tracking branches which no longer exist on the > + remote (as if the `--prune` option was give on the command line). We may want to say something about interaction between the two variables. E.g. fetch.prune=true, remote.origin.prune=false would hopefully not to prune when you are fetching from your 'origin', and fetch.prune=false, remote.origin.prune=true would. > diff --git a/builtin/fetch.c b/builtin/fetch.c > index d784b2e..3953317 100644 > --- a/builtin/fetch.c > +++ b/builtin/fetch.c > @@ -30,7 +30,14 @@ enum { > TAGS_SET = 2 > }; > > -static int all, append, dry_run, force, keep, multiple, prune, update_head_ok, verbosity; > +enum { > + PRUNE_UNSET = 0, > + PRUNE_DEFAULT = 1, > + PRUNE_FORCE = 2 > +}; > + > +static int prune = PRUNE_DEFAULT; I find this unconventional in that usually _UNSET means "the user hasn't explicitly said anything about what she wants" (hence typically a variable is initialized to that value). Also I am not sure what "FORCE" means. If this were enum { PRUNE_UNSET = -1, PRUNE_NO = 0, PRUNE_YES = 1 }; then I would understand, but at that point, that is a typical setting for a boolean variable, so we could just use -1/0/1. > +static int all, append, dry_run, force, keep, multiple, update_head_ok, verbosity; > static int progress = -1, recurse_submodules = RECURSE_SUBMODULES_DEFAULT; > static int tags = TAGS_DEFAULT, unshallow; > static const char *depth; > @@ -54,6 +61,17 @@ static int option_parse_recurse_submodules(const struct option *opt, > return 0; > } > > +static int git_fetch_config(const char *k, const char *v, void *cb) > +{ > + if (!strcmp(k, "fetch.prune")) { > + int boolval = git_config_bool(k, v); > + if (boolval) > + prune = PRUNE_FORCE; > + return 0; This is not good, is it? Imagine fetch.prune=true in ~/.gitconfig and fetch.prune=false in $GIT_DIR/config; I'd expect the more specific one to set "prune" back to non-FORCE value. As you do not have transport available before you process parse_options(), I think you need two variables, "prune" that is used to determine what happens (same as in the code before your patch) and a new one "fetch_prune_config" that records what we read from the fetch.prune configuration. So I _suspect_ the interaction between the configuration parser and the command line option parser should look more like this, in order to implement the correct order of precedence: static int fetch_prune_config = -1; /* unspecified */ static int prune = -1; /* unspecified */ #define PRUNE_BY_DEFAULT 0 ... /* set "fetch_prune_config" */ git_config(git_fetch_config); --> git_fetch_config(): if (!strcmp(k, "fetch.prune")) { fetch_prune_config = git_config_bool(k, v); return 0; } ... /* set "prune" */ parse_options(); --> fetch_one(); transport_get(); if (prune < 0) { /* no command line request; combine configs */ if (0 <= transport->remote->prune) prune = transport->remote->prune; else if (0 <= fetch_prune_config) prune = fetch_prune_config; else prune = PRUNE_BY_DEFAULT; } You would need to update make_remote() to initialise its .prune member with -1 (unspecified). You also need to change OPT_BOOLEAN() to OPT_BOOL() for the command line processing for "prune", as the former is a "count up" that is useful for things like "-v", "-v -v", etc. > + } > + return git_default_config(k, v, cb); What kind of random configuration are we expecting to read from and affect our execution by falling back to the default config? > static struct option builtin_fetch_options[] = { > OPT__VERBOSITY(&verbosity), > OPT_BOOLEAN(0, "all", &all, > @@ -770,7 +788,7 @@ static int do_fetch(struct transport *transport, > retcode = 1; > goto cleanup; > } > - if (prune) { > + if (prune == PRUNE_FORCE || (transport->remote->prune && prune)) { I cannot offhand see how this is correct with your code (without the above "you need two variables" suggestion). It reads to me: If fetch.prune is set, we set it to PRUNE_FORCE in the configuration parser, and in that case we ignore everything else and go ahead to prune. which does not sound right. fetch.prune=yes remote.$name.prune=no should not prune, fetch.prune=yes with --no-prune from the command line should not prune, etc. But I may be misreading this complex boolean expression in the patch. And with the suggested change, this can stay if (prune) without having to do any mental gymnastics here. > @@ -882,8 +900,10 @@ static void add_options_to_argv(struct argv_array *argv) > { > if (dry_run) > argv_array_push(argv, "--dry-run"); > - if (prune) > + if (prune == PRUNE_FORCE) > argv_array_push(argv, "--prune"); > + else if (prune == PRUNE_UNSET) > + argv_array_push(argv, "--no-prune"); > if (update_head_ok) > argv_array_push(argv, "--update-head-ok"); > if (force) And I think this hunk can go with the suggested change. > @@ -1007,6 +1027,8 @@ int cmd_fetch(int argc, const char **argv, const char *prefix) > for (i = 1; i < argc; i++) > strbuf_addf(&default_rla, " %s", argv[i]); > > + git_config(git_fetch_config, NULL); > + > argc = parse_options(argc, argv, prefix, > builtin_fetch_options, builtin_fetch_usage, 0); > > diff --git a/remote.c b/remote.c > index 6f57830..e6f2acb 100644 > --- a/remote.c > +++ b/remote.c > @@ -404,6 +404,8 @@ static int handle_config(const char *key, const char *value, void *cb) > remote->skip_default_update = git_config_bool(key, value); > else if (!strcmp(subkey, ".skipfetchall")) > remote->skip_default_update = git_config_bool(key, value); > + else if (!strcmp(subkey, ".prune")) > + remote->prune = git_config_bool(key, value); > else if (!strcmp(subkey, ".url")) { > const char *v; > if (git_config_string(&v, key, value)) > diff --git a/remote.h b/remote.h > index cf56724..4db3498 100644 > --- a/remote.h > +++ b/remote.h > @@ -40,6 +40,7 @@ struct remote { > int fetch_tags; > int skip_default_update; > int mirror; > + int prune; > > const char *receivepack; > const char *uploadpack; > diff --git a/t/t5510-fetch.sh b/t/t5510-fetch.sh > index fde6891..f3d63ca 100755 > --- a/t/t5510-fetch.sh > +++ b/t/t5510-fetch.sh > @@ -497,6 +497,44 @@ test_expect_success "should be able to fetch with duplicate refspecs" ' > ) > ' > > +test_expect_success 'fetch should prune when fetch.prune is true' ' > + cd "$D" && > + git branch somebranch && > + ( > + cd one && > + git fetch && > + test -f .git/refs/remotes/origin/somebranch > + ) && > + git branch -d somebranch && > + ( > + cd one && > + git config fetch.prune true && > + git fetch --no-prune && > + test -f .git/refs/remotes/origin/somebranch && > + git fetch && > + ! test -f .git/refs/remotes/origin/somebranch > + ) > +' OK, "fetch.prune < --no-prune" and "fetch.prune alone" are tested with this. "fetch.prune=no" with "--prune" is not tested. > +test_expect_success 'fetch should prune when remote.<name>.prune is true' ' > + cd "$D" && > + git branch somebranch && > + ( > + cd one && > + git fetch && > + test -f .git/refs/remotes/origin/somebranch Depending on the success/failure of the previous test, we do not know what value fetch.prune is set in this repository. What are we testing here? By using "test_unconfig" to clear the variables you care about before starting each test, you would make it clear what exactly you are testing. There are at least 9 combinations of settings we should be testing. A naive matrix: fetch.prune set to false or not set, set to true remote.origin.prune set to false or not set, set to true command line --no-prune, --prune, (neither) will give us 12 combinations (for completeness, you may want to test fetch.prune that is not set at all and fetch.prune explicitly set to false separately, but let's not go overboard), but we presumably have been testing cases where neither fetch.prune or remote.*.prune is set, so we would need to only test cases where at least one of the configuration variables is set (that would make 3 cases), multiplied with the command line combinations. > + ) && > + git branch -d somebranch && > + ( > + cd one && > + git config remote.origin.prune true && > + git fetch --no-prune && > + test -f .git/refs/remotes/origin/somebranch && > + git fetch && > + ! test -f .git/refs/remotes/origin/somebranch > + ) > +' > + > test_expect_success 'all boundary commits are excluded' ' > test_commit base && > test_commit oneside && ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [RFC/PATCH] fetch: make --prune configurable 2013-07-08 18:36 ` Junio C Hamano @ 2013-07-12 22:38 ` Junio C Hamano 0 siblings, 0 replies; 5+ messages in thread From: Junio C Hamano @ 2013-07-12 22:38 UTC (permalink / raw) To: Michael Schubert; +Cc: git Here is my previous review comments in a squashable patch form. The result seems to pass all 27 combinations (fetch.prune, remote.*.prune and command line all are tristate yes/no/unspecified). Without the fix-up in *.c files, three combinations seem to fail. Documentation/config.txt | 3 +- builtin/fetch.c | 41 +++++++++------- remote.c | 1 + t/t5510-fetch.sh | 118 ++++++++++++++++++++++++++++++++--------------- 4 files changed, 108 insertions(+), 55 deletions(-) diff --git a/Documentation/config.txt b/Documentation/config.txt index fc39f3a..e4ce7c4 100644 --- a/Documentation/config.txt +++ b/Documentation/config.txt @@ -1051,7 +1051,7 @@ fetch.unpackLimit:: fetch.prune:: If true, fetch will automatically behave as if the `--prune` - option was given on the command line. + option was given on the command line. See also `remote.<name>.prune`. format.attach:: Enable multipart/mixed attachments as the default for @@ -1992,6 +1992,7 @@ remote.<name>.prune:: When set to true, fetching from this remote by default will also remove any remote-tracking branches which no longer exist on the remote (as if the `--prune` option was give on the command line). + Overrides `fetch.prune` settings, if any. remotes.<group>:: The list of remotes which are fetched by "git remote update diff --git a/builtin/fetch.c b/builtin/fetch.c index 082450b..08ab948 100644 --- a/builtin/fetch.c +++ b/builtin/fetch.c @@ -30,13 +30,10 @@ enum { TAGS_SET = 2 }; -enum { - PRUNE_UNSET = 0, - PRUNE_DEFAULT = 1, - PRUNE_FORCE = 2 -}; +static int fetch_prune_config = -1; /* unspecified */ +static int prune = -1; /* unspecified */ +#define PRUNE_BY_DEFAULT 0 /* do we prune by default? */ -static int prune = PRUNE_DEFAULT; static int all, append, dry_run, force, keep, multiple, update_head_ok, verbosity; static int progress = -1, recurse_submodules = RECURSE_SUBMODULES_DEFAULT; static int tags = TAGS_DEFAULT, unshallow; @@ -64,12 +61,10 @@ static int option_parse_recurse_submodules(const struct option *opt, static int git_fetch_config(const char *k, const char *v, void *cb) { if (!strcmp(k, "fetch.prune")) { - int boolval = git_config_bool(k, v); - if (boolval) - prune = PRUNE_FORCE; + fetch_prune_config = git_config_bool(k, v); return 0; } - return git_default_config(k, v, cb); + return 0; } static struct option builtin_fetch_options[] = { @@ -87,8 +82,8 @@ static struct option builtin_fetch_options[] = { N_("fetch all tags and associated objects"), TAGS_SET), OPT_SET_INT('n', NULL, &tags, N_("do not fetch all tags (--no-tags)"), TAGS_UNSET), - OPT_BOOLEAN('p', "prune", &prune, - N_("prune remote-tracking branches no longer on remote")), + OPT_BOOL('p', "prune", &prune, + N_("prune remote-tracking branches no longer on remote")), { OPTION_CALLBACK, 0, "recurse-submodules", NULL, N_("on-demand"), N_("control recursive fetching of submodules"), PARSE_OPT_OPTARG, option_parse_recurse_submodules }, @@ -756,8 +751,11 @@ static int do_fetch(struct transport *transport, free_refs(ref_map); return 1; } - if (prune == PRUNE_FORCE || (transport->remote->prune && prune)) { - /* If --tags was specified, pretend the user gave us the canonical tags refspec */ + if (prune) { + /* + * If --tags was specified, pretend that the user gave us + * the canonical tags refspec + */ if (tags == TAGS_SET) { const char *tags_str = "refs/tags/*:refs/tags/*"; struct refspec *tags_refspec, *refspec; @@ -866,10 +864,8 @@ static void add_options_to_argv(struct argv_array *argv) { if (dry_run) argv_array_push(argv, "--dry-run"); - if (prune == PRUNE_FORCE) + if (prune > 0) argv_array_push(argv, "--prune"); - else if (prune == PRUNE_UNSET) - argv_array_push(argv, "--no-prune"); if (update_head_ok) argv_array_push(argv, "--update-head-ok"); if (force) @@ -936,6 +932,17 @@ static int fetch_one(struct remote *remote, int argc, const char **argv) "remote name from which new revisions should be fetched.")); transport = transport_get(remote, NULL); + + if (prune < 0) { + /* no command line request */ + if (0 <= transport->remote->prune) + prune = transport->remote->prune; + else if (0 <= fetch_prune_config) + prune = fetch_prune_config; + else + prune = PRUNE_BY_DEFAULT; + } + transport_set_verbosity(transport, verbosity, progress); if (upload_pack) set_option(TRANS_OPT_UPLOADPACK, upload_pack); diff --git a/remote.c b/remote.c index d0ddbef..89be211 100644 --- a/remote.c +++ b/remote.c @@ -148,6 +148,7 @@ static struct remote *make_remote(const char *name, int len) } ret = xcalloc(1, sizeof(struct remote)); + ret->prune = -1; /* unspecified */ ALLOC_GROW(remotes, remotes_nr + 1, remotes_alloc); remotes[remotes_nr++] = ret; if (len) diff --git a/t/t5510-fetch.sh b/t/t5510-fetch.sh index 33fe3d5..019535f 100755 --- a/t/t5510-fetch.sh +++ b/t/t5510-fetch.sh @@ -471,43 +471,87 @@ test_expect_success "should be able to fetch with duplicate refspecs" ' ) ' -test_expect_success 'fetch should prune when fetch.prune is true' ' - cd "$D" && - git branch somebranch && - ( - cd one && - git fetch && - test -f .git/refs/remotes/origin/somebranch - ) && - git branch -d somebranch && - ( - cd one && - git config fetch.prune true && - git fetch --no-prune && - test -f .git/refs/remotes/origin/somebranch && - git fetch && - ! test -f .git/refs/remotes/origin/somebranch - ) -' - -test_expect_success 'fetch should prune when remote.<name>.prune is true' ' - cd "$D" && - git branch somebranch && - ( - cd one && - git fetch && - test -f .git/refs/remotes/origin/somebranch - ) && - git branch -d somebranch && - ( - cd one && - git config remote.origin.prune true && - git fetch --no-prune && - test -f .git/refs/remotes/origin/somebranch && - git fetch && - ! test -f .git/refs/remotes/origin/somebranch - ) -' +# configured prune tests + +set_config_tristate () { + # var=$1 val=$2 + case "$2" in + unset) test_unconfig "$1" ;; + *) git config "$1" "$2" ;; + esac +} + +test_configured_prune () { + fetch_prune=$1 remote_origin_prune=$2 cmdline=$3 expected=$4 + + test_expect_success "prune fetch.prune=$1 remote.origin.prune=$2${3:+ $3}; $4" ' + # make sure a newbranch is there in . and also in one + git branch -f newbranch && + ( + cd one && + test_unconfig fetch.prune && + test_unconfig remote.origin.prune && + git fetch && + git rev-parse --verify refs/remotes/origin/newbranch + ) + + # now remove it + git branch -d newbranch && + + # then test + ( + cd one && + set_config_tristate fetch.prune $fetch_prune && + set_config_tristate remote.origin.prune $remote_origin_prune && + + git fetch $cmdline && + case "$expected" in + pruned) + test_must_fail git rev-parse --verify refs/remotes/origin/newbranch + ;; + kept) + git rev-parse --verify refs/remotes/origin/newbranch + ;; + esac + ) + ' +} + +test_configured_prune unset unset "" kept +test_configured_prune unset unset "--no-prune" kept +test_configured_prune unset unset "--prune" pruned + +test_configured_prune false unset "" kept +test_configured_prune false unset "--no-prune" kept +test_configured_prune false unset "--prune" pruned + +test_configured_prune true unset "" pruned +test_configured_prune true unset "--prune" pruned +test_configured_prune true unset "--no-prune" kept + +test_configured_prune unset false "" kept +test_configured_prune unset false "--no-prune" kept +test_configured_prune unset false "--prune" pruned + +test_configured_prune false false "" kept +test_configured_prune false false "--no-prune" kept +test_configured_prune false false "--prune" pruned + +test_configured_prune true false "" kept +test_configured_prune true false "--prune" pruned +test_configured_prune true false "--no-prune" kept + +test_configured_prune unset true "" pruned +test_configured_prune unset true "--no-prune" kept +test_configured_prune unset true "--prune" pruned + +test_configured_prune false true "" pruned +test_configured_prune false true "--no-prune" kept +test_configured_prune false true "--prune" pruned + +test_configured_prune true true "" pruned +test_configured_prune true true "--prune" pruned +test_configured_prune true true "--no-prune" kept test_expect_success 'all boundary commits are excluded' ' test_commit base && -- 1.8.3.2-941-gda9c3c8 ^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [RFC/PATCH] fetch: make --prune configurable 2013-07-08 12:56 [RFC/PATCH] fetch: make --prune configurable Michael Schubert 2013-07-08 18:36 ` Junio C Hamano @ 2013-07-08 19:01 ` John Keeping 2013-07-09 3:50 ` Jeff King 2 siblings, 0 replies; 5+ messages in thread From: John Keeping @ 2013-07-08 19:01 UTC (permalink / raw) To: Michael Schubert; +Cc: git On Mon, Jul 08, 2013 at 02:56:57PM +0200, Michael Schubert wrote: > $gmane/201715 brought up the idea to fetch --prune by default. > Since --prune is a "potentially destructive operation" (Git doesn't > keep reflogs for deleted references yet), we don't want to prune > without users consent. > > To accommodate users who want to either prune always or when fetching > from a particular remote, add two new configuration variables > "fetch.prune" and "remote.<name>.prune": > > - "fetch.prune" allows to enable prune for all fetch operations. > > - "remote.<name>.prune" allows to change the behaviour per remote. Should this be "remote.<name>.pruneFetch"? I'd quite like to be able to configure --prune for git-push as well (I just haven't got around to actually doing anything about it yet...) and it might be better to be explicit in the remote.<name> section from the start. I'm not sure it's necessary since we already have "remote" and "pushremote" so we could have "prune" and "pushprune" but perhaps it's worth considering. ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [RFC/PATCH] fetch: make --prune configurable 2013-07-08 12:56 [RFC/PATCH] fetch: make --prune configurable Michael Schubert 2013-07-08 18:36 ` Junio C Hamano 2013-07-08 19:01 ` John Keeping @ 2013-07-09 3:50 ` Jeff King 2 siblings, 0 replies; 5+ messages in thread From: Jeff King @ 2013-07-09 3:50 UTC (permalink / raw) To: Michael Schubert; +Cc: git On Mon, Jul 08, 2013 at 02:56:57PM +0200, Michael Schubert wrote: > $gmane/201715 brought up the idea to fetch --prune by default. > Since --prune is a "potentially destructive operation" (Git doesn't > keep reflogs for deleted references yet), we don't want to prune > without users consent. > > To accommodate users who want to either prune always or when fetching > from a particular remote, add two new configuration variables > "fetch.prune" and "remote.<name>.prune": > > - "fetch.prune" allows to enable prune for all fetch operations. > > - "remote.<name>.prune" allows to change the behaviour per remote. Thanks. As the person who brought up the destructive nature of --prune in the thread you mentioned, I have no problem at all with doing something like this, where the user gets to make the choice. And it is even a good building block if we later do have deleted-branch reflogs; we can just flip the default from "off" to "on". In the meantime, I don't know if it is worth mentioning in the documentation that the remote branches are hard to get back. On the one hand, it is the (or at least a) reason why the default is not "on". But it is also far from the only place refs get deleted, so I don't know if it is worth calling attention to it specifically. -Peff ^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2013-07-12 22:39 UTC | newest] Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2013-07-08 12:56 [RFC/PATCH] fetch: make --prune configurable Michael Schubert 2013-07-08 18:36 ` Junio C Hamano 2013-07-12 22:38 ` Junio C Hamano 2013-07-08 19:01 ` John Keeping 2013-07-09 3:50 ` Jeff King
Code repositories for project(s) associated with this public inbox https://80x24.org/mirrors/git.git This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).