From 4e46a8d62c551e11e21bd04e059e9ae3cdcfd029 Mon Sep 17 00:00:00 2001 From: Johannes Schindelin Date: Sat, 20 Dec 2008 01:00:27 +0100 Subject: [PATCH] fast-export: deal with tag objects that do not have a tagger When no tagger was found (old Git produced tags like this), no "tagger" line is printed (but this is incompatible with the current git fast-import). Alternatively, you can pass the option --fake-missing-tagger, forcing fast-export to fake a tagger Unspecified Tagger with a tag date of the beginning of (Unix) time in the case of a missing tagger, so that fast-import is still able to import the result. Signed-off-by: Johannes Schindelin Signed-off-by: Junio C Hamano --- Documentation/git-fast-export.txt | 6 ++++++ builtin-fast-export.c | 21 ++++++++++++++++----- t/t9301-fast-export.sh | 20 ++++++++++++++++++++ 3 files changed, 42 insertions(+), 5 deletions(-) diff --git a/Documentation/git-fast-export.txt b/Documentation/git-fast-export.txt index b974e2115..539decbeb 100644 --- a/Documentation/git-fast-export.txt +++ b/Documentation/git-fast-export.txt @@ -65,6 +65,12 @@ If the backend uses a similar \--import-marks file, this allows for incremental bidirectional exporting of the repository by keeping the marks the same across runs. +--fake-missing-tagger:: + Some old repositories have tags without a tagger. The + fast-import protocol was pretty strict about that, and did not + allow that. So fake a tagger to be able to fast-import the + output. + EXAMPLES -------- diff --git a/builtin-fast-export.c b/builtin-fast-export.c index 7d5d57ad7..838633808 100644 --- a/builtin-fast-export.c +++ b/builtin-fast-export.c @@ -24,6 +24,7 @@ static const char *fast_export_usage[] = { static int progress; static enum { VERBATIM, WARN, STRIP, ABORT } signed_tag_mode = ABORT; +static int fake_missing_tagger; static int parse_opt_signed_tag_mode(const struct option *opt, const char *arg, int unset) @@ -297,10 +298,17 @@ static void handle_tag(const char *name, struct tag *tag) message_size = strlen(message); } tagger = memmem(buf, message ? message - buf : size, "\ntagger ", 8); - if (!tagger) - die ("No tagger for tag %s", sha1_to_hex(tag->object.sha1)); - tagger++; - tagger_end = strchrnul(tagger, '\n'); + if (!tagger) { + if (fake_missing_tagger) + tagger = "tagger Unspecified Tagger " + " 0 +0000"; + else + tagger = ""; + tagger_end = tagger + strlen(tagger); + } else { + tagger++; + tagger_end = strchrnul(tagger, '\n'); + } /* handle signed tags */ if (message) { @@ -326,9 +334,10 @@ static void handle_tag(const char *name, struct tag *tag) if (!prefixcmp(name, "refs/tags/")) name += 10; - printf("tag %s\nfrom :%d\n%.*s\ndata %d\n%.*s\n", + printf("tag %s\nfrom :%d\n%.*s%sdata %d\n%.*s\n", name, get_object_mark(tag->tagged), (int)(tagger_end - tagger), tagger, + tagger == tagger_end ? "" : "\n", (int)message_size, (int)message_size, message ? message : ""); } @@ -483,6 +492,8 @@ int cmd_fast_export(int argc, const char **argv, const char *prefix) "Dump marks to this file"), OPT_STRING(0, "import-marks", &import_filename, "FILE", "Import marks from this file"), + OPT_BOOLEAN(0, "fake-missing-tagger", &fake_missing_tagger, + "Fake a tagger when tags lack one"), OPT_END() }; diff --git a/t/t9301-fast-export.sh b/t/t9301-fast-export.sh index 638c858dc..3a6509a1c 100755 --- a/t/t9301-fast-export.sh +++ b/t/t9301-fast-export.sh @@ -239,4 +239,24 @@ test_expect_success 'fast-export | fast-import when master is tagged' ' ' +cat > tag-content << EOF +object $(git rev-parse HEAD) +type commit +tag rosten +EOF + +test_expect_success 'cope with tagger-less tags' ' + + TAG=$(git hash-object -t tag -w tag-content) && + git update-ref refs/tags/sonnenschein $TAG && + git fast-export -C -C --signed-tags=strip --all > output && + test $(grep -c "^tag " output) = 4 && + ! grep "Unspecified Tagger" output && + git fast-export -C -C --signed-tags=strip --all \ + --fake-missing-tagger > output && + test $(grep -c "^tag " output) = 4 && + grep "Unspecified Tagger" output + +' + test_done -- 2.30.2