summaryrefslogtreecommitdiff
path: root/vcs-svn
diff options
context:
space:
mode:
authorDavid Barr <david.barr@cordelta.com>2010-11-19 18:57:46 -0600
committerJunio C Hamano <gitster@pobox.com>2010-11-24 14:53:59 -0800
commit6b01b67658e2905b550739f1aee56a00911ca13c (patch)
tree15212576be03435d3ccd798720bd8dd156e3f595 /vcs-svn
parent6263c06d49abdf5e5defdf528c3ff67bf948ac9b (diff)
downloadgit-6b01b67658e2905b550739f1aee56a00911ca13c.tar.gz
vcs-svn: Implement Prop-delta handling
The rules for what file is used as delta source for each file are not documented in dump-load-format.txt. Luckily, the Apache Software Foundation repository has rich enough examples to figure out most of the rules: Node-action: replace implies the empty property set and empty text as preimage for deltas. Otherwise, if a copyfrom source is given, that node is the preimage for deltas. Lastly, if none of the above applies and the node path exists in the current revision, then that version forms the basis. [jn: refactored, with tests] Signed-off-by: David Barr <david.barr@cordelta.com> Signed-off-by: Jonathan Nieder <jrnieder@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Diffstat (limited to 'vcs-svn')
-rw-r--r--vcs-svn/svndump.c54
1 files changed, 44 insertions, 10 deletions
diff --git a/vcs-svn/svndump.c b/vcs-svn/svndump.c
index 576d148e5e..c71a57599e 100644
--- a/vcs-svn/svndump.c
+++ b/vcs-svn/svndump.c
@@ -115,20 +115,35 @@ static void init_keys(void)
keys.prop_delta = pool_intern("Prop-delta");
}
-static void handle_property(uint32_t key, const char *val, uint32_t len)
+static void handle_property(uint32_t key, const char *val, uint32_t len,
+ uint32_t *type_set)
{
if (key == keys.svn_log) {
+ if (!val)
+ die("invalid dump: unsets svn:log");
/* Value length excludes terminating nul. */
rev_ctx.log = log_copy(len + 1, val);
} else if (key == keys.svn_author) {
rev_ctx.author = pool_intern(val);
} else if (key == keys.svn_date) {
+ if (!val)
+ die("invalid dump: unsets svn:date");
if (parse_date_basic(val, &rev_ctx.timestamp, NULL))
- fprintf(stderr, "Invalid timestamp: %s\n", val);
- } else if (key == keys.svn_executable) {
- node_ctx.type = REPO_MODE_EXE;
- } else if (key == keys.svn_special) {
- node_ctx.type = REPO_MODE_LNK;
+ warning("invalid timestamp: %s", val);
+ } else if (key == keys.svn_executable || key == keys.svn_special) {
+ if (*type_set) {
+ if (!val)
+ return;
+ die("invalid dump: sets type twice");
+ }
+ if (!val) {
+ node_ctx.type = REPO_MODE_BLB;
+ return;
+ }
+ *type_set = 1;
+ node_ctx.type = key == keys.svn_executable ?
+ REPO_MODE_EXE :
+ REPO_MODE_LNK;
}
}
@@ -136,6 +151,19 @@ static void read_props(void)
{
uint32_t key = ~0;
const char *t;
+ /*
+ * NEEDSWORK: to support simple mode changes like
+ * K 11
+ * svn:special
+ * V 1
+ * *
+ * D 14
+ * svn:executable
+ * we keep track of whether a mode has been set and reset to
+ * plain file only if not. We should be keeping track of the
+ * symlink and executable bits separately instead.
+ */
+ uint32_t type_set = 0;
while ((t = buffer_read_line()) && strcmp(t, "PROPS-END")) {
uint32_t len;
const char *val;
@@ -151,8 +179,13 @@ static void read_props(void)
case 'K':
key = pool_intern(val);
continue;
+ case 'D':
+ key = pool_intern(val);
+ val = NULL;
+ len = 0;
+ /* fall through */
case 'V':
- handle_property(key, val, len);
+ handle_property(key, val, len, &type_set);
key = ~0;
continue;
default:
@@ -167,8 +200,8 @@ static void handle_node(void)
const uint32_t type = node_ctx.type;
const int have_props = node_ctx.propLength != LENGTH_UNKNOWN;
- if (node_ctx.text_delta || node_ctx.prop_delta)
- die("text and property deltas not supported");
+ if (node_ctx.text_delta)
+ die("text deltas not supported");
if (node_ctx.textLength != LENGTH_UNKNOWN)
mark = next_blob_mark();
if (node_ctx.action == NODEACT_DELETE) {
@@ -206,7 +239,8 @@ static void handle_node(void)
}
if (have_props) {
const uint32_t old_mode = node_ctx.type;
- node_ctx.type = type;
+ if (!node_ctx.prop_delta)
+ node_ctx.type = type;
if (node_ctx.propLength)
read_props();
if (node_ctx.type != old_mode)