git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH/RFC v3 15/16] remote-svn: add marks-file regeneration.

From
Florian Achleitner <florian.achleitner.2.6.31@gmail.com>
Date
Aug 14, 2012, 19:13 UTC
Message-ID
<1344971598-8213-16-git-send-email-florian.achleitner.2.6.31@gmail.com>
In-Reply-To
<1344971598-8213-15-git-send-email-florian.achleitner.2.6.31@gmail.com>

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.

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>
---
 contrib/svn-fe/remote-svn.c |   69 ++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 68 insertions(+), 1 deletion(-)
diff --git a/contrib/svn-fe/remote-svn.c b/contrib/svn-fe/remote-svn.c
index d659a0e..94e5196 100644
--- a/contrib/svn-fe/remote-svn.c
+++ b/contrib/svn-fe/remote-svn.c
@@ -13,7 +13,7 @@ static const char *url;
 static int dump_from_file;
 static const char *private_ref;
 static const char *remote_ref = "refs/heads/master";
-static const char *notes_ref;
+static const char *notes_ref, *marksfilename;
 struct rev_note { unsigned int rev_nr; };
 
 static int cmd_capabilities(const char *line);
@@ -87,6 +87,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, &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() {
+	int ret;
+	FILE *marksfile;
+	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;
+	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);
+	else {
+		strbuf_addf(&sb, ":%d ", latestrev);
+		while (getline(&line, &linelen, marksfile) != -1) {
+			if (!prefixcmp(line, sb.buf)) {
+				found++;
+				break;
+			}
+		}
+		fclose(marksfile);
+		if (!found)
+			regenerate_marks();
+	}
+	free_notes(NULL);
+	strbuf_release(&sb);
+}
+
 static int cmd_import(const char *line)
 {
 	int code;
@@ -112,6 +174,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);
@@ -238,6 +301,9 @@ int main(int argc, const char **argv)
 	strbuf_addf(&buf, "refs/notes/%s/revs", remote->name);
 	notes_ref = strbuf_detach(&buf, NULL);
 
+	strbuf_addf(&buf, "%s/info/fast-import/marks/%s", get_git_dir(), remote->name);
+	marksfilename = strbuf_detach(&buf, NULL);
+
 	while(1) {
 		if (strbuf_getline(&buf, stdin, '\n') == EOF) {
 			if (ferror(stdin))
@@ -254,5 +320,6 @@ int main(int argc, const char **argv)
 	free((void*)url);
 	free((void*)private_ref);
 	free((void*)notes_ref);
+	free((void*)marksfilename);
 	return 0;
 }
-- 
1.7.9.5
Previous: Florian AchleitnerNext: Florian Achleitner
Message 16 of 36 in “GSOC remote-svn”
  1. 00/16 GSOC remote-svnFlorian Achleitner, Aug 14, 2012
  2. 01/16 Implement a remote helper for svn in C.Florian Achleitner, Aug 14, 2012
  3. 02/16 Integrate remote-svn into svn-fe/Makefile.Florian Achleitner, Aug 14, 2012
  4. 03/16 Add svndump_init_fd to allow reading dumps from arbitrary FDs.Florian Achleitner, Aug 14, 2012
  5. 04/16 Connect fast-import to the remote-helper via pipe, adding 'bidi-import' capability.Florian Achleitner, Aug 14, 2012
  6. 05/16 Add documentation for the 'bidi-import' capability of remote-helpers.Florian Achleitner, Aug 14, 2012
  7. 06/16 remote-svn, vcs-svn: Enable fetching to private refs.Florian Achleitner, Aug 14, 2012
  8. 07/16 Add a symlink 'git-remote-svn' in base dir.Florian Achleitner, Aug 14, 2012
  9. 08/16 Allow reading svn dumps from files via file:// urls.Florian Achleitner, Aug 14, 2012
  10. 09/16 vcs-svn: add fast_export_note to create notesFlorian Achleitner, Aug 14, 2012
  11. 10/16 Create a note for every imported commit containing svn metadata.Florian Achleitner, Aug 14, 2012
  12. 11/16 When debug==1, start fast-import with "--stats" instead of "--quiet".Florian Achleitner, Aug 14, 2012
  13. 12/16 remote-svn: add incremental import.Florian Achleitner, Aug 14, 2012
  14. 13/16 Add a svnrdump-simulator replaying a dump file for testing.Florian Achleitner, Aug 14, 2012
  15. 14/16 transport-helper: add import|export-marks to fast-import command line.Florian Achleitner, Aug 14, 2012
  16. 15/16 remote-svn: add marks-file regeneration.Florian Achleitner, Aug 14, 2012
  17. 16/16 Add a test script for remote-svn.Florian Achleitner, Aug 14, 2012
  18. Florian AchleitnerAug 15, 2012
  19. Junio C HamanoAug 15, 2012
  20. Florian AchleitnerAug 15, 2012
  21. Florian AchleitnerAug 15, 2012
  22. Junio C HamanoAug 15, 2012
  23. Junio C HamanoAug 15, 2012
  24. Florian AchleitnerAug 15, 2012
  25. Junio C HamanoAug 14, 2012
  26. Junio C HamanoAug 14, 2012
  27. Florian AchleitnerAug 15, 2012
  28. Junio C HamanoAug 14, 2012
  29. Florian AchleitnerAug 15, 2012
  30. Junio C HamanoAug 15, 2012
  31. Junio C HamanoAug 14, 2012
  32. Junio C HamanoAug 14, 2012
  33. Florian AchleitnerAug 15, 2012
  34. Junio C HamanoAug 14, 2012
  35. Florian AchleitnerAug 15, 2012
  36. David Michael BarrAug 14, 2012

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.