Re: [PATCH v5 15/16] remote-svn: add marks-file regeneration
From: Junio C Hamano <hidden>
Date: 2016-06-15 22:54:32
Florian Achleitner [off-list ref] writes:
quoted hunk
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 <redacted> Signed-off-by: Junio C Hamano <redacted> --- remote-testsvn.c | 63 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+)diff --git a/remote-testsvn.c b/remote-testsvn.c index e90d221..2c0dc99 100644 --- a/remote-testsvn.c +++ b/remote-testsvn.c@@ -86,6 +86,68 @@ 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, ¬e)) + 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() { + int ret; + FILE *marksfile; + marksfile = fopen(marksfilename, "w+");
Where does marksfilename come from? Should this be
static void regenerate_marks(const char *marksfilename)
{
+ 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;
+ char *line = NULL;
+ size_t linelen = 0;
+ struct strbuf sb = 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);
Huh? regenerate_marks() take a NULL pointer of type "FILE *"?
I think you meant something like:
init_notes(NULL, notes_ref, NULL, 0);
marksfile = fopen(marksfilename, "r");
if (!marksfile) {
regenerate_marks(marksfilename);
marksfile = fopen(marksfilename, "r");
if (!marksfile)
die("cannot read marks file!");
} else {
...
Also there is another call to regenerate_marks() without any
argument. Has this even been compile-tested?