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

[PATCH 08/13] Implement dump_node

From
Ramkumar Ramachandra <artagnon@gmail.com>
Date
Jul 7, 2010, 00:14 UTC
Message-ID
<1278461693-3828-9-git-send-email-artagnon@gmail.com>
In-Reply-To
<1278461693-3828-1-git-send-email-artagnon@gmail.com>

Add a new dump_node function to dump node headers Node-path, Node-kind, Node-action and set the right variables to trigger dumping properties. Copies are also handled appropriately using eb->is_copy, copyfrom_path, copyfrom_rev informatino from the caller. Also add a related dump_props helper function that uses write_hash_to_stringbuf to dump properties.

Signed-off-by: Ramkumar Ramachandra <artagnon@gmail.com>
---
 dump_editor.c |  132 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 dumpr_util.c  |   48 +++++++++++++++++++++
 dumpr_util.h  |    5 ++
 3 files changed, 185 insertions(+), 0 deletions(-)
diff --git a/dump_editor.c b/dump_editor.c
index 6e9b0f5..0f7d231 100644
--- a/dump_editor.c
+++ b/dump_editor.c
@@ -15,6 +15,10 @@
 
 #include "dumpr_util.h"
 
+#define ARE_VALID_COPY_ARGS(p,r) ((p) && SVN_IS_VALID_REVNUM(r))
+
+svn_boolean_t must_dump_props = FALSE, must_dump_text = FALSE,
+	dump_props_pending = FALSE;
 
 /* Make a directory baton to represent the directory was path
    (relative to EDIT_BATON's path) is PATH.
@@ -70,6 +74,134 @@ struct dir_baton *make_dir_baton(const char *path,
 
 	return new_db;
 }
+/*
+ * Write out a node record for PATH of type KIND under EB->FS_ROOT.
+ * ACTION describes what is happening to the node (see enum svn_node_action).
+ * Write record to writable EB->STREAM, using EB->BUFFER to write in chunks.
+ *
+ * If the node was itself copied, IS_COPY is TRUE and the
+ * path/revision of the copy source are in CMP_PATH/CMP_REV.  If
+ * IS_COPY is FALSE, yet CMP_PATH/CMP_REV are valid, this node is part
+ * of a copied subtree.
+ */
+svn_error_t *dump_node(struct edit_baton *eb,
+		       const char *path,    /* an absolute path. */
+		       svn_node_kind_t kind,
+		       enum svn_node_action action,
+		       const char *cmp_path,
+		       svn_revnum_t cmp_rev,
+		       apr_pool_t *pool)
+{
+	/* Some pending properties to dump? */
+	SVN_ERR(dump_props(eb, &dump_props_pending, TRUE, pool));
+
+	/* Write out metadata headers for this file node. */
+	SVN_ERR(svn_stream_printf(eb->stream, pool,
+				  SVN_REPOS_DUMPFILE_NODE_PATH ": %s\n",
+				  (*path == '/') ? path + 1 : path));
+
+	if (kind == svn_node_file)
+		SVN_ERR(svn_stream_printf(eb->stream, pool,
+		                          SVN_REPOS_DUMPFILE_NODE_KIND ": file\n"));
+	else if (kind == svn_node_dir)
+		SVN_ERR(svn_stream_printf(eb->stream, pool,
+		                          SVN_REPOS_DUMPFILE_NODE_KIND ": dir\n"));
+
+	/* Remove leading slashes from copyfrom paths. */
+	if (cmp_path)
+		cmp_path = ((*cmp_path == '/') ? cmp_path + 1 : cmp_path);
+
+	switch (action) {
+		/* Appropriately handle the four svn_node_action actions */
+
+	case svn_node_action_change:
+		SVN_ERR(svn_stream_printf(eb->stream, pool,
+		                          SVN_REPOS_DUMPFILE_NODE_ACTION
+		                          ": change\n"));
+		break;
+
+	case svn_node_action_replace:
+		if (!eb->is_copy) {
+			/* a simple delete+add, implied by a single 'replace' action. */
+			SVN_ERR(svn_stream_printf(eb->stream, pool,
+			                          SVN_REPOS_DUMPFILE_NODE_ACTION
+			                          ": replace\n"));
+
+			/* definitely need to dump all content for a replace. */
+			must_dump_props = TRUE;
+			break;
+		}
+		/* More complex case: eb->is_copy is true, and
+		   cmp_path/ cmp_rev are present: delete the original,
+		   and then re-add it */
+
+		/* the path & kind headers have already been printed;  just
+		   add a delete action, and end the current record.*/
+		SVN_ERR(svn_stream_printf(eb->stream, pool,
+		                          SVN_REPOS_DUMPFILE_NODE_ACTION
+		                          ": delete\n\n"));
+
+		/* recurse:  print an additional add-with-history record. */
+		SVN_ERR(dump_node(eb, path, kind, svn_node_action_add,
+		                  cmp_path, cmp_rev, pool));
+
+		/* we can leave this routine quietly now, don't need to dump
+		   any content;  that was already done in the second record. */
+		must_dump_props = FALSE;
+		eb->is_copy = FALSE;
+		break;
+
+	case svn_node_action_delete:
+		SVN_ERR(svn_stream_printf(eb->stream, pool,
+		                          SVN_REPOS_DUMPFILE_NODE_ACTION
+		                          ": delete\n"));
+
+		/* we can leave this routine quietly now, don't need to dump
+		   any content. */
+		SVN_ERR(svn_stream_printf(eb->stream, pool, "\n\n"));
+		must_dump_props = FALSE;
+		break;
+
+	case svn_node_action_add:
+		SVN_ERR(svn_stream_printf(eb->stream, pool,
+		                          SVN_REPOS_DUMPFILE_NODE_ACTION ": add\n"));
+
+		if (!eb->is_copy) {
+			/* If it's a file or directory not copied from
+			   somewhere, wait for change_file_prop or
+			   change_directory_prop */
+			dump_props_pending = TRUE;
+			break;
+		}
+
+		SVN_ERR(svn_stream_printf(eb->stream, pool,
+		                          SVN_REPOS_DUMPFILE_NODE_COPYFROM_REV
+		                          ": %ld\n"
+		                          SVN_REPOS_DUMPFILE_NODE_COPYFROM_PATH
+		                          ": %s\n",
+		                          cmp_rev, cmp_path));
+
+		/* Dump the text only if apply_textdelta sets
+		   must_dump_text */
+
+		/* UGLY hack: If a directory was copied from a
+		   previous revision, nothing else can be done, and
+		   close_file won't be called to write two blank
+		   lines; write them here */
+		if (kind == svn_node_dir)
+			SVN_ERR(svn_stream_printf(eb->stream, pool, "\n\n"));
+
+		eb->is_copy = FALSE;
+
+		break;
+	}
+
+	/* Dump property headers */
+	SVN_ERR(dump_props(eb, &must_dump_props, FALSE, pool));
+
+	return SVN_NO_ERROR;
+}
+
 svn_error_t *open_root(void *edit_baton,
                        svn_revnum_t base_revision,
                        apr_pool_t *pool,
diff --git a/dumpr_util.c b/dumpr_util.c
index 41940d4..a3328b6 100644
--- a/dumpr_util.c
+++ b/dumpr_util.c
@@ -62,3 +62,51 @@ void write_hash_to_stringbuf(apr_hash_t *properties,
 		}
 	}
 }
+
+svn_error_t *dump_props(struct edit_baton *eb,
+			svn_boolean_t *trigger_var,
+			svn_boolean_t dump_data_too,
+			apr_pool_t *pool)
+{
+	if (trigger_var && !*trigger_var)
+		return SVN_NO_ERROR;
+
+	/* Build a propstring to print */
+	svn_stringbuf_setempty(eb->propstring);
+	write_hash_to_stringbuf(eb->properties,
+				FALSE,
+				&(eb->propstring), eb->pool);
+	write_hash_to_stringbuf(eb->del_properties,
+				TRUE,
+				&(eb->propstring), eb->pool);
+	svn_stringbuf_appendbytes(eb->propstring, "PROPS-END\n", 10);
+
+	/* prop-delta header */
+	SVN_ERR(svn_stream_printf(eb->stream, pool,
+				  SVN_REPOS_DUMPFILE_PROP_DELTA
+				  ": true\n"));
+
+	/* prop-content-length header */
+	SVN_ERR(svn_stream_printf(eb->stream, pool,
+				  SVN_REPOS_DUMPFILE_PROP_CONTENT_LENGTH
+				  ": %" APR_SIZE_T_FMT "\n", eb->propstring->len));
+
+	if (dump_data_too) {
+		/* content-length header */
+		SVN_ERR(svn_stream_printf(eb->stream, pool,
+					  SVN_REPOS_DUMPFILE_CONTENT_LENGTH
+					  ": %" APR_SIZE_T_FMT "\n\n",
+					  eb->propstring->len));
+
+		/* the properties themselves */
+		SVN_ERR(svn_stream_write(eb->stream, eb->propstring->data,
+					 &(eb->propstring->len)));
+
+		/* Cleanup so that data is never dumped twice */
+		apr_hash_clear(eb->properties);
+		apr_hash_clear(eb->del_properties);
+		if (trigger_var)
+			*trigger_var = FALSE;
+	}
+	return SVN_NO_ERROR;
+}
diff --git a/dumpr_util.h b/dumpr_util.h
index 96670ff..79de1ab 100644
--- a/dumpr_util.h
+++ b/dumpr_util.h
@@ -66,4 +66,9 @@ void write_hash_to_stringbuf(apr_hash_t *properties,
 			     svn_stringbuf_t **strbuf,
 			     apr_pool_t *pool);
 
+svn_error_t *dump_props(struct edit_baton *eb,
+			svn_boolean_t *trigger_var,
+			svn_boolean_t dump_data_too,
+			apr_pool_t *pool);
+
 #endif
-- 
1.7.1
Previous: Ramkumar RamachandraNext: Ramkumar Ramachandra
Message 25 of 31 in “[GSoC update] git-remote-svn: Week 10”
  1. Ramkumar RamachandraJul 7, 2010
  2. 01/13 Add LICENSERamkumar Ramachandra, Jul 7, 2010
  3. 02/13 Add skeleton SVN client and MakefileRamkumar Ramachandra, Jul 7, 2010
  4. Jonathan NiederJul 7, 2010
  5. Ramkumar RamachandraJul 7, 2010
  6. Jonathan NiederJul 7, 2010
  7. Ramkumar RamachandraJul 7, 2010
  8. Daniel ShahafJul 7, 2010
  9. 03/13 Add debug editor from Subversion trunkRamkumar Ramachandra, Jul 7, 2010
  10. Jonathan NiederJul 7, 2010
  11. 04/13 Add skeleton dump editorRamkumar Ramachandra, Jul 7, 2010
  12. Jonathan NiederJul 7, 2010
  13. Ramkumar RamachandraJul 8, 2010
  14. 05/13 Drive the debug editorRamkumar Ramachandra, Jul 7, 2010
  15. Jonathan NiederJul 7, 2010
  16. Ramkumar RamachandraJul 7, 2010
  17. Jonathan NiederJul 7, 2010
  18. Ramkumar RamachandraJul 8, 2010
  19. 06/13 Dump the revprops at the start of every revisionRamkumar Ramachandra, Jul 7, 2010
  20. Jonathan NiederJul 7, 2010
  21. Ramkumar RamachandraJul 21, 2010
  22. Julian FoadJul 26, 2010
  23. Ramkumar RamachandraJul 26, 2010
  24. 07/13 Implement open_root and close_editRamkumar Ramachandra, Jul 7, 2010
  25. 08/13 Implement dump_nodeRamkumar Ramachandra, Jul 7, 2010
  26. 09/13 Implement directory-related functionsRamkumar Ramachandra, Jul 7, 2010
  27. 10/13 Implement file-related functionsRamkumar Ramachandra, Jul 7, 2010
  28. 11/13 Implement apply_textdeltaRamkumar Ramachandra, Jul 7, 2010
  29. 12/13 Implement close_fileRamkumar Ramachandra, Jul 7, 2010
  30. 13/13 Add a validation scriptRamkumar Ramachandra, Jul 7, 2010
  31. Ramkumar RamachandraJul 7, 2010

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.