[PATCH 3/3] repack: introduce --force to force filtering

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



A previous commit introduced --filter=<filter-spec>, but disallowed it
when stdin doesn't refer to a terminal, and asked the user when it does
refer to a terminal. This is because this option is dangerous as it
could lose data and corrupt the repo.

In some cases people might want to run this command automatically when
stdin desn't refer to a terminal or when no question should be asked.
Let's introduce --force for this purpose.

Unfortunately, we cannot use OPT__FORCE() to implement this because -f is
already a repack option (to pass --no-reuse-delta to git-pack-objects),
so we use OPT_BOOL() instead.

This is also a good time to test that --filter works properly as it
wasn't done in the previous commit that introduced --filter.

Signed-off-by: Christian Couder <chriscool@xxxxxxxxxxxxx>
---
 Documentation/git-repack.txt | 12 +++++++++++-
 builtin/repack.c             |  7 +++++--
 t/t7700-repack.sh            | 15 +++++++++++++++
 3 files changed, 31 insertions(+), 3 deletions(-)

diff --git a/Documentation/git-repack.txt b/Documentation/git-repack.txt
index 230f176e10..574f569fbe 100644
--- a/Documentation/git-repack.txt
+++ b/Documentation/git-repack.txt
@@ -142,7 +142,17 @@ depth is 4095.
 	packfile. WARNING: this could easily corrupt the current repo
 	and lose data if ANY of the omitted objects hasn't been
 	already pushed to a remote. See linkgit:git-rev-list[1] for
-	valid `<filter-spec>` forms.
+	valid `<filter-spec>` forms. See also `--force` option below.
+
+--force::
+	By default when using `--filter=<filter-spec>` and stdin
+	refers to a terminal, the user will be warned and asked if the
+	filtering repack should really be launched. This tries to
+	avoid possible data loss and repo corruption. See `--filter`
+	option above. If stdin doesn't refer to a terminal, the repack
+	is aborted. `--force` allows the repack to go on anyway when
+	stdin doesn't refer to a terminal or when no question should
+	be asked.
 
 -b::
 --write-bitmap-index::
diff --git a/builtin/repack.c b/builtin/repack.c
index 0a93f38da4..3660dbb7a7 100644
--- a/builtin/repack.c
+++ b/builtin/repack.c
@@ -56,6 +56,7 @@ struct pack_objects_args {
 	int no_reuse_object;
 	int quiet;
 	int local;
+	int force;
 };
 
 static int repack_config(const char *var, const char *value, void *cb)
@@ -793,6 +794,8 @@ int cmd_repack(int argc, const char **argv, const char *prefix)
 				N_("maximum size of each packfile")),
 		OPT_STRING(0, "filter", &po_args.filter, N_("args"),
 				N_("object filtering")),
+		OPT_BOOL(0, "force", &po_args.force,
+				N_("force object filtering")),
 		OPT_BOOL(0, "pack-kept-objects", &pack_kept_objects,
 				N_("repack objects in packs marked with .keep")),
 		OPT_STRING_LIST(0, "keep-pack", &keep_pack_list, N_("name"),
@@ -825,12 +828,12 @@ int cmd_repack(int argc, const char **argv, const char *prefix)
 			die(_("options '%s' and '%s' cannot be used together"), "--cruft", "-k");
 	}
 
-	if (po_args.filter) {
+	if (po_args.filter && !po_args.force) {
 		const char *yesno;
 
 		if (!isatty(STDIN_FILENO))
 			die (_("Repacking with a filter is not allowed "
-			       "yet unless a terminal is used!"));
+			       "unless a terminal is used or --force is passed!"));
 
 		/*
 		 * TRANSLATORS: Make sure to include [y] and [N] in your translation.
diff --git a/t/t7700-repack.sh b/t/t7700-repack.sh
index f8764d1dd9..20727112b5 100755
--- a/t/t7700-repack.sh
+++ b/t/t7700-repack.sh
@@ -242,6 +242,21 @@ test_expect_success 'repacking with a filter is not allowed' '
 	test_i18ngrep "Repacking with a filter is not allowed" actual
 '
 
+test_expect_success 'repacking with a filter works when --force is passed' '
+	test_when_finished "rm -rf server client" &&
+	test_create_repo server &&
+	git -C server config uploadpack.allowFilter true &&
+	git -C server config uploadpack.allowAnySHA1InWant true &&
+	test_commit -C server 1 &&
+	git clone --bare --no-local server client &&
+	git -C client config remote.origin.promisor true &&
+	git -C client rev-list --objects --all --missing=print >objects &&
+	test $(grep "^?" objects | wc -l) = 0 &&
+	git -C client -c repack.writebitmaps=false repack -a -d --filter=blob:none --force &&
+	git -C client rev-list --objects --all --missing=print >objects &&
+	test $(grep "^?" objects | wc -l) = 1
+'
+
 objdir=.git/objects
 midx=$objdir/pack/multi-pack-index
 
-- 
2.38.0.4.g7f9724c7bf.dirty




[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]

  Powered by Linux