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 <no-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 <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
Johannes Schindelin 2008-12-20 01:00:27 +01:00 committed by Junio C Hamano
parent 672752470c
commit 4e46a8d62c
3 changed files with 42 additions and 5 deletions

View File

@ -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 incremental bidirectional exporting of the repository by keeping the
marks the same across runs. 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 EXAMPLES
-------- --------

View File

@ -24,6 +24,7 @@ static const char *fast_export_usage[] = {
static int progress; static int progress;
static enum { VERBATIM, WARN, STRIP, ABORT } signed_tag_mode = ABORT; 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, static int parse_opt_signed_tag_mode(const struct option *opt,
const char *arg, int unset) const char *arg, int unset)
@ -297,10 +298,17 @@ static void handle_tag(const char *name, struct tag *tag)
message_size = strlen(message); message_size = strlen(message);
} }
tagger = memmem(buf, message ? message - buf : size, "\ntagger ", 8); tagger = memmem(buf, message ? message - buf : size, "\ntagger ", 8);
if (!tagger) if (!tagger) {
die ("No tagger for tag %s", sha1_to_hex(tag->object.sha1)); if (fake_missing_tagger)
tagger = "tagger Unspecified Tagger "
"<unspecified-tagger> 0 +0000";
else
tagger = "";
tagger_end = tagger + strlen(tagger);
} else {
tagger++; tagger++;
tagger_end = strchrnul(tagger, '\n'); tagger_end = strchrnul(tagger, '\n');
}
/* handle signed tags */ /* handle signed tags */
if (message) { if (message) {
@ -326,9 +334,10 @@ static void handle_tag(const char *name, struct tag *tag)
if (!prefixcmp(name, "refs/tags/")) if (!prefixcmp(name, "refs/tags/"))
name += 10; 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), name, get_object_mark(tag->tagged),
(int)(tagger_end - tagger), tagger, (int)(tagger_end - tagger), tagger,
tagger == tagger_end ? "" : "\n",
(int)message_size, (int)message_size, message ? message : ""); (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"), "Dump marks to this file"),
OPT_STRING(0, "import-marks", &import_filename, "FILE", OPT_STRING(0, "import-marks", &import_filename, "FILE",
"Import marks from this file"), "Import marks from this file"),
OPT_BOOLEAN(0, "fake-missing-tagger", &fake_missing_tagger,
"Fake a tagger when tags lack one"),
OPT_END() OPT_END()
}; };

View File

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