From mboxrd@z Thu Jan 1 00:00:00 1970 From: David Barr Subject: [PATCH 6/7] vcs-svn: implement prop-delta handling. Date: Wed, 13 Oct 2010 00:50:23 +1100 Message-ID: <1286891424-2067-7-git-send-email-david.barr@cordelta.com> References: <1286891424-2067-1-git-send-email-david.barr@cordelta.com> Cc: Jonathan Nieder , Ramkumar Ramachandra , Sverre Rabbelier , David Barr To: Git Mailing List X-From: git-owner@vger.kernel.org Tue Oct 12 15:50:49 2010 Return-path: Envelope-to: gcvg-git-2@lo.gmane.org Received: from vger.kernel.org ([209.132.180.67]) by lo.gmane.org with esmtp (Exim 4.69) (envelope-from ) id 1P5fFc-0004Px-GD for gcvg-git-2@lo.gmane.org; Tue, 12 Oct 2010 15:50:44 +0200 Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932428Ab0JLNui (ORCPT ); Tue, 12 Oct 2010 09:50:38 -0400 Received: from static-198-196.grapevine.transact.net.au ([121.127.198.196]:58872 "EHLO mailhost.cordelta" rhost-flags-OK-FAIL-OK-FAIL) by vger.kernel.org with ESMTP id S932283Ab0JLNue (ORCPT ); Tue, 12 Oct 2010 09:50:34 -0400 Received: from localhost (localhost.localdomain [127.0.0.1]) by mailhost.cordelta (Postfix) with ESMTP id 21599C06A; Wed, 13 Oct 2010 00:50:36 +1100 (EST) X-Virus-Scanned: amavisd-new at mailhost.cordelta Received: from mailhost.cordelta ([127.0.0.1]) by localhost (mailhost.cordelta [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id cgj+I7HPhNm8; Wed, 13 Oct 2010 00:50:32 +1100 (EST) Received: from dba.cordelta (unknown [192.168.123.127]) by mailhost.cordelta (Postfix) with ESMTP id E417AC06D; Wed, 13 Oct 2010 00:50:29 +1100 (EST) X-Mailer: git-send-email 1.7.3.1 In-Reply-To: <1286891424-2067-1-git-send-email-david.barr@cordelta.com> Sender: git-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org Archived-At: By testing against the Apache Software Foundation repository, some simple rules for decoding prop deltas were derived. 'Node-action: replace' implies the empty prop set as the base for the delta. Otherwise, if a copyfrom source is given that node forms the basis for the delta. Lastly, if the destination path exists in the active revision it forms the basis. Signed-off-by: David Barr --- vcs-svn/fast_export.c | 4 +++- vcs-svn/fast_export.h | 3 ++- vcs-svn/repo_tree.c | 23 +++++++++++++++++++++++ vcs-svn/repo_tree.h | 2 ++ vcs-svn/svndump.c | 35 +++++++++++++++++++++++++++++++---- 5 files changed, 61 insertions(+), 6 deletions(-) diff --git a/vcs-svn/fast_export.c b/vcs-svn/fast_export.c index 260cf50..d984aaa 100644 --- a/vcs-svn/fast_export.c +++ b/vcs-svn/fast_export.c @@ -63,7 +63,9 @@ void fast_export_commit(uint32_t revision, uint32_t author, char *log, printf("progress Imported commit %"PRIu32".\n\n", revision); } -void fast_export_blob(uint32_t mode, uint32_t mark, uint32_t len, struct line_buffer *input) +void fast_export_blob(uint32_t mode, uint32_t mark, uint32_t len, + uint32_t delta, uint32_t srcMark, uint32_t srcMode, + struct line_buffer *input) { if (mode == REPO_MODE_LNK) { /* svn symlink blobs start with "link " */ diff --git a/vcs-svn/fast_export.h b/vcs-svn/fast_export.h index 054e7d5..634d9c6 100644 --- a/vcs-svn/fast_export.h +++ b/vcs-svn/fast_export.h @@ -9,6 +9,7 @@ void fast_export_modify(uint32_t depth, uint32_t *path, uint32_t mode, void fast_export_commit(uint32_t revision, uint32_t author, char *log, uint32_t uuid, uint32_t url, unsigned long timestamp); void fast_export_blob(uint32_t mode, uint32_t mark, uint32_t len, - struct line_buffer *input); + uint32_t delta, uint32_t srcMark, uint32_t srcMode, + struct line_buffer *input); #endif diff --git a/vcs-svn/repo_tree.c b/vcs-svn/repo_tree.c index e94d91d..b616bda 100644 --- a/vcs-svn/repo_tree.c +++ b/vcs-svn/repo_tree.c @@ -157,6 +157,29 @@ static void repo_write_dirent(uint32_t *path, uint32_t mode, dent_remove(&dir_pointer(parent_dir_o)->entries, dent); } +uint32_t repo_read_mark(uint32_t revision, uint32_t *path) +{ + uint32_t mode = 0, content_offset = 0; + struct repo_dirent *src_dent; + src_dent = repo_read_dirent(revision, path); + if (src_dent != NULL) { + mode = src_dent->mode; + content_offset = src_dent->content_offset; + } + return mode && mode != REPO_MODE_DIR ? content_offset : 0; +} + +uint32_t repo_read_mode(uint32_t revision, uint32_t *path) +{ + uint32_t mode = 0; + struct repo_dirent *src_dent; + src_dent = repo_read_dirent(revision, path); + if (src_dent != NULL) { + mode = src_dent->mode; + } + return mode; +} + uint32_t repo_copy(uint32_t revision, uint32_t *src, uint32_t *dst) { uint32_t mode = 0, content_offset = 0; diff --git a/vcs-svn/repo_tree.h b/vcs-svn/repo_tree.h index 5476175..bd6a3f7 100644 --- a/vcs-svn/repo_tree.h +++ b/vcs-svn/repo_tree.h @@ -12,6 +12,8 @@ #define REPO_MAX_PATH_DEPTH 1000 uint32_t next_blob_mark(void); +uint32_t repo_read_mark(uint32_t revision, uint32_t *path); +uint32_t repo_read_mode(uint32_t revision, uint32_t *path); uint32_t repo_copy(uint32_t revision, uint32_t *src, uint32_t *dst); void repo_add(uint32_t *path, uint32_t mode, uint32_t blob_mark); uint32_t repo_replace(uint32_t *path, uint32_t blob_mark); diff --git a/vcs-svn/svndump.c b/vcs-svn/svndump.c index 458053e..3431c22 100644 --- a/vcs-svn/svndump.c +++ b/vcs-svn/svndump.c @@ -45,7 +45,7 @@ static char* log_copy(uint32_t length, char *log) } static struct { - uint32_t action, propLength, textLength, srcRev, srcMode, mark, type; + uint32_t action, propLength, textLength, srcRev, srcMode, srcMark, mark, type; uint32_t src[REPO_MAX_PATH_DEPTH], dst[REPO_MAX_PATH_DEPTH]; uint32_t text_delta, prop_delta; char text_delta_base_md5[MD5_HEX_LENGTH + 1]; @@ -86,6 +86,7 @@ static void reset_node_ctx(char *fname) node_ctx.src[0] = ~0; node_ctx.srcRev = 0; node_ctx.srcMode = 0; + node_ctx.srcMark = 0; pool_tok_seq(REPO_MAX_PATH_DEPTH, node_ctx.dst, "/", fname); node_ctx.mark = 0; node_ctx.text_delta = 0; @@ -168,17 +169,42 @@ static void read_props(void) } key = ~0; buffer_read_line(&input); + } else if (!strncmp(t, "D ", 2)) { + len = atoi(&t[2]); + key = pool_intern(buffer_read_string(&input, len)); + buffer_read_line(&input); + if (key == keys.svn_executable) { + if (node_ctx.type == REPO_MODE_EXE) + node_ctx.type = REPO_MODE_BLB; + } else if (key == keys.svn_special) { + if (node_ctx.type == REPO_MODE_LNK) + node_ctx.type = REPO_MODE_BLB; + } + key = ~0; } } } static void handle_node(void) { + if (node_ctx.prop_delta) { + if (node_ctx.srcRev) + node_ctx.srcMode = repo_read_mode(node_ctx.srcRev, node_ctx.src); + else + node_ctx.srcMode = repo_read_mode(rev_ctx.revision, node_ctx.dst); + if (node_ctx.srcMode && node_ctx.action != NODEACT_REPLACE) + node_ctx.type = node_ctx.srcMode; + } + if (node_ctx.propLength != LENGTH_UNKNOWN && node_ctx.propLength) read_props(); - if (node_ctx.srcRev) + if (node_ctx.srcRev) { + node_ctx.srcMark = repo_read_mark(node_ctx.srcRev, node_ctx.src); node_ctx.srcMode = repo_copy(node_ctx.srcRev, node_ctx.src, node_ctx.dst); + } else { + node_ctx.srcMark = repo_read_mark(rev_ctx.revision, node_ctx.dst); + } if (node_ctx.textLength != LENGTH_UNKNOWN && node_ctx.type != REPO_MODE_DIR) @@ -209,8 +235,9 @@ static void handle_node(void) node_ctx.type = node_ctx.srcMode; if (node_ctx.mark) - fast_export_blob(node_ctx.type, - node_ctx.mark, node_ctx.textLength, &input); + fast_export_blob(node_ctx.type, node_ctx.mark, node_ctx.textLength, + node_ctx.text_delta, node_ctx.srcMark, node_ctx.srcMode, + &input); else if (node_ctx.textLength != LENGTH_UNKNOWN) buffer_skip_bytes(&input, node_ctx.textLength); } -- 1.7.3.1