{"thread":{"id":"21993","subject":"Efficiency and correctness patches for git-svn mergeinfo support","startedAt":"2009-12-19T16:33:50Z","lastAt":"2009-12-21T10:44:44Z","messageCount":13,"participants":["Sam Vilain","Andrew Myrick","Eric Wong"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"130145","messageId":"1261240435-8948-1-git-send-email-sam@vilain.net","threadId":"21993","inReplyTo":null,"subject":"Efficiency and correctness patches for git-svn mergeinfo support","fromName":"Sam Vilain","fromEmail":"sam@vilain.net","sentAt":"2009-12-19T16:33:50Z","receivedAt":"2009-12-19T16:33:50Z","isPatch":false,"sender":{"key":"sam@vilain.net","avatar":"https://gravatar.com/avatar/8fc840ca854dbf6f7065b4335e3b934951c1dca3b11db688e95e471901f8f4a8?d=mp&s=160"},"body":"This series implements some efficiency enhancements; particularly in\ndealing with repositories which have a single trunk branch which\nreceives many merges of feature branches and/or cherry-picks.  It also\nfixes a number of corner cases in the merge conversion code.\n\nIt would be nice if the people who have experienced slow git-svn\nperformance in these situations could test that this fixes the\nperformance issues, and that the resulting repositories seem to have\ncorrect contents.\n\nEric, I'm using Alex's trick of a single commit which adds failing\ntests - marked as _expect_failure - and then marked them as succeeding\nas the series progresses.\n"},{"id":"130148","messageId":"1261240435-8948-2-git-send-email-sam@vilain.net","threadId":"21993","inReplyTo":"1261240435-8948-1-git-send-email-sam@vilain.net","subject":"[PATCH 1/5] git-svn: expand the svn mergeinfo test suite, highlighting some failures","fromName":"Sam Vilain","fromEmail":"sam@vilain.net","sentAt":"2009-12-19T16:33:51Z","receivedAt":"2009-12-19T16:33:51Z","isPatch":true,"sender":{"key":"sam@vilain.net","avatar":"https://gravatar.com/avatar/8fc840ca854dbf6f7065b4335e3b934951c1dca3b11db688e95e471901f8f4a8?d=mp&s=160"},"body":"As shown, git-svn has some problems; not all svn merges are correctly\ndetected, and cherry picks may incorrectly be detected as real merges.\nThese test cases will be marked as _success once the relevant fixes are in.\n\nSigned-off-by: Sam Vilain <sam@vilain.net>\n---\n t/t9151-svn-mergeinfo.sh   |   27 ++-\n t/t9151/make-svnmerge-dump |  166 ++++++---\n t/t9151/svn-mergeinfo.dump |  839 ++++++++++++++++++++++++++++++++++++++------\n 3 files changed, 860 insertions(+), 172 deletions(-)\n\ndiff --git a/t/t9151-svn-mergeinfo.sh b/t/t9151-svn-mergeinfo.sh\nindex f57daf4..dc3478f 100755\n--- a/t/t9151-svn-mergeinfo.sh\n+++ b/t/t9151-svn-mergeinfo.sh\n@@ -15,12 +15,27 @@ test_expect_success 'load svn dump' \"\n \tgit svn fetch --all\n \t\"\n \n-test_expect_success 'represent svn merges without intervening commits' \"\n-\t[ `git cat-file commit HEAD^1 | grep parent | wc -l` -eq 2 ]\n-\t\"\n+test_expect_failure 'all svn merges became git merge commits' '\n+\tunmarked=$(git rev-list --parents --all --grep=Merge |\n+\t\tgrep -v \" .* \" | cut -f1 -d\" \")\n+\t[ -z \"$unmarked\" ]\n+\t'\n \n-test_expect_success 'represent svn merges with intervening commits' \"\n-\t[ `git cat-file commit HEAD | grep parent | wc -l` -eq 2 ]\n-\t\"\n+test_expect_failure 'cherry picks did not become git merge commits' '\n+\tbad_cherries=$(git rev-list --parents --all --grep=Cherry |\n+\t\tgrep \" .* \" | cut -f1 -d\" \")\n+\t[ -z \"$bad_cherries\" ]\n+\t'\n+\n+test_expect_success 'svn non-merge merge commits did not become git merge commits' '\n+\tbad_non_merges=$(git rev-list --parents --all --grep=non-merge |\n+\t\tgrep \" .* \" | cut -f1 -d\" \")\n+\t[ -z \"$bad_non_merges\" ]\n+\t'\n+\n+test_expect_failure 'everything got merged in the end' '\n+\tunmerged=$(git rev-list --all --not master)\n+\t[ -z \"$unmerged\" ]\n+\t'\n \n test_done\ndiff --git a/t/t9151/make-svnmerge-dump b/t/t9151/make-svnmerge-dump\nindex 7e3da75..d917717 100644\n--- a/t/t9151/make-svnmerge-dump\n+++ b/t/t9151/make-svnmerge-dump\n@@ -11,93 +11,151 @@ mkdir foo.svn\n svnadmin create foo.svn\n svn co file://`pwd`/foo.svn foo\n \n+commit() {\n+    i=$(( $1 + 1 ))\n+    shift;\n+    svn commit -m \"(r$i) $*\" >/dev/null || exit 1\n+    echo $i\n+}\n+\n+say() {\n+    echo \"\u001b[1m * $*\u001b[0m\"\n+}\n+\n+i=0\n cd foo\n mkdir trunk\n mkdir branches\n svn add trunk branches\n-svn commit -m \"Setup trunk and branches\"\n-cd trunk\n+i=$(commit $i \"Setup trunk and branches\")\n \n-git cat-file blob 6683463e:Makefile > Makefile\n-svn add Makefile \n+git cat-file blob 6683463e:Makefile > trunk/Makefile\n+svn add trunk/Makefile \n \n-echo \"Committing ANCESTOR\"\n-svn commit -m \"ancestor\"\n-cd ..\n+say \"Committing ANCESTOR\"\n+i=$(commit $i \"ancestor\")\n svn cp trunk branches/left\n \n-echo \"Committing BRANCH POINT\"\n-svn commit -m \"make left branch\"\n+say \"Committing BRANCH POINT\"\n+i=$(commit $i \"make left branch\")\n svn cp trunk branches/right\n \n-echo \"Committing other BRANCH POINT\"\n-svn commit -m \"make right branch\"\n-cd branches/left/\n+say \"Committing other BRANCH POINT\"\n+i=$(commit $i \"make right branch\")\n \n-#$sm init\n-#svn commit -m \"init svnmerge\"\n+say \"Committing LEFT UPDATE\"\n+git cat-file blob 5873b67e:Makefile > branches/left/Makefile\n+i=$(commit $i \"left update 1\")\n \n-git cat-file blob 5873b67e:Makefile > Makefile\n-echo \"Committing BRANCH UPDATE 1\"\n-svn commit -m \"left update 1\"\n-cd ../..\n-\n-cd trunk\n-git cat-file blob 75118b13:Makefile > Makefile\n-echo \"Committing TRUNK UPDATE\"\n-svn commit -m \"trunk update\"\n+git cat-file blob 75118b13:Makefile > branches/right/Makefile\n+say \"Committing RIGHT UPDATE\"\n+pre_right_update_1=$i\n+i=$(commit $i \"right update 1\")\n \n-cd ../branches/left\n-git cat-file blob ff5ebe39:Makefile > Makefile\n-echo \"Committing BRANCH UPDATE 2\"\n-svn commit -m \"left update 2\"\n+say \"Making more commits on LEFT\"\n+git cat-file blob ff5ebe39:Makefile > branches/left/Makefile\n+i=$(commit $i \"left update 2\")\n+git cat-file blob b5039db6:Makefile > branches/left/Makefile\n+i=$(commit $i \"left update 3\")\n \n-git cat-file blob b5039db6:Makefile > Makefile\n-echo \"Committing BRANCH UPDATE 3\"\n-svn commit -m \"left update 3\"\n+say \"Making a LEFT SUB-BRANCH\"\n+svn cp branches/left branches/left-sub\n+sub_left_make=$i\n+i=$(commit $i \"make left sub-branch\")\n \n-# merge to trunk\n+say \"Making a commit on LEFT SUB-BRANCH\"\n+echo \"crunch\" > branches/left-sub/README\n+svn add branches/left-sub/README\n+i=$(commit $i \"left sub-branch update 1\")\n \n-cd ../..\n+say \"Merging LEFT to TRUNK\"\n svn update\n cd trunk\n-\n svn merge ../branches/left --accept postpone\n-\n-git cat-file blob b51ad431:Makefile > Makefile\n-\n+git cat-file blob b5039db6:Makefile > Makefile\n svn resolved Makefile\n+i=$(commit $i \"Merge left to trunk 1\")\n+cd ..\n \n-svn commit -m \"Merge trunk 1\"\n-\n-# create commits on both branches\n-\n-cd ../branches/left\n-git cat-file blob ff5ebe39:Makefile > Makefile\n-echo \"Committing BRANCH UPDATE 4\"\n-svn commit -m \"left update 4\"\n-\n-cd ../right\n-git cat-file blob b5039db6:Makefile > Makefile\n-echo \"Committing other BRANCH UPDATE 1\"\n-svn commit -m \"right update 1\"\n+say \"Making more commits on LEFT and RIGHT\"\n+echo \"touche\" > branches/left/zlonk\n+svn add branches/left/zlonk\n+i=$(commit $i \"left update 4\")\n+echo \"thwacke\" > branches/right/bang\n+svn add branches/right/bang\n+i=$(commit $i \"right update 2\")\n \n-# merge to trun again\n+say \"Squash merge of RIGHT tip 2 commits onto TRUNK\"\n+svn update\n+cd trunk\n+svn merge -r$pre_right_update_1:$i ../branches/right\n+i=$(commit $i \"Cherry-pick right 2 commits to trunk\")\n+cd ..\n \n-cd ../..\n+say \"Merging RIGHT to TRUNK\"\n svn update\n cd trunk\n+svn merge ../branches/right --accept postpone\n+git cat-file blob b51ad431:Makefile > Makefile\n+svn resolved Makefile\n+i=$(commit $i \"Merge right to trunk 1\")\n+cd ..\n \n-svn merge ../branches/left --accept postpone\n+say \"Making more commits on RIGHT and TRUNK\"\n+echo \"whamm\" > branches/right/urkkk\n+svn add branches/right/urkkk\n+i=$(commit $i \"right update 3\")\n+echo \"pow\" > trunk/vronk\n+svn add trunk/vronk\n+i=$(commit $i \"trunk update 1\")\n \n+say \"Merging RIGHT to LEFT SUB-BRANCH\"\n+svn update\n+cd branches/left-sub\n+svn merge ../right --accept postpone\n git cat-file blob b51ad431:Makefile > Makefile\n-\n svn resolved Makefile\n+i=$(commit $i \"Merge right to left sub-branch\")\n+cd ../..\n \n-svn commit -m \"Merge trunk 2\"\n+say \"Making more commits on LEFT SUB-BRANCH and LEFT\"\n+echo \"zowie\" > branches/left-sub/wham_eth\n+svn add branches/left-sub/wham_eth\n+pre_sub_left_update_2=$i\n+i=$(commit $i \"left sub-branch update 2\")\n+sub_left_update_2=$i\n+echo \"eee_yow\" > branches/left/glurpp\n+svn add branches/left/glurpp\n+i=$(commit $i \"left update 5\")\n+\n+say \"Cherry pick LEFT SUB-BRANCH commit to LEFT\"\n+svn update\n+cd branches/left\n+svn merge -r$pre_sub_left_update_2:$sub_left_update_2 ../left-sub\n+i=$(commit $i \"Cherry-pick left sub-branch commit to left\")\n+cd ../..\n \n+say \"Merging LEFT SUB-BRANCH back to LEFT\"\n+svn update\n+cd branches/left\n+# it's only a merge because the previous merge cherry-picked the top commit\n+svn merge -r$sub_left_make:$sub_left_update_2 ../left-sub --accept postpone\n+i=$(commit $i \"Merge left sub-branch to left\")\n cd ../..\n \n+say \"Merging EVERYTHING to TRUNK\"\n+svn update\n+cd trunk\n+svn merge ../branches/left --accept postpone\n+svn resolved bang\n+i=$(commit $i \"Merge left to trunk 2\")\n+# this merge, svn happily updates the mergeinfo, but there is actually\n+# nothing to merge.  git-svn will not make a meaningless merge commit.\n+svn merge ../branches/right --accept postpone\n+i=$(commit $i \"non-merge right to trunk 2\")\n+cd ..\n+\n+cd ..\n svnadmin dump foo.svn > svn-mergeinfo.dump\n \n rm -rf foo foo.svn\ndiff --git a/t/t9151/svn-mergeinfo.dump b/t/t9151/svn-mergeinfo.dump\nindex 11a883f..9543e31 100644\n--- a/t/t9151/svn-mergeinfo.dump\n+++ b/t/t9151/svn-mergeinfo.dump\n@@ -1,6 +1,6 @@\n SVN-fs-dump-format-version: 2\n \n-UUID: 1530d5a2-a1dc-4438-8ad5-d95e96db8945\n+UUID: 64142547-0943-4db2-836a-d1e1eb2f9924\n \n Revision-number: 0\n Prop-content-length: 56\n@@ -9,25 +9,25 @@ Content-length: 56\n K 8\n svn:date\n V 27\n-2009-11-12T20:29:38.812226Z\n+2009-12-19T16:17:51.232640Z\n PROPS-END\n \n Revision-number: 1\n-Prop-content-length: 127\n-Content-length: 127\n+Prop-content-length: 128\n+Content-length: 128\n \n K 7\n svn:log\n-V 24\n-Setup trunk and branches\n+V 29\n+(r1) Setup trunk and branches\n K 10\n svn:author\n-V 8\n-tallsopp\n+V 4\n+samv\n K 8\n svn:date\n V 27\n-2009-11-12T20:29:39.045856Z\n+2009-12-19T16:17:51.831965Z\n PROPS-END\n \n Node-path: branches\n@@ -49,21 +49,21 @@ PROPS-END\n \n \n Revision-number: 2\n-Prop-content-length: 110\n-Content-length: 110\n+Prop-content-length: 112\n+Content-length: 112\n \n K 7\n svn:log\n-V 8\n-ancestor\n+V 13\n+(r2) ancestor\n K 10\n svn:author\n-V 8\n-tallsopp\n+V 4\n+samv\n K 8\n svn:date\n V 27\n-2009-11-12T20:29:40.079587Z\n+2009-12-19T16:17:52.300075Z\n PROPS-END\n \n Node-path: trunk/Makefile\n@@ -156,21 +156,21 @@ backup: clean\n \n \n Revision-number: 3\n-Prop-content-length: 119\n-Content-length: 119\n+Prop-content-length: 120\n+Content-length: 120\n \n K 7\n svn:log\n-V 16\n-make left branch\n+V 21\n+(r3) make left branch\n K 10\n svn:author\n-V 8\n-tallsopp\n+V 4\n+samv\n K 8\n svn:date\n V 27\n-2009-11-12T20:29:42.084439Z\n+2009-12-19T16:17:52.768800Z\n PROPS-END\n \n Node-path: branches/left\n@@ -190,21 +190,21 @@ Text-copy-source-sha1: 103205ce331f7d64086dba497574734f78439590\n \n \n Revision-number: 4\n-Prop-content-length: 120\n-Content-length: 120\n+Prop-content-length: 121\n+Content-length: 121\n \n K 7\n svn:log\n-V 17\n-make right branch\n+V 22\n+(r4) make right branch\n K 10\n svn:author\n-V 8\n-tallsopp\n+V 4\n+samv\n K 8\n svn:date\n V 27\n-2009-11-12T20:29:44.065452Z\n+2009-12-19T16:17:53.177879Z\n PROPS-END\n \n Node-path: branches/right\n@@ -224,21 +224,21 @@ Text-copy-source-sha1: 103205ce331f7d64086dba497574734f78439590\n \n \n Revision-number: 5\n-Prop-content-length: 116\n-Content-length: 116\n+Prop-content-length: 117\n+Content-length: 117\n \n K 7\n svn:log\n-V 13\n-left update 1\n+V 18\n+(r5) left update 1\n K 10\n svn:author\n-V 8\n-tallsopp\n+V 4\n+samv\n K 8\n svn:date\n V 27\n-2009-11-12T20:29:45.066262Z\n+2009-12-19T16:17:53.604691Z\n PROPS-END\n \n Node-path: branches/left/Makefile\n@@ -329,24 +329,24 @@ backup: clean\n \n \n Revision-number: 6\n-Prop-content-length: 115\n-Content-length: 115\n+Prop-content-length: 118\n+Content-length: 118\n \n K 7\n svn:log\n-V 12\n-trunk update\n+V 19\n+(r6) right update 1\n K 10\n svn:author\n-V 8\n-tallsopp\n+V 4\n+samv\n K 8\n svn:date\n V 27\n-2009-11-12T20:29:46.278498Z\n+2009-12-19T16:17:54.063555Z\n PROPS-END\n \n-Node-path: trunk/Makefile\n+Node-path: branches/right/Makefile\n Node-kind: file\n Node-action: change\n Text-content-length: 2521\n@@ -437,21 +437,21 @@ backup: clean\n \n \n Revision-number: 7\n-Prop-content-length: 116\n-Content-length: 116\n+Prop-content-length: 117\n+Content-length: 117\n \n K 7\n svn:log\n-V 13\n-left update 2\n+V 18\n+(r7) left update 2\n K 10\n svn:author\n-V 8\n-tallsopp\n+V 4\n+samv\n K 8\n svn:date\n V 27\n-2009-11-12T20:29:47.069090Z\n+2009-12-19T16:17:54.523904Z\n PROPS-END\n \n Node-path: branches/left/Makefile\n@@ -542,21 +542,21 @@ backup: clean\n \n \n Revision-number: 8\n-Prop-content-length: 116\n-Content-length: 116\n+Prop-content-length: 117\n+Content-length: 117\n \n K 7\n svn:log\n-V 13\n-left update 3\n+V 18\n+(r8) left update 3\n K 10\n svn:author\n-V 8\n-tallsopp\n+V 4\n+samv\n K 8\n svn:date\n V 27\n-2009-11-12T20:29:48.053835Z\n+2009-12-19T16:17:54.975970Z\n PROPS-END\n \n Node-path: branches/left/Makefile\n@@ -647,33 +647,285 @@ backup: clean\n \n \n Revision-number: 9\n-Prop-content-length: 116\n-Content-length: 116\n+Prop-content-length: 124\n+Content-length: 124\n \n K 7\n svn:log\n-V 13\n-Merge trunk 1\n+V 25\n+(r9) make left sub-branch\n+K 10\n+svn:author\n+V 4\n+samv\n+K 8\n+svn:date\n+V 27\n+2009-12-19T16:17:55.459904Z\n+PROPS-END\n+\n+Node-path: branches/left-sub\n+Node-kind: dir\n+Node-action: add\n+Node-copyfrom-rev: 3\n+Node-copyfrom-path: branches/left\n+\n+\n+Node-path: branches/left-sub/Makefile\n+Node-kind: file\n+Node-action: delete\n+\n+Node-path: branches/left-sub/Makefile\n+Node-kind: file\n+Node-action: add\n+Node-copyfrom-rev: 8\n+Node-copyfrom-path: branches/left/Makefile\n+Text-copy-source-md5: 5ccff689fb290e00b85fe18ee50c54ba\n+Text-copy-source-sha1: a13de8e23f1483efca3e57b2b64b0ae6f740ce10\n+\n+\n+\n+\n+Revision-number: 10\n+Prop-content-length: 129\n+Content-length: 129\n+\n+K 7\n+svn:log\n+V 30\n+(r10) left sub-branch update 1\n K 10\n svn:author\n-V 8\n-tallsopp\n+V 4\n+samv\n K 8\n svn:date\n V 27\n-2009-11-12T20:29:51.098306Z\n+2009-12-19T16:17:55.862113Z\n+PROPS-END\n+\n+Node-path: branches/left-sub/README\n+Node-kind: file\n+Node-action: add\n+Prop-content-length: 10\n+Text-content-length: 7\n+Text-content-md5: fdbcfb6be9afe1121862143f226b51cf\n+Text-content-sha1: 1d1f5ea4ceb584337ffe59b8980d92e3b78dfef4\n+Content-length: 17\n+\n+PROPS-END\n+crunch\n+\n+\n+Revision-number: 11\n+Prop-content-length: 126\n+Content-length: 126\n+\n+K 7\n+svn:log\n+V 27\n+(r11) Merge left to trunk 1\n+K 10\n+svn:author\n+V 4\n+samv\n+K 8\n+svn:date\n+V 27\n+2009-12-19T16:17:56.413416Z\n PROPS-END\n \n Node-path: trunk\n Node-kind: dir\n Node-action: change\n-Prop-content-length: 53\n-Content-length: 53\n+Prop-content-length: 54\n+Content-length: 54\n \n K 13\n svn:mergeinfo\n-V 18\n-/branches/left:2-8\n+V 19\n+/branches/left:2-10\n+PROPS-END\n+\n+\n+Node-path: trunk/Makefile\n+Node-kind: file\n+Node-action: change\n+Text-content-length: 2593\n+Text-content-md5: 5ccff689fb290e00b85fe18ee50c54ba\n+Text-content-sha1: a13de8e23f1483efca3e57b2b64b0ae6f740ce10\n+Content-length: 2593\n+\n+# -DCOLLISION_CHECK if you believe that SHA1's\n+# 1461501637330902918203684832716283019655932542976 hashes do not give you\n+# enough guarantees about no collisions between objects ever hapenning.\n+#\n+# -DNSEC if you want git to care about sub-second file mtimes and ctimes.\n+# Note that you need some new glibc (at least >2.2.4) for this, and it will\n+# BREAK YOUR LOCAL DIFFS! show-diff and anything using it will likely randomly\n+# break unless your underlying filesystem supports those sub-second times\n+# (my ext3 doesn't).\n+CFLAGS=-g -O3 -Wall\n+\n+CC=gcc\n+\n+\n+PROG=   update-cache show-diff init-db write-tree read-tree commit-tree \\\n+\tcat-file fsck-cache checkout-cache diff-tree rev-tree show-files \\\n+\tcheck-files ls-tree merge-base\n+\n+all: $(PROG)\n+\n+install: $(PROG)\n+\tinstall $(PROG) $(HOME)/bin/\n+\n+LIBS= -lssl -lz\n+\n+init-db: init-db.o\n+\n+update-cache: update-cache.o read-cache.o\n+\t$(CC) $(CFLAGS) -o update-cache update-cache.o read-cache.o $(LIBS)\n+\n+show-diff: show-diff.o read-cache.o\n+\t$(CC) $(CFLAGS) -o show-diff show-diff.o read-cache.o $(LIBS)\n+\n+write-tree: write-tree.o read-cache.o\n+\t$(CC) $(CFLAGS) -o write-tree write-tree.o read-cache.o $(LIBS)\n+\n+read-tree: read-tree.o read-cache.o\n+\t$(CC) $(CFLAGS) -o read-tree read-tree.o read-cache.o $(LIBS)\n+\n+commit-tree: commit-tree.o read-cache.o\n+\t$(CC) $(CFLAGS) -o commit-tree commit-tree.o read-cache.o $(LIBS)\n+\n+cat-file: cat-file.o read-cache.o\n+\t$(CC) $(CFLAGS) -o cat-file cat-file.o read-cache.o $(LIBS)\n+\n+fsck-cache: fsck-cache.o read-cache.o object.o commit.o tree.o blob.o\n+\t$(CC) $(CFLAGS) -o fsck-cache fsck-cache.o read-cache.o object.o commit.o tree.o blob.o $(LIBS)\n+\n+checkout-cache: checkout-cache.o read-cache.o\n+\t$(CC) $(CFLAGS) -o checkout-cache checkout-cache.o read-cache.o $(LIBS)\n+\n+diff-tree: diff-tree.o read-cache.o\n+\t$(CC) $(CFLAGS) -o diff-tree diff-tree.o read-cache.o $(LIBS)\n+\n+rev-tree: rev-tree.o read-cache.o object.o commit.o tree.o blob.o\n+\t$(CC) $(CFLAGS) -o rev-tree rev-tree.o read-cache.o object.o commit.o tree.o blob.o $(LIBS)\n+\n+show-files: show-files.o read-cache.o\n+\t$(CC) $(CFLAGS) -o show-files show-files.o read-cache.o $(LIBS)\n+\n+check-files: check-files.o read-cache.o\n+\t$(CC) $(CFLAGS) -o check-files check-files.o read-cache.o $(LIBS)\n+\n+ls-tree: ls-tree.o read-cache.o\n+\t$(CC) $(CFLAGS) -o ls-tree ls-tree.o read-cache.o $(LIBS)\n+\n+merge-base: merge-base.o read-cache.o object.o commit.o tree.o blob.o\n+\t$(CC) $(CFLAGS) -o merge-base merge-base.o read-cache.o object.o commit.o tree.o blob.o $(LIBS)\n+\n+read-cache.o: cache.h\n+show-diff.o: cache.h\n+\n+clean:\n+\trm -f *.o $(PROG)\n+\n+backup: clean\n+\tcd .. ; tar czvf dircache.tar.gz dir-cache\n+\n+\n+Revision-number: 12\n+Prop-content-length: 118\n+Content-length: 118\n+\n+K 7\n+svn:log\n+V 19\n+(r12) left update 4\n+K 10\n+svn:author\n+V 4\n+samv\n+K 8\n+svn:date\n+V 27\n+2009-12-19T16:17:56.831014Z\n+PROPS-END\n+\n+Node-path: branches/left/zlonk\n+Node-kind: file\n+Node-action: add\n+Prop-content-length: 10\n+Text-content-length: 7\n+Text-content-md5: 8b9d8c7c2aaa6167e7d3407a773bbbba\n+Text-content-sha1: 9716527ebd70a75c27625cacbeb2d897c6e86178\n+Content-length: 17\n+\n+PROPS-END\n+touche\n+\n+\n+Revision-number: 13\n+Prop-content-length: 119\n+Content-length: 119\n+\n+K 7\n+svn:log\n+V 20\n+(r13) right update 2\n+K 10\n+svn:author\n+V 4\n+samv\n+K 8\n+svn:date\n+V 27\n+2009-12-19T16:17:57.341143Z\n+PROPS-END\n+\n+Node-path: branches/right/bang\n+Node-kind: file\n+Node-action: add\n+Prop-content-length: 10\n+Text-content-length: 8\n+Text-content-md5: 34c28f1d2dc6a9adeccc4265bf7516cb\n+Text-content-sha1: 0bc5bb345c0e71d28f784f12e0bd2d384c283062\n+Content-length: 18\n+\n+PROPS-END\n+thwacke\n+\n+\n+Revision-number: 14\n+Prop-content-length: 141\n+Content-length: 141\n+\n+K 7\n+svn:log\n+V 42\n+(r14) Cherry-pick right 2 commits to trunk\n+K 10\n+svn:author\n+V 4\n+samv\n+K 8\n+svn:date\n+V 27\n+2009-12-19T16:17:57.841851Z\n+PROPS-END\n+\n+Node-path: trunk\n+Node-kind: dir\n+Node-action: change\n+Prop-content-length: 75\n+Content-length: 75\n+\n+K 13\n+svn:mergeinfo\n+V 40\n+/branches/left:2-10\n+/branches/right:6-13\n PROPS-END\n \n \n@@ -767,31 +1019,147 @@ backup: clean\n \tcd .. ; tar czvf dircache.tar.gz dir-cache\n \n \n-Revision-number: 10\n-Prop-content-length: 116\n-Content-length: 116\n+Node-path: trunk/bang\n+Node-kind: file\n+Node-action: add\n+Node-copyfrom-rev: 13\n+Node-copyfrom-path: branches/right/bang\n+Text-copy-source-md5: 34c28f1d2dc6a9adeccc4265bf7516cb\n+Text-copy-source-sha1: 0bc5bb345c0e71d28f784f12e0bd2d384c283062\n+\n+\n+Revision-number: 15\n+Prop-content-length: 127\n+Content-length: 127\n \n K 7\n svn:log\n-V 13\n-left update 4\n+V 28\n+(r15) Merge right to trunk 1\n K 10\n svn:author\n-V 8\n-tallsopp\n+V 4\n+samv\n K 8\n svn:date\n V 27\n-2009-11-12T20:29:52.081644Z\n+2009-12-19T16:17:58.368520Z\n PROPS-END\n \n-Node-path: branches/left/Makefile\n+Node-path: trunk\n+Node-kind: dir\n+Node-action: change\n+Prop-content-length: 75\n+Content-length: 75\n+\n+K 13\n+svn:mergeinfo\n+V 40\n+/branches/left:2-10\n+/branches/right:2-14\n+PROPS-END\n+\n+\n+Revision-number: 16\n+Prop-content-length: 119\n+Content-length: 119\n+\n+K 7\n+svn:log\n+V 20\n+(r16) right update 3\n+K 10\n+svn:author\n+V 4\n+samv\n+K 8\n+svn:date\n+V 27\n+2009-12-19T16:17:58.779056Z\n+PROPS-END\n+\n+Node-path: branches/right/urkkk\n+Node-kind: file\n+Node-action: add\n+Prop-content-length: 10\n+Text-content-length: 6\n+Text-content-md5: 5889c8392e16251b0c80927607a03036\n+Text-content-sha1: 3934264d277a0cf886b6b1c7f2b9e56da2525302\n+Content-length: 16\n+\n+PROPS-END\n+whamm\n+\n+\n+Revision-number: 17\n+Prop-content-length: 119\n+Content-length: 119\n+\n+K 7\n+svn:log\n+V 20\n+(r17) trunk update 1\n+K 10\n+svn:author\n+V 4\n+samv\n+K 8\n+svn:date\n+V 27\n+2009-12-19T16:17:59.221851Z\n+PROPS-END\n+\n+Node-path: trunk/vronk\n Node-kind: file\n+Node-action: add\n+Prop-content-length: 10\n+Text-content-length: 4\n+Text-content-md5: b2f80fa02a7f1364b9c29d3da44bf9f9\n+Text-content-sha1: e994d980c0f2d7a3f76138bf96d57f36f9633828\n+Content-length: 14\n+\n+PROPS-END\n+pow\n+\n+\n+Revision-number: 18\n+Prop-content-length: 135\n+Content-length: 135\n+\n+K 7\n+svn:log\n+V 36\n+(r18) Merge right to left sub-branch\n+K 10\n+svn:author\n+V 4\n+samv\n+K 8\n+svn:date\n+V 27\n+2009-12-19T16:17:59.781666Z\n+PROPS-END\n+\n+Node-path: branches/left-sub\n+Node-kind: dir\n Node-action: change\n-Text-content-length: 2529\n-Text-content-md5: f6b197cc3f2e89a83e545d4bb003de73\n-Text-content-sha1: 2f656677cfec0bceec85e53036ffb63e25126f8e\n-Content-length: 2529\n+Prop-content-length: 55\n+Content-length: 55\n+\n+K 13\n+svn:mergeinfo\n+V 20\n+/branches/right:2-17\n+PROPS-END\n+\n+\n+Node-path: branches/left-sub/Makefile\n+Node-kind: file\n+Node-action: change\n+Text-content-length: 2713\n+Text-content-md5: 0afbe34f244cd662b1f97d708c687f90\n+Text-content-sha1: 46d9377d783e67a9b581da110352e799517c8a14\n+Content-length: 2713\n \n # -DCOLLISION_CHECK if you believe that SHA1's\n # 1461501637330902918203684832716283019655932542976 hashes do not give you\n@@ -809,7 +1177,7 @@ CC=gcc\n \n PROG=   update-cache show-diff init-db write-tree read-tree commit-tree \\\n \tcat-file fsck-cache checkout-cache diff-tree rev-tree show-files \\\n-\tcheck-files ls-tree merge-base\n+\tcheck-files ls-tree merge-base merge-cache\n \n all: $(PROG)\n \n@@ -859,8 +1227,11 @@ check-files: check-files.o read-cache.o\n ls-tree: ls-tree.o read-cache.o\n \t$(CC) $(CFLAGS) -o ls-tree ls-tree.o read-cache.o $(LIBS)\n \n-merge-base: merge-base.o read-cache.o\n-\t$(CC) $(CFLAGS) -o merge-base merge-base.o read-cache.o $(LIBS)\n+merge-base: merge-base.o read-cache.o object.o commit.o tree.o blob.o\n+\t$(CC) $(CFLAGS) -o merge-base merge-base.o read-cache.o object.o commit.o tree.o blob.o $(LIBS)\n+\n+merge-cache: merge-cache.o read-cache.o\n+\t$(CC) $(CFLAGS) -o merge-cache merge-cache.o read-cache.o $(LIBS)\n \n read-cache.o: cache.h\n show-diff.o: cache.h\n@@ -872,31 +1243,165 @@ backup: clean\n \tcd .. ; tar czvf dircache.tar.gz dir-cache\n \n \n-Revision-number: 11\n-Prop-content-length: 117\n-Content-length: 117\n+Node-path: branches/left-sub/bang\n+Node-kind: file\n+Node-action: add\n+Node-copyfrom-rev: 17\n+Node-copyfrom-path: branches/right/bang\n+Text-copy-source-md5: 34c28f1d2dc6a9adeccc4265bf7516cb\n+Text-copy-source-sha1: 0bc5bb345c0e71d28f784f12e0bd2d384c283062\n+\n+\n+Node-path: branches/left-sub/urkkk\n+Node-kind: file\n+Node-action: add\n+Node-copyfrom-rev: 17\n+Node-copyfrom-path: branches/right/urkkk\n+Text-copy-source-md5: 5889c8392e16251b0c80927607a03036\n+Text-copy-source-sha1: 3934264d277a0cf886b6b1c7f2b9e56da2525302\n+\n+\n+Revision-number: 19\n+Prop-content-length: 129\n+Content-length: 129\n \n K 7\n svn:log\n-V 14\n-right update 1\n+V 30\n+(r19) left sub-branch update 2\n K 10\n svn:author\n-V 8\n-tallsopp\n+V 4\n+samv\n K 8\n svn:date\n V 27\n-2009-11-12T20:29:53.059636Z\n+2009-12-19T16:18:00.200531Z\n PROPS-END\n \n-Node-path: branches/right/Makefile\n+Node-path: branches/left-sub/wham_eth\n+Node-kind: file\n+Node-action: add\n+Prop-content-length: 10\n+Text-content-length: 6\n+Text-content-md5: 757bcd5818572ef3f9580052617c1c8b\n+Text-content-sha1: b165019b005c199237ba822c4404e771e93b654a\n+Content-length: 16\n+\n+PROPS-END\n+zowie\n+\n+\n+Revision-number: 20\n+Prop-content-length: 118\n+Content-length: 118\n+\n+K 7\n+svn:log\n+V 19\n+(r20) left update 5\n+K 10\n+svn:author\n+V 4\n+samv\n+K 8\n+svn:date\n+V 27\n+2009-12-19T16:18:00.659636Z\n+PROPS-END\n+\n+Node-path: branches/left/glurpp\n Node-kind: file\n+Node-action: add\n+Prop-content-length: 10\n+Text-content-length: 8\n+Text-content-md5: 14a169f628e0bb59df9c2160649d0a30\n+Text-content-sha1: ef7d929e52177767ecfcd28941f6b7f04b4131e3\n+Content-length: 18\n+\n+PROPS-END\n+eee_yow\n+\n+\n+Revision-number: 21\n+Prop-content-length: 147\n+Content-length: 147\n+\n+K 7\n+svn:log\n+V 48\n+(r21) Cherry-pick left sub-branch commit to left\n+K 10\n+svn:author\n+V 4\n+samv\n+K 8\n+svn:date\n+V 27\n+2009-12-19T16:18:01.194402Z\n+PROPS-END\n+\n+Node-path: branches/left\n+Node-kind: dir\n Node-action: change\n-Text-content-length: 2593\n-Text-content-md5: 5ccff689fb290e00b85fe18ee50c54ba\n-Text-content-sha1: a13de8e23f1483efca3e57b2b64b0ae6f740ce10\n-Content-length: 2593\n+Prop-content-length: 56\n+Content-length: 56\n+\n+K 13\n+svn:mergeinfo\n+V 21\n+/branches/left-sub:19\n+PROPS-END\n+\n+\n+Node-path: branches/left/wham_eth\n+Node-kind: file\n+Node-action: add\n+Node-copyfrom-rev: 19\n+Node-copyfrom-path: branches/left-sub/wham_eth\n+Text-copy-source-md5: 757bcd5818572ef3f9580052617c1c8b\n+Text-copy-source-sha1: b165019b005c199237ba822c4404e771e93b654a\n+\n+\n+Revision-number: 22\n+Prop-content-length: 134\n+Content-length: 134\n+\n+K 7\n+svn:log\n+V 35\n+(r22) Merge left sub-branch to left\n+K 10\n+svn:author\n+V 4\n+samv\n+K 8\n+svn:date\n+V 27\n+2009-12-19T16:18:01.679218Z\n+PROPS-END\n+\n+Node-path: branches/left\n+Node-kind: dir\n+Node-action: change\n+Prop-content-length: 79\n+Content-length: 79\n+\n+K 13\n+svn:mergeinfo\n+V 44\n+/branches/left-sub:4-19\n+/branches/right:2-17\n+PROPS-END\n+\n+\n+Node-path: branches/left/Makefile\n+Node-kind: file\n+Node-action: change\n+Text-content-length: 2713\n+Text-content-md5: 0afbe34f244cd662b1f97d708c687f90\n+Text-content-sha1: 46d9377d783e67a9b581da110352e799517c8a14\n+Content-length: 2713\n \n # -DCOLLISION_CHECK if you believe that SHA1's\n # 1461501637330902918203684832716283019655932542976 hashes do not give you\n@@ -914,7 +1419,7 @@ CC=gcc\n \n PROG=   update-cache show-diff init-db write-tree read-tree commit-tree \\\n \tcat-file fsck-cache checkout-cache diff-tree rev-tree show-files \\\n-\tcheck-files ls-tree merge-base\n+\tcheck-files ls-tree merge-base merge-cache\n \n all: $(PROG)\n \n@@ -967,6 +1472,9 @@ ls-tree: ls-tree.o read-cache.o\n merge-base: merge-base.o read-cache.o object.o commit.o tree.o blob.o\n \t$(CC) $(CFLAGS) -o merge-base merge-base.o read-cache.o object.o commit.o tree.o blob.o $(LIBS)\n \n+merge-cache: merge-cache.o read-cache.o\n+\t$(CC) $(CFLAGS) -o merge-cache merge-cache.o read-cache.o $(LIBS)\n+\n read-cache.o: cache.h\n show-diff.o: cache.h\n \n@@ -977,34 +1485,141 @@ backup: clean\n \tcd .. ; tar czvf dircache.tar.gz dir-cache\n \n \n-Revision-number: 12\n-Prop-content-length: 116\n-Content-length: 116\n+Node-path: branches/left/README\n+Node-kind: file\n+Node-action: add\n+Node-copyfrom-rev: 18\n+Node-copyfrom-path: branches/left-sub/README\n+Text-copy-source-md5: fdbcfb6be9afe1121862143f226b51cf\n+Text-copy-source-sha1: 1d1f5ea4ceb584337ffe59b8980d92e3b78dfef4\n+\n+\n+Node-path: branches/left/bang\n+Node-kind: file\n+Node-action: add\n+Node-copyfrom-rev: 18\n+Node-copyfrom-path: branches/left-sub/bang\n+Text-copy-source-md5: 34c28f1d2dc6a9adeccc4265bf7516cb\n+Text-copy-source-sha1: 0bc5bb345c0e71d28f784f12e0bd2d384c283062\n+\n+\n+Node-path: branches/left/urkkk\n+Node-kind: file\n+Node-action: add\n+Node-copyfrom-rev: 18\n+Node-copyfrom-path: branches/left-sub/urkkk\n+Text-copy-source-md5: 5889c8392e16251b0c80927607a03036\n+Text-copy-source-sha1: 3934264d277a0cf886b6b1c7f2b9e56da2525302\n+\n+\n+Revision-number: 23\n+Prop-content-length: 126\n+Content-length: 126\n \n K 7\n svn:log\n-V 13\n-Merge trunk 2\n+V 27\n+(r23) Merge left to trunk 2\n K 10\n svn:author\n-V 8\n-tallsopp\n+V 4\n+samv\n K 8\n svn:date\n V 27\n-2009-11-12T20:29:56.083003Z\n+2009-12-19T16:18:02.212349Z\n PROPS-END\n \n Node-path: trunk\n Node-kind: dir\n Node-action: change\n-Prop-content-length: 54\n-Content-length: 54\n+Prop-content-length: 99\n+Content-length: 99\n \n K 13\n svn:mergeinfo\n-V 19\n-/branches/left:2-11\n+V 64\n+/branches/left:2-22\n+/branches/left-sub:4-19\n+/branches/right:2-17\n+PROPS-END\n+\n+\n+Node-path: trunk/README\n+Node-kind: file\n+Node-action: add\n+Node-copyfrom-rev: 22\n+Node-copyfrom-path: branches/left/README\n+Text-copy-source-md5: fdbcfb6be9afe1121862143f226b51cf\n+Text-copy-source-sha1: 1d1f5ea4ceb584337ffe59b8980d92e3b78dfef4\n+\n+\n+Node-path: trunk/glurpp\n+Node-kind: file\n+Node-action: add\n+Node-copyfrom-rev: 22\n+Node-copyfrom-path: branches/left/glurpp\n+Text-copy-source-md5: 14a169f628e0bb59df9c2160649d0a30\n+Text-copy-source-sha1: ef7d929e52177767ecfcd28941f6b7f04b4131e3\n+\n+\n+Node-path: trunk/urkkk\n+Node-kind: file\n+Node-action: add\n+Node-copyfrom-rev: 22\n+Node-copyfrom-path: branches/left/urkkk\n+Text-copy-source-md5: 5889c8392e16251b0c80927607a03036\n+Text-copy-source-sha1: 3934264d277a0cf886b6b1c7f2b9e56da2525302\n+\n+\n+Node-path: trunk/wham_eth\n+Node-kind: file\n+Node-action: add\n+Node-copyfrom-rev: 22\n+Node-copyfrom-path: branches/left/wham_eth\n+Text-copy-source-md5: 757bcd5818572ef3f9580052617c1c8b\n+Text-copy-source-sha1: b165019b005c199237ba822c4404e771e93b654a\n+\n+\n+Node-path: trunk/zlonk\n+Node-kind: file\n+Node-action: add\n+Node-copyfrom-rev: 22\n+Node-copyfrom-path: branches/left/zlonk\n+Text-copy-source-md5: 8b9d8c7c2aaa6167e7d3407a773bbbba\n+Text-copy-source-sha1: 9716527ebd70a75c27625cacbeb2d897c6e86178\n+\n+\n+Revision-number: 24\n+Prop-content-length: 131\n+Content-length: 131\n+\n+K 7\n+svn:log\n+V 32\n+(r24) non-merge right to trunk 2\n+K 10\n+svn:author\n+V 4\n+samv\n+K 8\n+svn:date\n+V 27\n+2009-12-19T16:18:02.672148Z\n+PROPS-END\n+\n+Node-path: trunk\n+Node-kind: dir\n+Node-action: change\n+Prop-content-length: 99\n+Content-length: 99\n+\n+K 13\n+svn:mergeinfo\n+V 64\n+/branches/left:2-22\n+/branches/left-sub:4-19\n+/branches/right:2-22\n PROPS-END\n \n \n-- \n1.6.3.3\n"},{"id":"130147","messageId":"1261240435-8948-3-git-send-email-sam@vilain.net","threadId":"21993","inReplyTo":"1261240435-8948-2-git-send-email-sam@vilain.net","subject":"[PATCH 2/5] git-svn: memoize conversion of SVN merge ticket info to git commit ranges","fromName":"Sam Vilain","fromEmail":"sam@vilain.net","sentAt":"2009-12-19T16:33:52Z","receivedAt":"2009-12-19T16:33:52Z","isPatch":true,"sender":{"key":"sam@vilain.net","avatar":"https://gravatar.com/avatar/8fc840ca854dbf6f7065b4335e3b934951c1dca3b11db688e95e471901f8f4a8?d=mp&s=160"},"body":"Each time the svn mergeinfo ticket changes, we look it up in the rev_map;\nwhen there are a lot of merged branches, this will result in many repeated\nlookups of the same information for subsequent commits.  Arrange the slow\npart of the function so that it may be memoized, and memoize it.  The more\nexpensive revision walking operation can be memoized separately.\n\nSigned-off-by: Sam Vilain <sam@vilain.net>\n---\n git-svn.perl |   91 ++++++++++++++++++++++++++++++++++-----------------------\n 1 files changed, 54 insertions(+), 37 deletions(-)\n\ndiff --git a/git-svn.perl b/git-svn.perl\nindex a4b052c..3b17a83 100755\n--- a/git-svn.perl\n+++ b/git-svn.perl\n@@ -1634,6 +1634,7 @@ use Carp qw/croak/;\n use File::Path qw/mkpath/;\n use File::Copy qw/copy/;\n use IPC::Open3;\n+use Memoize;  # core since 5.8.0, Jul 2002\n \n my ($_gc_nr, $_gc_period);\n \n@@ -2967,6 +2968,55 @@ sub find_extra_svk_parents {\n \t}\n }\n \n+sub lookup_svn_merge {\n+\tmy $uuid = shift;\n+\tmy $url = shift;\n+\tmy $merge = shift;\n+\n+\tmy ($source, $revs) = split \":\", $merge;\n+\tmy $path = $source;\n+\t$path =~ s{^/}{};\n+\tmy $gs = Git::SVN->find_by_url($url.$source, $url, $path);\n+\tif ( !$gs ) {\n+\t\twarn \"Couldn't find revmap for $url$source\\n\";\n+\t\tnext;\n+\t}\n+\tmy @ranges = split \",\", $revs;\n+\tmy ($tip, $tip_commit);\n+\tmy @merged_commit_ranges;\n+\t# find the tip\n+\tfor my $range ( @ranges ) {\n+\t\tmy ($bottom, $top) = split \"-\", $range;\n+\t\t$top ||= $bottom;\n+\t\tmy $bottom_commit =\n+\t\t\t$gs->rev_map_get($bottom, $uuid) ||\n+\t\t\t$gs->rev_map_get($bottom+1, $uuid);\n+\t\tmy $top_commit;\n+\t\tfor (; !$top_commit && $top >= $bottom; --$top) {\n+\t\t\t$top_commit =\n+\t\t\t\t$gs->rev_map_get($top, $uuid);\n+\t\t}\n+\n+\t\tunless ($top_commit and $bottom_commit) {\n+\t\t\twarn \"W:unknown path/rev in svn:mergeinfo \"\n+\t\t\t\t.\"dirprop: $source:$range\\n\";\n+\t\t\tnext;\n+\t\t}\n+\n+\t\tpush @merged_commit_ranges,\n+\t\t\t\"$bottom_commit..$top_commit\";\n+\n+\t\tif ( !defined $tip or $top > $tip ) {\n+\t\t\t$tip = $top;\n+\t\t\t$tip_commit = $top_commit;\n+\t\t}\n+\t}\n+\treturn ($tip_commit, @merged_commit_ranges);\n+}\n+BEGIN {\n+\tmemoize 'lookup_svn_merge';\n+}\n+\n # note: this function should only be called if the various dirprops\n # have actually changed\n sub find_extra_svn_parents {\n@@ -2981,44 +3031,11 @@ sub find_extra_svn_parents {\n \tmy @merge_tips;\n \tmy @merged_commit_ranges;\n \tmy $url = $self->rewrite_root || $self->{url};\n+\tmy $uuid = $self->ra_uuid;\n \tfor my $merge ( @merges ) {\n-\t\tmy ($source, $revs) = split \":\", $merge;\n-\t\tmy $path = $source;\n-\t\t$path =~ s{^/}{};\n-\t\tmy $gs = Git::SVN->find_by_url($url.$source, $url, $path);\n-\t\tif ( !$gs ) {\n-\t\t\twarn \"Couldn't find revmap for $url$source\\n\";\n-\t\t\tnext;\n-\t\t}\n-\t\tmy @ranges = split \",\", $revs;\n-\t\tmy ($tip, $tip_commit);\n-\t\t# find the tip\n-\t\tfor my $range ( @ranges ) {\n-\t\t\tmy ($bottom, $top) = split \"-\", $range;\n-\t\t\t$top ||= $bottom;\n-\t\t\tmy $bottom_commit =\n-\t\t\t\t$gs->rev_map_get($bottom, $self->ra_uuid) ||\n-\t\t\t\t$gs->rev_map_get($bottom+1, $self->ra_uuid);\n-\t\t\tmy $top_commit;\n-\t\t\tfor (; !$top_commit && $top >= $bottom; --$top) {\n-\t\t\t\t$top_commit =\n-\t\t\t\t\t$gs->rev_map_get($top, $self->ra_uuid);\n-\t\t\t}\n-\n-\t\t\tunless ($top_commit and $bottom_commit) {\n-\t\t\t\twarn \"W:unknown path/rev in svn:mergeinfo \"\n-\t\t\t\t\t.\"dirprop: $source:$range\\n\";\n-\t\t\t\tnext;\n-\t\t\t}\n-\n-\t\t\tpush @merged_commit_ranges,\n-\t\t\t\t\"$bottom_commit..$top_commit\";\n-\n-\t\t\tif ( !defined $tip or $top > $tip ) {\n-\t\t\t\t$tip = $top;\n-\t\t\t\t$tip_commit = $top_commit;\n-\t\t\t}\n-\t\t}\n+\t\tmy ($tip_commit, @ranges) =\n+\t\t\tlookup_svn_merge( $uuid, $url, $merge );\n+\t\tpush @merged_commit_ranges, @ranges;\n \t\tunless (!$tip_commit or\n \t\t\t\tgrep { $_ eq $tip_commit } @$parents ) {\n \t\t\tpush @merge_tips, $tip_commit;\n-- \n1.6.3.3\n"},{"id":"130146","messageId":"1261240435-8948-4-git-send-email-sam@vilain.net","threadId":"21993","inReplyTo":"1261240435-8948-3-git-send-email-sam@vilain.net","subject":"[PATCH 3/5] git-svn: fix some mistakes with interpreting SVN mergeinfo commit ranges","fromName":"Sam Vilain","fromEmail":"sam@vilain.net","sentAt":"2009-12-19T16:33:53Z","receivedAt":"2009-12-19T16:33:53Z","isPatch":true,"sender":{"key":"sam@vilain.net","avatar":"https://gravatar.com/avatar/8fc840ca854dbf6f7065b4335e3b934951c1dca3b11db688e95e471901f8f4a8?d=mp&s=160"},"body":"SVN's list of commit ranges in mergeinfo tickets is inclusive, whereas\ngit commit ranges are exclusive on the left hand side.  Also, the end\npoints of the commit ranges may not exist; they simply delineate\nranges of commits which may or may not exist.  Fix these two mistakes.\n\nSigned-off-by: Sam Vilain <sam@vilain.net>\n---\n git-svn.perl             |   12 +++---------\n t/t9151-svn-mergeinfo.sh |    2 +-\n 2 files changed, 4 insertions(+), 10 deletions(-)\n\ndiff --git a/git-svn.perl b/git-svn.perl\nindex 3b17a83..9cf4a3e 100755\n--- a/git-svn.perl\n+++ b/git-svn.perl\n@@ -2988,14 +2988,8 @@ sub lookup_svn_merge {\n \tfor my $range ( @ranges ) {\n \t\tmy ($bottom, $top) = split \"-\", $range;\n \t\t$top ||= $bottom;\n-\t\tmy $bottom_commit =\n-\t\t\t$gs->rev_map_get($bottom, $uuid) ||\n-\t\t\t$gs->rev_map_get($bottom+1, $uuid);\n-\t\tmy $top_commit;\n-\t\tfor (; !$top_commit && $top >= $bottom; --$top) {\n-\t\t\t$top_commit =\n-\t\t\t\t$gs->rev_map_get($top, $uuid);\n-\t\t}\n+\t\tmy $bottom_commit = $gs->find_rev_after( $bottom, 1, $top );\n+\t\tmy $top_commit = $gs->find_rev_before( $top, 1, $bottom );\n \n \t\tunless ($top_commit and $bottom_commit) {\n \t\t\twarn \"W:unknown path/rev in svn:mergeinfo \"\n@@ -3004,7 +2998,7 @@ sub lookup_svn_merge {\n \t\t}\n \n \t\tpush @merged_commit_ranges,\n-\t\t\t\"$bottom_commit..$top_commit\";\n+\t\t\t\"$bottom_commit^..$top_commit\";\n \n \t\tif ( !defined $tip or $top > $tip ) {\n \t\t\t$tip = $top;\ndiff --git a/t/t9151-svn-mergeinfo.sh b/t/t9151-svn-mergeinfo.sh\nindex dc3478f..f6e00ea 100755\n--- a/t/t9151-svn-mergeinfo.sh\n+++ b/t/t9151-svn-mergeinfo.sh\n@@ -33,7 +33,7 @@ test_expect_success 'svn non-merge merge commits did not become git merge commit\n \t[ -z \"$bad_non_merges\" ]\n \t'\n \n-test_expect_failure 'everything got merged in the end' '\n+test_expect_success 'everything got merged in the end' '\n \tunmerged=$(git rev-list --all --not master)\n \t[ -z \"$unmerged\" ]\n \t'\n-- \n1.6.3.3\n"},{"id":"130150","messageId":"1261240435-8948-5-git-send-email-sam@vilain.net","threadId":"21993","inReplyTo":"1261240435-8948-4-git-send-email-sam@vilain.net","subject":"[PATCH 4/5] git-svn: exclude already merged tips using one rev-list call","fromName":"Sam Vilain","fromEmail":"sam@vilain.net","sentAt":"2009-12-19T16:33:54Z","receivedAt":"2009-12-19T16:33:54Z","isPatch":true,"sender":{"key":"sam@vilain.net","avatar":"https://gravatar.com/avatar/8fc840ca854dbf6f7065b4335e3b934951c1dca3b11db688e95e471901f8f4a8?d=mp&s=160"},"body":"The old function would have to check all mentioned merge tips, every time\nthat the mergeinfo ticket changed.  This involved 1-2 rev-list operation\nfor each listed mergeinfo line.  If there are a lot of feature branches\nbeing merged into a trunk, this makes for a very expensive operation for\ndetecting the new parents on every merge.\n\nThis new version first uses a single 'rev-list' to figure out which commit\nranges are already reachable from the parents.  This is used to eliminate\nthe already merged branches from the list.\n\nSigned-off-by: Sam Vilain <sam@vilain.net>\n---\n git-svn.perl |   52 ++++++++++++++++++++++++++++++++++++++++++++++++----\n 1 files changed, 48 insertions(+), 4 deletions(-)\n\ndiff --git a/git-svn.perl b/git-svn.perl\nindex 9cf4a3e..7a790d7 100755\n--- a/git-svn.perl\n+++ b/git-svn.perl\n@@ -3011,6 +3011,41 @@ BEGIN {\n \tmemoize 'lookup_svn_merge';\n }\n \n+sub parents_exclude {\n+\tmy $parents = shift;\n+\tmy @commits = @_;\n+\treturn unless @commits;\n+\n+\tmy @excluded;\n+\tmy $excluded;\n+\tdo {\n+\t\tmy @cmd = ('rev-list', \"-1\", @commits, \"--not\", @$parents );\n+\t\t$excluded = command_oneline(@cmd);\n+\t\tif ( $excluded ) {\n+\t\t\tmy @new;\n+\t\t\tmy $found;\n+\t\t\tfor my $commit ( @commits ) {\n+\t\t\t\tif ( $commit eq $excluded ) {\n+\t\t\t\t\tpush @excluded, $commit;\n+\t\t\t\t\t$found++;\n+\t\t\t\t\tlast;\n+\t\t\t\t}\n+\t\t\t\telse {\n+\t\t\t\t\tpush @new, $commit;\n+\t\t\t\t}\n+\t\t\t}\n+\t\t\tdie \"saw commit '$excluded' in rev-list output, \"\n+\t\t\t\t.\"but we didn't ask for that commit (wanted: @commits --not @$parents)\"\n+\t\t\t\t\tunless $found;\n+\t\t\t@commits = @new;\n+\t\t}\n+\t}\n+\t\twhile ($excluded and @commits);\n+\n+\treturn @excluded;\n+}\n+\n+\n # note: this function should only be called if the various dirprops\n # have actually changed\n sub find_extra_svn_parents {\n@@ -3023,23 +3058,32 @@ sub find_extra_svn_parents {\n \t# are now marked as merge, we can add the tip as a parent.\n \tmy @merges = split \"\\n\", $mergeinfo;\n \tmy @merge_tips;\n-\tmy @merged_commit_ranges;\n \tmy $url = $self->rewrite_root || $self->{url};\n \tmy $uuid = $self->ra_uuid;\n+\tmy %ranges;\n \tfor my $merge ( @merges ) {\n \t\tmy ($tip_commit, @ranges) =\n \t\t\tlookup_svn_merge( $uuid, $url, $merge );\n-\t\tpush @merged_commit_ranges, @ranges;\n \t\tunless (!$tip_commit or\n \t\t\t\tgrep { $_ eq $tip_commit } @$parents ) {\n \t\t\tpush @merge_tips, $tip_commit;\n+\t\t\t$ranges{$tip_commit} = \\@ranges;\n \t\t} else {\n \t\t\tpush @merge_tips, undef;\n \t\t}\n \t}\n+\n+\tmy %excluded = map { $_ => 1 }\n+\t\tparents_exclude($parents, grep { defined } @merge_tips);\n+\n+\t# check merge tips for new parents\n+\tmy @new_parents;\n \tfor my $merge_tip ( @merge_tips ) {\n \t\tmy $spec = shift @merges;\n-\t\tnext unless $merge_tip;\n+\t\tnext unless $merge_tip and $excluded{$merge_tip};\n+\n+\t\tmy $ranges = $ranges{$merge_tip};\n+\n \t\tmy @cmd = ('rev-list', \"-1\", $merge_tip,\n \t\t\t   \"--not\", @$parents );\n \t\tmy ($msg_fh, $ctx) = command_output_pipe(@cmd);\n@@ -3049,7 +3093,7 @@ sub find_extra_svn_parents {\n \t\t}\n \t\tcommand_close_pipe($msg_fh, $ctx);\n \t\tif ( $new ) {\n-\t\t\tpush @cmd, @merged_commit_ranges;\n+\t\t\tpush @cmd, @$ranges;\n \t\t\tmy ($msg_fh, $ctx) = command_output_pipe(@cmd);\n \t\t\tmy $unmerged;\n \t\t\twhile ( <$msg_fh> ) {\n-- \n1.6.3.3\n"},{"id":"130149","messageId":"1261240435-8948-6-git-send-email-sam@vilain.net","threadId":"21993","inReplyTo":"1261240435-8948-5-git-send-email-sam@vilain.net","subject":"[PATCH 5/5] git-svn: detect cherry-picks correctly.","fromName":"Sam Vilain","fromEmail":"sam@vilain.net","sentAt":"2009-12-19T16:33:55Z","receivedAt":"2009-12-19T16:33:55Z","isPatch":true,"sender":{"key":"sam@vilain.net","avatar":"https://gravatar.com/avatar/8fc840ca854dbf6f7065b4335e3b934951c1dca3b11db688e95e471901f8f4a8?d=mp&s=160"},"body":"The old function was incorrect; in some instances it marks a cherry picked\nrange as a merged branch (because of an incorrect assumption that\n'rev-list COMMIT --not RANGE' would work).  This is replaced with a\nfunction which should detect them correctly, memoized to limit the expense\nof dealing with branches with many cherry picks to one 'merge-base' call\nper merge, per branch which used cherry picking.\n\nSigned-off-by: Sam Vilain <sam@vilain.net>\n---\n git-svn.perl             |   87 +++++++++++++++++++++++++++++++++------------\n t/t9151-svn-mergeinfo.sh |    4 +-\n 2 files changed, 66 insertions(+), 25 deletions(-)\n\ndiff --git a/git-svn.perl b/git-svn.perl\nindex 7a790d7..f06e535 100755\n--- a/git-svn.perl\n+++ b/git-svn.perl\n@@ -3007,8 +3007,35 @@ sub lookup_svn_merge {\n \t}\n \treturn ($tip_commit, @merged_commit_ranges);\n }\n+\n+sub _rev_list {\n+\tmy ($msg_fh, $ctx) = command_output_pipe(\n+\t\t\"rev-list\", @_,\n+\t       );\n+\tmy @rv;\n+\twhile ( <$msg_fh> ) {\n+\t\tchomp;\n+\t\tpush @rv, $_;\n+\t}\n+\tcommand_close_pipe($msg_fh, $ctx);\n+\t@rv;\n+}\n+\n+sub check_cherry_pick {\n+\tmy $base = shift;\n+\tmy $tip = shift;\n+\tmy @ranges = @_;\n+\tmy %commits = map { $_ => 1 }\n+\t\t_rev_list(\"--no-merges\", $tip, \"--not\", $base);\n+\tfor my $range ( @ranges ) {\n+\t\tdelete @commits{_rev_list($range)};\n+\t}\n+\treturn (keys %commits);\n+}\n+\n BEGIN {\n \tmemoize 'lookup_svn_merge';\n+\tmemoize 'check_cherry_pick';\n }\n \n sub parents_exclude {\n@@ -3084,32 +3111,46 @@ sub find_extra_svn_parents {\n \n \t\tmy $ranges = $ranges{$merge_tip};\n \n-\t\tmy @cmd = ('rev-list', \"-1\", $merge_tip,\n-\t\t\t   \"--not\", @$parents );\n-\t\tmy ($msg_fh, $ctx) = command_output_pipe(@cmd);\n-\t\tmy $new;\n-\t\twhile ( <$msg_fh> ) {\n-\t\t\t$new=1;last;\n-\t\t}\n-\t\tcommand_close_pipe($msg_fh, $ctx);\n-\t\tif ( $new ) {\n-\t\t\tpush @cmd, @$ranges;\n-\t\t\tmy ($msg_fh, $ctx) = command_output_pipe(@cmd);\n-\t\t\tmy $unmerged;\n-\t\t\twhile ( <$msg_fh> ) {\n-\t\t\t\t$unmerged=1;last;\n-\t\t\t}\n-\t\t\tcommand_close_pipe($msg_fh, $ctx);\n-\t\t\tif ( $unmerged ) {\n-\t\t\t\twarn \"W:svn cherry-pick ignored ($spec)\\n\";\n-\t\t\t} else {\n-\t\t\t\twarn\n-\t\t\t\t  \"Found merge parent (svn:mergeinfo prop): \",\n-\t\t\t\t  $merge_tip, \"\\n\";\n-\t\t\t\tpush @$parents, $merge_tip;\n+\t\t# check out 'new' tips\n+\t\tmy $merge_base = command_oneline(\n+\t\t\t\"merge-base\",\n+\t\t\t@$parents, $merge_tip,\n+\t\t       );\n+\n+\t\t# double check that there are no missing non-merge commits\n+\t\tmy (@incomplete) = check_cherry_pick(\n+\t\t\t$merge_base, $merge_tip,\n+\t\t\t@$ranges,\n+\t\t       );\n+\n+\t\tif ( @incomplete ) {\n+\t\t\twarn \"W:svn cherry-pick ignored ($spec) - missing \"\n+\t\t\t\t.@incomplete.\" commit(s) (eg $incomplete[0])\\n\";\n+\t\t} else {\n+\t\t\twarn\n+\t\t\t\t\"Found merge parent (svn:mergeinfo prop): \",\n+\t\t\t\t\t$merge_tip, \"\\n\";\n+\t\t\tpush @new_parents, $merge_tip;\n+\t\t}\n+\t}\n+\n+\t# cater for merges which merge commits from multiple branches\n+\tif ( @new_parents > 1 ) {\n+\t\tfor ( my $i = 0; $i <= $#new_parents; $i++ ) {\n+\t\t\tfor ( my $j = 0; $j <= $#new_parents; $j++ ) {\n+\t\t\t\tnext if $i == $j;\n+\t\t\t\tnext unless $new_parents[$i];\n+\t\t\t\tnext unless $new_parents[$j];\n+\t\t\t\tmy $revs = command_oneline(\n+\t\t\t\t\t\"rev-list\", \"-1\", \"$i..$j\",\n+\t\t\t\t       );\n+\t\t\t\tif ( !$revs ) {\n+\t\t\t\t\tundef($new_parents[$i]);\n+\t\t\t\t}\n \t\t\t}\n \t\t}\n \t}\n+\tpush @$parents, grep { defined } @new_parents;\n }\n \n sub make_log_entry {\ndiff --git a/t/t9151-svn-mergeinfo.sh b/t/t9151-svn-mergeinfo.sh\nindex f6e00ea..359eeaa 100755\n--- a/t/t9151-svn-mergeinfo.sh\n+++ b/t/t9151-svn-mergeinfo.sh\n@@ -15,13 +15,13 @@ test_expect_success 'load svn dump' \"\n \tgit svn fetch --all\n \t\"\n \n-test_expect_failure 'all svn merges became git merge commits' '\n+test_expect_success 'all svn merges became git merge commits' '\n \tunmarked=$(git rev-list --parents --all --grep=Merge |\n \t\tgrep -v \" .* \" | cut -f1 -d\" \")\n \t[ -z \"$unmarked\" ]\n \t'\n \n-test_expect_failure 'cherry picks did not become git merge commits' '\n+test_expect_success 'cherry picks did not become git merge commits' '\n \tbad_cherries=$(git rev-list --parents --all --grep=Cherry |\n \t\tgrep \" .* \" | cut -f1 -d\" \")\n \t[ -z \"$bad_cherries\" ]\n-- \n1.6.3.3\n"},{"id":"130151","messageId":"1261240658.20752.5.camel@denix","threadId":"21993","inReplyTo":"1261240435-8948-3-git-send-email-sam@vilain.net","subject":"Re: [PATCH 2/5] git-svn: memoize conversion of SVN merge ticket info to git commit ranges","fromName":"Sam Vilain","fromEmail":"sam@vilain.net","sentAt":"2009-12-19T16:37:38Z","receivedAt":"2009-12-19T16:37:38Z","isPatch":true,"sender":{"key":"sam@vilain.net","avatar":"https://gravatar.com/avatar/8fc840ca854dbf6f7065b4335e3b934951c1dca3b11db688e95e471901f8f4a8?d=mp&s=160"},"body":"On Sun, 2009-12-20 at 05:33 +1300, Sam Vilain wrote:\n> Each time the svn mergeinfo ticket changes, we look it up in the rev_map;\n> when there are a lot of merged branches, this will result in many repeated\n> lookups of the same information for subsequent commits.  Arrange the slow\n> part of the function so that it may be memoized, and memoize it.  The more\n> expensive revision walking operation can be memoized separately.\n\nSorry, that text was an old revision.  Read as:\n\nEach time the svn mergeinfo ticket changes, we look it up in the\nrev_map; when there are a lot of merged branches, this will result in\nmany repeated lookups of the same information for subsequent commits.\nArrange that part of the function so that it may be memoized, and\nmemoize it.\n\nSam\n"},{"id":"130152","messageId":"1261240968.20752.8.camel@denix","threadId":"21993","inReplyTo":"1261240435-8948-1-git-send-email-sam@vilain.net","subject":"Re: Efficiency and correctness patches for git-svn mergeinfo support","fromName":"Sam Vilain","fromEmail":"sam@vilain.net","sentAt":"2009-12-19T16:42:48Z","receivedAt":"2009-12-19T16:42:48Z","isPatch":false,"sender":{"key":"sam@vilain.net","avatar":"https://gravatar.com/avatar/8fc840ca854dbf6f7065b4335e3b934951c1dca3b11db688e95e471901f8f4a8?d=mp&s=160"},"body":"On Sun, 2009-12-20 at 05:33 +1300, Sam Vilain wrote:\n> This series implements some efficiency enhancements; particularly in\n> dealing with repositories which have a single trunk branch which\n> receives many merges of feature branches and/or cherry-picks.  It also\n> fixes a number of corner cases in the merge conversion code.\n> \n> It would be nice if the people who have experienced slow git-svn\n> performance in these situations could test that this fixes the\n> performance issues, and that the resulting repositories seem to have\n> correct contents.\n> \n> Eric, I'm using Alex's trick of a single commit which adds failing\n> tests - marked as _expect_failure - and then marked them as succeeding\n> as the series progresses.\n\nMore useful info:\n\n git-svn.perl               |  220 +++++++++----\n t/t9151-svn-mergeinfo.sh   |   27 ++-\n t/t9151/make-svnmerge-dump |  166 ++++++---\n t/t9151/svn-mergeinfo.dump |  839\n++++++++++++++++++++++++++++++++++++++------\n 4 files changed, 1018 insertions(+), 234 deletions(-)\n\nAnd available at git://github.com/samv/git (branch mergeinfo-fixes)\n\nSam\n"},{"id":"130162","messageId":"6b2f9b1d0912191415n560a5a58xbe6390b1fcade854@mail.gmail.com","threadId":"21993","inReplyTo":"1261240435-8948-1-git-send-email-sam@vilain.net","subject":"Re: Efficiency and correctness patches for git-svn mergeinfo support","fromName":"Andrew Myrick","fromEmail":"amyrick@gmail.com","sentAt":"2009-12-19T22:15:56Z","receivedAt":"2009-12-19T22:15:56Z","isPatch":false,"sender":{"key":"amyrick@gmail.com","avatar":null},"body":"> It would be nice if the people who have experienced slow git-svn\n> performance in these situations could test that this fixes the\n> performance issues, and that the resulting repositories seem to have\n> correct contents.\n\nI tried cloning from a fairly recent revision that I knew was after\nour switchover to svn 1.5, and I received a number of these errors:\n\n   Couldn't find revmap for [branch]\n   Exiting subroutine via next at /Users/adm/libexec/git-core/git-svn line 2983.\n   Exiting subroutine via next at /Users/adm/libexec/git-core/git-svn line 2983.\n   Exiting subroutine via next at /Users/adm/libexec/git-core/git-svn line 2983.\n\nI'm not sure if this is expected, since I didn't clone from the whole\nrepo, but it did cause a lot of spew.  I'm starting a fresh clone now,\nbut it takes a few days to get through the whole repository.  I'm\nfairly new to git, so I would welcome any tips on how I can test this\nmore quickly.\n\n-Andrew\n"},{"id":"130194","messageId":"1261343240.20752.20.camel@denix","threadId":"21993","inReplyTo":"6b2f9b1d0912191415n560a5a58xbe6390b1fcade854@mail.gmail.com","subject":"Re: Efficiency and correctness patches for git-svn mergeinfo support","fromName":"Sam Vilain","fromEmail":"sam@vilain.net","sentAt":"2009-12-20T21:07:20Z","receivedAt":"2009-12-20T21:07:20Z","isPatch":false,"sender":{"key":"sam@vilain.net","avatar":"https://gravatar.com/avatar/8fc840ca854dbf6f7065b4335e3b934951c1dca3b11db688e95e471901f8f4a8?d=mp&s=160"},"body":"On Sat, 2009-12-19 at 14:15 -0800, Andrew Myrick wrote:\n> I tried cloning from a fairly recent revision that I knew was after\n> our switchover to svn 1.5, and I received a number of these errors:\n> \n>    Couldn't find revmap for [branch]\n>    Exiting subroutine via next at /Users/adm/libexec/git-core/git-svn line 2983.\n>    Exiting subroutine via next at /Users/adm/libexec/git-core/git-svn line 2983.\n>    Exiting subroutine via next at /Users/adm/libexec/git-core/git-svn line 2983.\n> \n> I'm not sure if this is expected, since I didn't clone from the whole\n> repo, but it did cause a lot of spew.  I'm starting a fresh clone now,\n> but it takes a few days to get through the whole repository.  I'm\n> fairly new to git, so I would welcome any tips on how I can test this\n> more quickly.\n\nWhoops, no, not expected, I'll post a minor correction.  That means that\nthe branch which was merged in does not have git-svn metadata; ie, it's\nnot being tracked explicitly.  If people are doing merging of things\nwhich aren't roots of branches you would expect this.  SVN, like\nPerforce, supports a confusing amount of flexibility in its merge\ntracking.  If [branch] is a real branch, then you'll want to see why it\ndoesn't have metadata yet.  Is it really a sub-tree of a real branch?\nYou could fetch it independently using a separate git-svn remote, or you\ncould ignore the warning; it should be relatively self-evident what\nhappened from the merge message and the contents of the changeset.\n\nNote if your repository was significantly re-organized at any point, it\nwill pay to treat each section of history as a separate import project,\nand stitch the results together afterwards using grafts and\nfilter-branch.\n\nThis version should be *significantly* faster than the old one.  ie, it\nshould not take a minute per commit while importing the heavily\nmerged-into integration branch.  Possibly a few seconds at most.\n\nSam\n"},{"id":"130195","messageId":"1261344246.20752.24.camel@denix","threadId":"21993","inReplyTo":"1261240435-8948-3-git-send-email-sam@vilain.net","subject":"Re: [PATCH 2/5] git-svn: memoize conversion of SVN merge ticket info to git commit ranges","fromName":"Sam Vilain","fromEmail":"sam@vilain.net","sentAt":"2009-12-20T21:24:06Z","receivedAt":"2009-12-20T21:24:06Z","isPatch":true,"sender":{"key":"sam@vilain.net","avatar":"https://gravatar.com/avatar/8fc840ca854dbf6f7065b4335e3b934951c1dca3b11db688e95e471901f8f4a8?d=mp&s=160"},"body":"On Sun, 2009-12-20 at 05:33 +1300, Sam Vilain wrote:\n> Each time the svn mergeinfo ticket changes, we look it up in the rev_map;\n> when there are a lot of merged branches, this will result in many repeated\n> lookups of the same information for subsequent commits.  Arrange the slow\n> part of the function so that it may be memoized, and memoize it.  The more\n> expensive revision walking operation can be memoized separately.\n> \n> Signed-off-by: Sam Vilain <sam@vilain.net>\n> ---\n>  git-svn.perl |   91 ++++++++++++++++++++++++++++++++++-----------------------\n>  1 files changed, 54 insertions(+), 37 deletions(-)\n> \n> diff --git a/git-svn.perl b/git-svn.perl\n> index a4b052c..3b17a83 100755\n> --- a/git-svn.perl\n> +++ b/git-svn.perl\n> @@ -1634,6 +1634,7 @@ use Carp qw/croak/;\n>  use File::Path qw/mkpath/;\n>  use File::Copy qw/copy/;\n>  use IPC::Open3;\n> +use Memoize;  # core since 5.8.0, Jul 2002\n>  \n>  my ($_gc_nr, $_gc_period);\n>  \n> @@ -2967,6 +2968,55 @@ sub find_extra_svk_parents {\n>  \t}\n>  }\n>  \n> +sub lookup_svn_merge {\n> +\tmy $uuid = shift;\n> +\tmy $url = shift;\n> +\tmy $merge = shift;\n> +\n> +\tmy ($source, $revs) = split \":\", $merge;\n> +\tmy $path = $source;\n> +\t$path =~ s{^/}{};\n> +\tmy $gs = Git::SVN->find_by_url($url.$source, $url, $path);\n> +\tif ( !$gs ) {\n> +\t\twarn \"Couldn't find revmap for $url$source\\n\";\n> +\t\tnext;\n> +\t}\n\nAs mentioned in the other thread, that 'next' should now be 'return'.\n\nSam\n"},{"id":"130196","messageId":"6b2f9b1d0912201403t4a801284j39591b2bcf6e9f93@mail.gmail.com","threadId":"21993","inReplyTo":"1261343240.20752.20.camel@denix","subject":"Re: Efficiency and correctness patches for git-svn mergeinfo support","fromName":"Andrew Myrick","fromEmail":"amyrick@gmail.com","sentAt":"2009-12-20T22:03:52Z","receivedAt":"2009-12-20T22:03:52Z","isPatch":false,"sender":{"key":"amyrick@gmail.com","avatar":null},"body":"On Sun, Dec 20, 2009 at 1:07 PM, Sam Vilain <sam@vilain.net> wrote:\n> On Sat, 2009-12-19 at 14:15 -0800, Andrew Myrick wrote:\n>> I tried cloning from a fairly recent revision that I knew was after\n>> our switchover to svn 1.5, and I received a number of these errors:\n>>\n>>    Couldn't find revmap for [branch]\n>>    Exiting subroutine via next at /Users/adm/libexec/git-core/git-svn line 2983.\n>>    Exiting subroutine via next at /Users/adm/libexec/git-core/git-svn line 2983.\n>>    Exiting subroutine via next at /Users/adm/libexec/git-core/git-svn line 2983.\n>>\n>> I'm not sure if this is expected, since I didn't clone from the whole\n>> repo, but it did cause a lot of spew.  I'm starting a fresh clone now,\n>> but it takes a few days to get through the whole repository.  I'm\n>> fairly new to git, so I would welcome any tips on how I can test this\n>> more quickly.\n>\n> Whoops, no, not expected, I'll post a minor correction.  That means that\n> the branch which was merged in does not have git-svn metadata; ie, it's\n> not being tracked explicitly.  If people are doing merging of things\n> which aren't roots of branches you would expect this.  SVN, like\n> Perforce, supports a confusing amount of flexibility in its merge\n> tracking.  If [branch] is a real branch, then you'll want to see why it\n> doesn't have metadata yet.  Is it really a sub-tree of a real branch?\n> You could fetch it independently using a separate git-svn remote, or you\n> could ignore the warning; it should be relatively self-evident what\n> happened from the merge message and the contents of the changeset.\n\nI think the problem is that I started fetching from a later revision\nthan when the branch was created and reintegrated.  There would be no\nmetadata for the branch, so a lookup for it would fail.  Fetching the\nbranch explicitly, or fetching from r1 as my current test is doing,\nshould not experience this problem.\n\n> Note if your repository was significantly re-organized at any point, it\n> will pay to treat each section of history as a separate import project,\n> and stitch the results together afterwards using grafts and\n> filter-branch.\n\nI don't believe it was, but I will keep that in mind if I run into\ntrouble.  The import from r1 went fine with git v1.6.5.*, and it's\nproceeding well now.\n\n> This version should be *significantly* faster than the old one.  ie, it\n> should not take a minute per commit while importing the heavily\n> merged-into integration branch.  Possibly a few seconds at most.\n\nSo far, most commits are fetched in under 3s with your new version.\n\nThanks for your help, Sam.\n\n-Andrew\n"},{"id":"130213","messageId":"20091221104443.GA14539@dcvr.yhbt.net","threadId":"21993","inReplyTo":"1261344246.20752.24.camel@denix","subject":"Re: [PATCH 2/5] git-svn: memoize conversion of SVN merge ticket info to git commit ranges","fromName":"Eric Wong","fromEmail":"normalperson@yhbt.net","sentAt":"2009-12-21T10:44:44Z","receivedAt":"2009-12-21T10:44:44Z","isPatch":true,"sender":{"key":"e@80x24.org","avatar":null},"body":"Sam Vilain <sam@vilain.net> wrote:\n> On Sun, 2009-12-20 at 05:33 +1300, Sam Vilain wrote:\n> > +sub lookup_svn_merge {\n> > +\tmy $uuid = shift;\n> > +\tmy $url = shift;\n> > +\tmy $merge = shift;\n> > +\n> > +\tmy ($source, $revs) = split \":\", $merge;\n> > +\tmy $path = $source;\n> > +\t$path =~ s{^/}{};\n> > +\tmy $gs = Git::SVN->find_by_url($url.$source, $url, $path);\n> > +\tif ( !$gs ) {\n> > +\t\twarn \"Couldn't find revmap for $url$source\\n\";\n> > +\t\tnext;\n> > +\t}\n> \n> As mentioned in the other thread, that 'next' should now be 'return'.\n\nThanks Sam and Andrew.  I've acked this series and pushed them out along\nwith a release notes update as well as another small fix (inline below).\n\nEric Wong (2):\n      git svn: fix --revision when fetching deleted paths\n      update release notes for git svn in 1.6.6\n\nSam Vilain (5):\n      git-svn: expand the svn mergeinfo test suite, highlighting some failures\n      git-svn: memoize conversion of SVN merge ticket info to git commit ranges\n      git-svn: fix some mistakes with interpreting SVN mergeinfo commit ranges\n      git-svn: exclude already merged tips using one rev-list call\n      git-svn: detect cherry-picks correctly.\n\n>From 577e9fcad2c8968846b365226b89778050496a78 Mon Sep 17 00:00:00 2001\nFrom: Eric Wong <normalperson@yhbt.net>\nDate: Mon, 21 Dec 2009 02:06:04 -0800\nSubject: [PATCH] git svn: fix --revision when fetching deleted paths\n\nWhen using the -r/--revision argument to fetch deleted history,\ncalling SVN::Ra::get_log() from an SVN::Ra object initialized\nto track the deleted URL will fail.\n\nThis regression was introduced in:\n  commit 4aacaeb3dc82bb6479e70e120053dc27a399460e\n  \"fix shallow clone when upstream revision is too new\"\n\nWe now ignore errors from SVN::Ra::get_log() here because using\n--revision will always override the value of $head here if\n(and only if) we're tracking deleted directories.\n\nSigned-off-by: Eric Wong <normalperson@yhbt.net>\n---\n git-svn.perl |    6 +++++-\n 1 files changed, 5 insertions(+), 1 deletions(-)\n\ndiff --git a/git-svn.perl b/git-svn.perl\nindex d362de7..a6f5061 100755\n--- a/git-svn.perl\n+++ b/git-svn.perl\n@@ -1741,7 +1741,11 @@ sub fetch_all {\n \tmy $ra = Git::SVN::Ra->new($url);\n \tmy $uuid = $ra->get_uuid;\n \tmy $head = $ra->get_latest_revnum;\n-\t$ra->get_log(\"\", $head, 0, 1, 0, 1, sub { $head = $_[1] });\n+\n+\t# ignore errors, $head revision may not even exist anymore\n+\teval { $ra->get_log(\"\", $head, 0, 1, 0, 1, sub { $head = $_[1] }) };\n+\twarn \"W: $@\\n\" if $@;\n+\n \tmy $base = defined $fetch ? $head : 0;\n \n \t# read the max revs for wildcard expansion (branches/*, tags/*)\n-- \nEric Wong\n"}]}