From 89f9fbbb6d30bd7f75d655bd558e12eaa719e6dc Mon Sep 17 00:00:00 2001 From: Elijah Newren Date: Wed, 29 May 2019 13:11:55 -0700 Subject: [PATCH] filter-repo: partial repo filtering considerations Fix a few issues and add a token testcase for partial repo filtering. Add a note about how I think this is not a particularly interesting or core usecase for filter-repo, even if I have put some good effort into the fast-export side to ensure it worked. If there is a core usecase that can be addressed without causing usability problems (particularly the "don't mix old and new history" edict for normal rewrites), then I'll be happy to add more testcases, document it better, etc. Signed-off-by: Elijah Newren --- README.md | 12 ++++++++++++ git-filter-repo | 6 +++--- t/t9390-filter-repo.sh | 17 +++++++++++++++++ 3 files changed, 32 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index f2bd191..c2580e5 100644 --- a/README.md +++ b/README.md @@ -953,6 +953,18 @@ the user when it detects an issue: such as `-M` or `-C` would break assumptions used in other places of filter-repo. + * Partial-repo filtering does not mesh well with filter-repo's "avoid + mixing old and new history" design. filter-repo has some capability in + this area but it is undocumented, mostly untested, and may require + multiple non-obvious flags to be set to make sane use of it. While + there might be valid usecases for partial-repo filtering, the only ones + I've run into in the wild are sidestepping filter-branch's insanely + slow execution on commits that would not be changed by the filters in + question anyway (which is largely irrelevant since filter-repo is + multiple orders of magnitude faster), or to do operations better suited + to git-rebase(1) and which rebase grew special options for years ago + (e.g. the `--signoff` option). + ### Comments on reversibility Some people are interested in reversibility of of a rewrite; e.g. rewrite diff --git a/git-filter-repo b/git-filter-repo index f8f8fc1..ea76ad3 100755 --- a/git-filter-repo +++ b/git-filter-repo @@ -1521,8 +1521,8 @@ class FilteringOptions(object): "Will not modify your repo.")) refs = parser.add_argument_group(title=_("Git References")) - refs.add_argument('--refs', action='store_const', const=['--all'], - default=['--all'], help=argparse.SUPPRESS) + refs.add_argument('--refs', nargs='*', default=['--all'], + help=argparse.SUPPRESS) path = parser.add_argument_group(title=_("Filtering based on paths " "(see also --filename-callback)")) @@ -3159,7 +3159,7 @@ class RepoFilter(object): location = ['-C', self._args.source] if self._args.source else [] fep_cmd = ['git'] + location + ['fast-export', '--show-original-ids', '--signed-tags=strip', '--tag-of-filtered-object=rewrite', - '--fake-missing-tagger' + '--fake-missing-tagger', '--reference-excluded-parents' ] + extra_flags + self._args.refs self._fep = subprocess.Popen(fep_cmd, bufsize=-1, stdout=subprocess.PIPE) self._input = self._fep.stdout diff --git a/t/t9390-filter-repo.sh b/t/t9390-filter-repo.sh index e97f128..2c6b861 100755 --- a/t/t9390-filter-repo.sh +++ b/t/t9390-filter-repo.sh @@ -1025,6 +1025,23 @@ test_expect_success '--target' ' test 2 = $(git -C target rev-list --count master) ' +test_expect_success '--refs' ' + git init refs && + ( + cd refs && + git checkout -b other && + echo hello >world && + git add world && + git commit -m init + ) && + git -C refs rev-parse other >refs/expect && + git -C analyze_me rev-parse master >refs/expect && + git filter-repo --source analyze_me --target refs --refs master --force && + git -C refs rev-parse other >refs/actual && + git -C refs rev-parse master >refs/actual && + test_cmp refs/expect refs/actual +' + test_expect_success 'reset to specific refs' ' test_create_repo reset_to_specific_refs && (