Skip to content

Commit

Permalink
fast-export: deal with tag objects that do not have a tagger
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Johannes Schindelin authored and Junio C Hamano committed Dec 20, 2008
1 parent 6727524 commit 4e46a8d
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 5 deletions.
6 changes: 6 additions & 0 deletions Documentation/git-fast-export.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
--------
Expand Down
21 changes: 16 additions & 5 deletions builtin-fast-export.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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 "
"<unspecified-tagger> 0 +0000";
else
tagger = "";
tagger_end = tagger + strlen(tagger);
} else {
tagger++;
tagger_end = strchrnul(tagger, '\n');
}

/* handle signed tags */
if (message) {
Expand All @@ -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 : "");
}

Expand Down Expand Up @@ -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()
};

Expand Down
20 changes: 20 additions & 0 deletions t/t9301-fast-export.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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

0 comments on commit 4e46a8d

Please sign in to comment.