remote-svn: add marks-file regeneration

fast-import mark files are stored outside the object database and are
therefore not fetched and can be lost somehow else.  marks provide a
svn revision --> git sha1 mapping, while the notes that are attached
to each commit when it is imported provide a git sha1 --> svn revision
mapping.

If the marks file is not available or not plausible, regenerate it by
walking through the notes tree.  , i.e.  The plausibility check tests
if the highest revision in the marks file matches the revision of the
top ref. It doesn't ensure that the mark file is completely correct.
This could only be done with an effort equal to unconditional
regeneration.

Signed-off-by: Florian Achleitner <florian.achleitner.2.6.31@gmail.com>
Acked-by: David Michael Barr <b@rr-dav.id.au>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
Florian Achleitner 2012-09-19 17:21:29 +02:00 committed by Junio C Hamano
parent 16a7185447
commit 5bfc76b5b2

View File

@ -96,6 +96,76 @@ static int parse_rev_note(const char *msg, struct rev_note *res)
return 0;
}
static int note2mark_cb(const unsigned char *object_sha1,
const unsigned char *note_sha1, char *note_path,
void *cb_data)
{
FILE *file = (FILE *)cb_data;
char *msg;
unsigned long msglen;
enum object_type type;
struct rev_note note;
if (!(msg = read_sha1_file(note_sha1, &type, &msglen)) ||
!msglen || type != OBJ_BLOB) {
free(msg);
return 1;
}
if (parse_rev_note(msg, &note))
return 2;
if (fprintf(file, ":%d %s\n", note.rev_nr, sha1_to_hex(object_sha1)) < 1)
return 3;
return 0;
}
static void regenerate_marks(void)
{
int ret;
FILE *marksfile = fopen(marksfilename, "w+");
if (!marksfile)
die_errno("Couldn't create mark file %s.", marksfilename);
ret = for_each_note(NULL, 0, note2mark_cb, marksfile);
if (ret)
die("Regeneration of marks failed, returned %d.", ret);
fclose(marksfile);
}
static void check_or_regenerate_marks(int latestrev)
{
FILE *marksfile;
struct strbuf sb = STRBUF_INIT;
struct strbuf line = STRBUF_INIT;
int found = 0;
if (latestrev < 1)
return;
init_notes(NULL, notes_ref, NULL, 0);
marksfile = fopen(marksfilename, "r");
if (!marksfile) {
regenerate_marks();
marksfile = fopen(marksfilename, "r");
if (!marksfile)
die_errno("cannot read marks file %s!", marksfilename);
fclose(marksfile);
} else {
strbuf_addf(&sb, ":%d ", latestrev);
while (strbuf_getline(&line, marksfile, '\n') != EOF) {
if (!prefixcmp(line.buf, sb.buf)) {
found++;
break;
}
}
fclose(marksfile);
if (!found)
regenerate_marks();
}
free_notes(NULL);
strbuf_release(&sb);
strbuf_release(&line);
}
static int cmd_import(const char *line)
{
int code;
@ -121,6 +191,7 @@ static int cmd_import(const char *line)
free(note_msg);
}
}
check_or_regenerate_marks(startrev - 1);
if (dump_from_file) {
dumpin_fd = open(url, O_RDONLY);