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 <newren@gmail.com>
This commit is contained in:
Elijah Newren 2019-05-29 13:11:55 -07:00
parent 1a887c5c13
commit 89f9fbbb6d
3 changed files with 32 additions and 3 deletions

View File

@ -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

View File

@ -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

View File

@ -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 &&
(