Skip to content

Commit 5bfc76b

Browse files
flyingflogitster
authored andcommitted
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 <[email protected]> Acked-by: David Michael Barr <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 16a7185 commit 5bfc76b

File tree

1 file changed

+71
-0
lines changed

1 file changed

+71
-0
lines changed

remote-testsvn.c

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,76 @@ static int parse_rev_note(const char *msg, struct rev_note *res)
9696
return 0;
9797
}
9898

99+
static int note2mark_cb(const unsigned char *object_sha1,
100+
const unsigned char *note_sha1, char *note_path,
101+
void *cb_data)
102+
{
103+
FILE *file = (FILE *)cb_data;
104+
char *msg;
105+
unsigned long msglen;
106+
enum object_type type;
107+
struct rev_note note;
108+
109+
if (!(msg = read_sha1_file(note_sha1, &type, &msglen)) ||
110+
!msglen || type != OBJ_BLOB) {
111+
free(msg);
112+
return 1;
113+
}
114+
if (parse_rev_note(msg, &note))
115+
return 2;
116+
if (fprintf(file, ":%d %s\n", note.rev_nr, sha1_to_hex(object_sha1)) < 1)
117+
return 3;
118+
return 0;
119+
}
120+
121+
static void regenerate_marks(void)
122+
{
123+
int ret;
124+
FILE *marksfile = fopen(marksfilename, "w+");
125+
126+
if (!marksfile)
127+
die_errno("Couldn't create mark file %s.", marksfilename);
128+
ret = for_each_note(NULL, 0, note2mark_cb, marksfile);
129+
if (ret)
130+
die("Regeneration of marks failed, returned %d.", ret);
131+
fclose(marksfile);
132+
}
133+
134+
static void check_or_regenerate_marks(int latestrev)
135+
{
136+
FILE *marksfile;
137+
struct strbuf sb = STRBUF_INIT;
138+
struct strbuf line = STRBUF_INIT;
139+
int found = 0;
140+
141+
if (latestrev < 1)
142+
return;
143+
144+
init_notes(NULL, notes_ref, NULL, 0);
145+
marksfile = fopen(marksfilename, "r");
146+
if (!marksfile) {
147+
regenerate_marks();
148+
marksfile = fopen(marksfilename, "r");
149+
if (!marksfile)
150+
die_errno("cannot read marks file %s!", marksfilename);
151+
fclose(marksfile);
152+
} else {
153+
strbuf_addf(&sb, ":%d ", latestrev);
154+
while (strbuf_getline(&line, marksfile, '\n') != EOF) {
155+
if (!prefixcmp(line.buf, sb.buf)) {
156+
found++;
157+
break;
158+
}
159+
}
160+
fclose(marksfile);
161+
if (!found)
162+
regenerate_marks();
163+
}
164+
free_notes(NULL);
165+
strbuf_release(&sb);
166+
strbuf_release(&line);
167+
}
168+
99169
static int cmd_import(const char *line)
100170
{
101171
int code;
@@ -121,6 +191,7 @@ static int cmd_import(const char *line)
121191
free(note_msg);
122192
}
123193
}
194+
check_or_regenerate_marks(startrev - 1);
124195

125196
if (dump_from_file) {
126197
dumpin_fd = open(url, O_RDONLY);

0 commit comments

Comments
 (0)