From: Michael Haggerty <mhagger@alum.mit.edu>
To: git@vger.kernel.org
Cc: Junio C Hamano <gitster@pobox.com>,
Michael Haggerty <mhagger@alum.mit.edu>
Subject: [RFC 09/11] remote prune: allow --prune=<pattern> options
Date: Wed, 4 Dec 2013 06:44:48 +0100 [thread overview]
Message-ID: <1386135890-13954-10-git-send-email-mhagger@alum.mit.edu> (raw)
In-Reply-To: <1386135890-13954-1-git-send-email-mhagger@alum.mit.edu>
Allow "--prune=<pattern>" options to be provided to "git remote prune"
to specify which reference namespaces should be pruned. "--prune"
without an argument and "--no-prune" are disallowed here as they make
no sense.
Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
---
Documentation/git-remote.txt | 5 +++-
builtin/remote.c | 67 +++++++++++++++++++++++++++++++-------------
t/t5505-remote.sh | 15 ++++++++++
3 files changed, 66 insertions(+), 21 deletions(-)
diff --git a/Documentation/git-remote.txt b/Documentation/git-remote.txt
index 02e50a9..9cbc986 100644
--- a/Documentation/git-remote.txt
+++ b/Documentation/git-remote.txt
@@ -19,7 +19,7 @@ SYNOPSIS
'git remote set-url --add' [--push] <name> <newurl>
'git remote set-url --delete' [--push] <name> <url>
'git remote' [-v | --verbose] 'show' [-n] <name>...
-'git remote prune' [-n | --dry-run] <name>...
+'git remote prune' [-n | --dry-run] [--prune=<pattern>] <name>...
'git remote' [-v | --verbose] 'update' [-p | --no-prune | --prune[=<pattern>]...]
[(<group> | <remote>)...]
@@ -157,6 +157,9 @@ These stale branches have already been removed from the remote repository
referenced by <name>, but are still locally available in
"remotes/<name>".
+
+With `--prune=<pattern>`, only prune references whose names match
+pattern. This option can be used multiple times.
++
With `--dry-run` option, report what branches will be pruned, but do not
actually prune them.
diff --git a/builtin/remote.c b/builtin/remote.c
index 6aab923..e1d43e2 100644
--- a/builtin/remote.c
+++ b/builtin/remote.c
@@ -15,7 +15,7 @@ static const char * const builtin_remote_usage[] = {
N_("git remote remove <name>"),
N_("git remote set-head <name> (-a | --auto | -d | --delete |<branch>)"),
N_("git remote [-v | --verbose] show [-n] <name>"),
- N_("git remote prune [-n | --dry-run] <name>"),
+ N_("git remote prune [-n | --dry-run] [--prune=<pattern>] <name>"),
N_("git remote [-v | --verbose] update [-p | --prune[=<pattern>] | --no-prune] [(<group> | <remote>)...]"),
N_("git remote set-branches [--add] <name> <branch>..."),
N_("git remote set-url [--push] <name> <newurl> [<oldurl>]"),
@@ -326,10 +326,12 @@ struct ref_states {
int queried;
};
-static int get_ref_states(const struct ref *remote_refs, struct ref_states *states)
+static int get_ref_states(const struct ref *remote_refs,
+ struct ref_states *states,
+ struct prune_option *prune_option)
{
struct ref *fetch_map = NULL, **tail = &fetch_map;
- struct ref *ref, *stale_refs;
+ struct ref *ref;
int i;
for (i = 0; i < states->remote->fetch_refspec_nr; i++)
@@ -346,15 +348,20 @@ static int get_ref_states(const struct ref *remote_refs, struct ref_states *stat
else
string_list_append(&states->tracked, abbrev_branch(ref->name));
}
- stale_refs = get_stale_heads(states->remote->fetch,
- states->remote->fetch_refspec_nr,
- fetch_map, NULL);
- for (ref = stale_refs; ref; ref = ref->next) {
- struct string_list_item *item =
- string_list_append(&states->stale, abbrev_branch(ref->name));
- item->util = xstrdup(ref->name);
+ if (prune_option->prune) {
+ struct ref *stale_refs =
+ get_stale_heads(states->remote->fetch,
+ states->remote->fetch_refspec_nr,
+ fetch_map,
+ &prune_option->prune_patterns);
+
+ for (ref = stale_refs; ref; ref = ref->next) {
+ struct string_list_item *item =
+ string_list_append(&states->stale, abbrev_branch(ref->name));
+ item->util = xstrdup(ref->name);
+ }
+ free_refs(stale_refs);
}
- free_refs(stale_refs);
free_refs(fetch_map);
sort_string_list(&states->new);
@@ -878,8 +885,9 @@ static int append_ref_to_tracked_list(const char *refname,
}
static int get_remote_ref_states(const char *name,
- struct ref_states *states,
- int query)
+ struct ref_states *states, int query,
+ struct prune_option *prune_option,
+ int default_prune)
{
struct transport *transport;
const struct ref *remote_refs;
@@ -897,8 +905,19 @@ static int get_remote_ref_states(const char *name,
transport_disconnect(transport);
states->queried = 1;
- if (query & GET_REF_STATES)
- get_ref_states(remote_refs, states);
+ if (query & GET_REF_STATES) {
+ struct prune_option remote_prune_option =
+ PRUNE_OPTION_INIT;
+
+ remote_prune_option.prune = prune_option->prune;
+ string_list_append_list(&remote_prune_option.prune_patterns,
+ &prune_option->prune_patterns);
+ prune_option_fill(states->remote,
+ &remote_prune_option,
+ default_prune);
+ get_ref_states(remote_refs, states, &remote_prune_option);
+ prune_option_clear(&remote_prune_option);
+ }
if (query & GET_HEAD_NAMES)
get_head_names(remote_refs, states);
if (query & GET_PUSH_REF_STATES)
@@ -1144,6 +1163,7 @@ static int show_all(void)
static int show(int argc, const char **argv)
{
int no_query = 0, result = 0, query_flag = 0;
+ struct prune_option prune_option = PRUNE_OPTION_INIT;
struct option options[] = {
OPT_BOOL('n', NULL, &no_query, N_("do not query remotes")),
OPT_END()
@@ -1152,6 +1172,7 @@ static int show(int argc, const char **argv)
struct string_list info_list = STRING_LIST_INIT_NODUP;
struct show_info info;
+ prune_option.prune = 1;
argc = parse_options(argc, argv, NULL, options, builtin_remote_show_usage,
0);
@@ -1170,7 +1191,7 @@ static int show(int argc, const char **argv)
const char **url;
int url_nr;
- get_remote_ref_states(*argv, &states, query_flag);
+ get_remote_ref_states(*argv, &states, query_flag, &prune_option, 1);
printf_ln(_("* remote %s"), *argv);
printf_ln(_(" Fetch URL: %s"), states.remote->url_nr > 0 ?
@@ -1268,7 +1289,7 @@ static int set_head(int argc, const char **argv)
} else if (opt_a && !opt_d && argc == 1) {
struct ref_states states;
memset(&states, 0, sizeof(states));
- get_remote_ref_states(argv[0], &states, GET_HEAD_NAMES);
+ get_remote_ref_states(argv[0], &states, GET_HEAD_NAMES, NULL, 0);
if (!states.heads.nr)
result |= error(_("Cannot determine remote HEAD"));
else if (states.heads.nr > 1) {
@@ -1303,7 +1324,8 @@ static int set_head(int argc, const char **argv)
return result;
}
-static int prune_remote(const char *remote, int dry_run)
+static int prune_remote(const char *remote, int dry_run,
+ struct prune_option *prune_option)
{
int result = 0, i;
struct ref_states states;
@@ -1312,7 +1334,7 @@ static int prune_remote(const char *remote, int dry_run)
: _(" %s has become dangling!");
memset(&states, 0, sizeof(states));
- get_remote_ref_states(remote, &states, GET_REF_STATES);
+ get_remote_ref_states(remote, &states, GET_REF_STATES, prune_option, 1);
if (states.stale.nr) {
printf_ln(_("Pruning %s"), remote);
@@ -1344,11 +1366,16 @@ static int prune_remote(const char *remote, int dry_run)
static int prune(int argc, const char **argv)
{
int dry_run = 0, result = 0;
+ struct prune_option prune_option = PRUNE_OPTION_INIT;
struct option options[] = {
+ { OPTION_CALLBACK, 0, "prune", &prune_option, N_("pattern"),
+ N_("prune only references whose names match pattern"),
+ PARSE_OPT_NONEG, prune_option_parse },
OPT__DRY_RUN(&dry_run, N_("dry run")),
OPT_END()
};
+ prune_option.prune = 1;
argc = parse_options(argc, argv, NULL, options, builtin_remote_prune_usage,
0);
@@ -1356,7 +1383,7 @@ static int prune(int argc, const char **argv)
usage_with_options(builtin_remote_prune_usage, options);
for (; argc; argc--, argv++)
- result |= prune_remote(*argv, dry_run);
+ result |= prune_remote(*argv, dry_run, &prune_option);
return result;
}
diff --git a/t/t5505-remote.sh b/t/t5505-remote.sh
index 0dffe47..e156174 100755
--- a/t/t5505-remote.sh
+++ b/t/t5505-remote.sh
@@ -243,6 +243,21 @@ test_expect_success 'prune' '
)
'
+test_expect_success 'prune with --prune' '
+ git clone one prune-prune &&
+ (
+ cd prune-prune &&
+ git update-ref refs/remotes/origin/branch1 master &&
+ git update-ref refs/remotes/origin/branch2 master &&
+
+ test_must_fail git remote prune --prune origin &&
+ test_must_fail git remote prune --no-prune origin &&
+ git remote prune --prune="refs/remotes/*1" origin &&
+ test_must_fail git rev-parse origin/branch1 &&
+ git rev-parse origin/branch2
+ )
+'
+
test_expect_success 'set-head --delete' '
(
cd test &&
--
1.8.4.3
next prev parent reply other threads:[~2013-12-04 5:53 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-12-04 5:44 [RFC 00/11] Make reference pruning more configurable Michael Haggerty
2013-12-04 5:44 ` [RFC 01/11] get_stale_heads(): allow limiting to refname patterns Michael Haggerty
2013-12-04 5:44 ` [RFC 02/11] remote.c: add infrastructure for parsing --prune options Michael Haggerty
2013-12-04 12:57 ` Duy Nguyen
2013-12-04 17:04 ` Michael Haggerty
2013-12-04 5:44 ` [RFC 03/11] fetch: use the new functions for handling " Michael Haggerty
2013-12-04 5:44 ` [RFC 04/11] remote: " Michael Haggerty
2013-12-04 5:44 ` [RFC 05/11] remote.c: add infrastructure to handle --prune=<pattern> Michael Haggerty
2013-12-04 5:44 ` [RFC 06/11] fetch --prune: allow refname patterns to be specified Michael Haggerty
2013-12-04 5:44 ` [RFC 07/11] remote update " Michael Haggerty
2013-12-04 5:44 ` [RFC 08/11] string_list_append_list(): new function Michael Haggerty
2013-12-04 5:44 ` Michael Haggerty [this message]
2013-12-04 5:44 ` [RFC 10/11] remote show: allow --prune=<pattern> options Michael Haggerty
2013-12-04 5:44 ` [RFC 11/11] remote: allow prune patterns to be configured Michael Haggerty
2013-12-04 20:25 ` [RFC 00/11] Make reference pruning more configurable Junio C Hamano
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1386135890-13954-10-git-send-email-mhagger@alum.mit.edu \
--to=mhagger@alum.mit.edu \
--cc=git@vger.kernel.org \
--cc=gitster@pobox.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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 NNTP newsgroup(s).