diff --git a/Documentation/git-fast-export.txt b/Documentation/git-fast-export.txt index e809bb3f18..c63f109f1d 100644 --- a/Documentation/git-fast-export.txt +++ b/Documentation/git-fast-export.txt @@ -125,6 +125,12 @@ by keeping the marks the same across runs. the output stream, with the original refname, a space, and its anonymized counterpart. See the section on `ANONYMIZING` below. +--dump-anonymized-paths=:: + Output the mapping of real paths to anonymized paths to . + The output will contain one line per path that appears in the + output stream, with the original path, a space, and its + anonymized counterpart. See the section on `ANONYMIZING` below. + --reference-excluded-parents:: By default, running a command such as `git fast-export master~5..master` will not include the commit master{tilde}5 @@ -261,6 +267,10 @@ refs/tags/v2.0 refs/tags/ref50 which tells you that `git rev-list ref31..ref50` may produce the same bug in the re-imported anonymous repository. +Likewise, `--dump-anonymized-paths` may be useful for a bug that +involves pathspecs. E.g., `git rev-list v1.0..v2.0 -- foo.c` requires +knowing the path corresponding to `foo.c` in the result. + LIMITATIONS ----------- diff --git a/builtin/fast-export.c b/builtin/fast-export.c index cd0174d514..ed1f8daa7f 100644 --- a/builtin/fast-export.c +++ b/builtin/fast-export.c @@ -47,6 +47,7 @@ static struct string_list tag_refs = STRING_LIST_INIT_NODUP; static struct refspec refspecs = REFSPEC_INIT_FETCH; static int anonymize; static FILE *anonymized_refnames_handle; +static FILE *anonymized_paths_handle; static struct revision_sources revision_sources; static int parse_opt_signed_tag_mode(const struct option *opt, @@ -211,6 +212,9 @@ static void anonymize_path(struct strbuf *out, const char *path, struct hashmap *map, void *(*generate)(const void *, size_t *)) { + static struct seen_set seen; + const char *full_path = path; + while (*path) { const char *end_of_component = strchrnul(path, '/'); size_t len = end_of_component - path; @@ -220,6 +224,8 @@ static void anonymize_path(struct strbuf *out, const char *path, if (*path) strbuf_addch(out, *path++); } + + maybe_dump_anon(anonymized_paths_handle, &seen, full_path, out->buf); } static inline void *mark_to_ptr(uint32_t mark) @@ -1170,6 +1176,7 @@ int cmd_fast_export(int argc, const char **argv, const char *prefix) *import_filename = NULL, *import_filename_if_exists = NULL; const char *anonymized_refnames_file = NULL; + const char *anonymized_paths_file = NULL; uint32_t lastimportid; struct string_list refspecs_list = STRING_LIST_INIT_NODUP; struct string_list paths_of_changed_objects = STRING_LIST_INIT_DUP; @@ -1206,6 +1213,9 @@ int cmd_fast_export(int argc, const char **argv, const char *prefix) OPT_STRING(0, "dump-anonymized-refnames", &anonymized_refnames_file, N_("file"), N_("output anonymized refname mapping to ")), + OPT_STRING(0, "dump-anonymized-paths", + &anonymized_paths_file, N_("file"), + N_("output anonymized path mapping to ")), OPT_BOOL(0, "reference-excluded-parents", &reference_excluded_commits, N_("Reference parents which are not in fast-export stream by object id")), OPT_BOOL(0, "show-original-ids", &show_original_ids, @@ -1244,6 +1254,8 @@ int cmd_fast_export(int argc, const char **argv, const char *prefix) if (anonymized_refnames_file) anonymized_refnames_handle = xfopen(anonymized_refnames_file, "w"); + if (anonymized_paths_file) + anonymized_paths_handle = xfopen(anonymized_paths_file, "w"); if (use_done_feature) printf("feature done\n"); diff --git a/t/t9351-fast-export-anonymize.sh b/t/t9351-fast-export-anonymize.sh index 88847b0f60..3607b9b972 100755 --- a/t/t9351-fast-export-anonymize.sh +++ b/t/t9351-fast-export-anonymize.sh @@ -53,6 +53,14 @@ test_expect_success 'refname mapping can be dumped' ' grep "^refs/heads/other refs/heads/" refs.out ' +test_expect_success 'path mapping can be dumped' ' + git fast-export --anonymize --all \ + --dump-anonymized-paths=paths.out >/dev/null && + # do not assume a particular anonymization scheme or order; + # just sanity check that a sample line looks sensible. + grep "^foo " paths.out +' + # NOTE: we chdir to the new, anonymized repository # after this. All further tests should assume this. test_expect_success 'import stream to new repository' '