From 011c646ee80670b20b6c80d119f288efd60ebd5a Mon Sep 17 00:00:00 2001 From: Elijah Newren Date: Fri, 15 May 2020 23:47:49 -0700 Subject: [PATCH] filter-repo: suggest --no-local when cloning local repos Cloning local repos by default makes a bunch of hardlinks, giving you a non-packed repository, and leading folks to use and suggest --force. That, of course, bypasses the important fresh clone checks to prevent people from accidentally and irrecoverably deleting their non-backed-up data. Let's make it easier for people to avoid (and suggest) that mistake. Signed-off-by: Elijah Newren --- Documentation/git-filter-repo.txt | 4 +++- git-filter-repo | 13 +++++++++++-- t/t9390-filter-repo.sh | 12 ++++++++++++ 3 files changed, 26 insertions(+), 3 deletions(-) diff --git a/Documentation/git-filter-repo.txt b/Documentation/git-filter-repo.txt index b90471b..bc0652b 100644 --- a/Documentation/git-filter-repo.txt +++ b/Documentation/git-filter-repo.txt @@ -277,7 +277,9 @@ Miscellaneous options --force:: -f:: Rewrite history even if the current repo does not look like a fresh - clone. + clone. Note that when cloning repos on a local filesystem, it is + better to pass `--no-local` to git clone than passing `--force` to + git-filter-repo. --partial:: Do a partial history rewrite, resulting in the mixture of old and diff --git a/git-filter-repo b/git-filter-repo index 81cc263..b6323b1 100755 --- a/git-filter-repo +++ b/git-filter-repo @@ -2846,11 +2846,20 @@ class RepoFilter(object): @staticmethod def sanity_check(refs, is_bare): def abort(reason): + try: + cmd = 'git config remote.origin.url' + output = subproc.check_output(cmd.split()).strip() + except subprocess.CalledProcessError as e: + output = None + msg = "" + if os.path.isdir(output): + msg = _("Note: when cloning local repositories, you need to pass\n" + " --no-local to git clone to avoid this issue.\n") raise SystemExit( _("Aborting: Refusing to overwrite repo history since this does not\n" "look like a fresh clone.\n" - " (%s)\n" - "To override, use --force.") % reason) + " (%s)\n%s" + "To override, use --force.") % (reason, msg)) # Make sure repo is fully packed, just like a fresh clone would be. # Note that transfer.unpackLimit defaults to 100, meaning that a diff --git a/t/t9390-filter-repo.sh b/t/t9390-filter-repo.sh index 2db35e0..6085fad 100755 --- a/t/t9390-filter-repo.sh +++ b/t/t9390-filter-repo.sh @@ -1044,6 +1044,18 @@ test_expect_success 'startup sanity checks' ' git update-ref -m funsies refs/remotes/origin/master refs/heads/master~1 && test_must_fail git filter-repo --path numbers 2>../err && test_i18ngrep "refs/heads/master does not match refs/remotes/origin/master" ../err && + rm ../err && + + cd ../ && + git -C analyze_me gc && + echo foobar | git -C analyze_me hash-object -w --stdin && + git clone analyze_me startup_sanity_checks2 && + cd startup_sanity_checks2 && + + echo foobar | git hash-object -w --stdin && + test_must_fail git filter-repo --path numbers 2>../err && + test_i18ngrep "expected freshly packed repo" ../err && + test_i18ngrep "when cloning local repositories" ../err && rm ../err ) '