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

[PATCH] cvsimport: test case for severe branch import problem

From
Steffen Prohaska <prohaska@zib.de>
Date
Jun 23, 2007, 12:51 UTC
Message-ID
<11826031071213-git-send-email-prohaska@zib.de>

The result of importing branches using git-cvsimport depends on the time of the first commit to the cvs branch. If the first commit is done after other commits to the cvs trunk the result of cvsimport may be wrong. git-cvsimport creates a wrong history.

The problem is quite severe because merging such a wrongly imported branch by git may be successful without reporting any problem but the results are wrong. The result may differ from what a simple cvs merge (cvs up -j) yields.

This test script creates two cvs repositories and imports both to git. The first cvs repository has the 'wrong' order of commits and yields an error. The result of a merge in cvs and a merge in git differs. The second cvs repository has the 'right' order and the import to git runs as expected and merging yields the same results in cvs and git.

The conclusion is you must not rely on the existing cvsimport for tracking cvs branches. The history of such branches may be plain wrong. Git may display different patches than cvs would do. Merging cvs topic branches may yield completely wrong results. One obvious thing that may happen is that a merge reverts changes commited to the cvs trunk before the first commit to the cvs branch. And this would happen without any indication by git. Everything would seem to run smoothely.

This conclusion should be stated in bold at appropriate places in the documentation.

It's a pity because merging is what git is especially good at. But as long as git-cvsimport may create the wrong history you can't use git to merge cvs topic branches without double checking every detail, which makes this approach unfeasable.

Signed-off-by: Steffen Prohaska <prohaska@zib.de>
---
 t/t9600-cvsimport.sh |  184 ++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 184 insertions(+), 0 deletions(-)
 create mode 100755 t/t9600-cvsimport.sh
diff --git a/t/t9600-cvsimport.sh b/t/t9600-cvsimport.sh
new file mode 100755
index 0000000..180cd8a
--- /dev/null
+++ b/t/t9600-cvsimport.sh
@@ -0,0 +1,184 @@
+
+test_description='CVS import'
+
+. ./test-lib.sh
+
+cvs >/dev/null 2>&1
+if test $? -ne 1
+then
+    test_expect_success 'skipping git-cvsimport tests, cvs not found' :
+    test_done
+    exit
+fi
+
+CVSROOT=$(pwd)/cvsrootwrong
+CVSWORK=$(pwd)/cvsworkwrong
+CVSIMPORTED=$(pwd)/cvsimportedwrong
+export CVSROOT CVSWORK
+
+cvspscache="$HOME/.cvsps/$(echo $CVSROOT | sed -e 's%/%#%g')#src"
+rm -f $cvspscache
+
+rm -rf "$CVSROOT" "$CVSWORK"
+mkdir "$CVSROOT" &&
+cvs init &&
+mkdir "$CVSROOT/src"
+cvs -Q co -d "$CVSWORK" src &&
+rm -rf .git || 
+exit 1
+
+# sleeps are needed to fight cvsps' fuzz
+test_expect_success \
+	'initial cvs commits, tag, and branch' \
+	'( cd "$CVSWORK" &&
+	   echo "a: line 1" >>a.txt &&
+	   cvs add a.txt &&
+	   cvs commit -m "cvs commit 1" &&
+	   sleep 2 &&
+	   echo "a: line 2" >>a.txt &&
+	   echo "a: line 3" >>a.txt &&
+	   echo "a: line 4" >>a.txt &&
+	   echo "a: line 5" >>a.txt &&
+	   cvs commit -m "cvs commit 2" &&
+	   cvs tag split &&
+	   cvs tag -b branch &&
+	   sleep 2
+	)'
+
+test_expect_success \
+	'importing to git' \
+	'git-cvsimport -v -a -i -k -u -z 1 -a -C $CVSIMPORTED -o cvshead src'
+
+test_expect_success \
+	'cvs commit' \
+	'( cd "$CVSWORK" &&
+	   echo "a: line 6" >>a.txt &&
+	   cvs commit -m "cvs commit 2" &&
+	   sleep 2
+	)'
+
+test_expect_success \
+	'cvs commit' \
+	'( cd "$CVSWORK" &&
+	   echo "a: line 7" >>a.txt &&
+	   cvs commit -m "cvs commit 3" &&
+	   sleep 2
+	)'
+
+test_expect_success \
+	'importing to git' \
+	'git-cvsimport -v -a -i -k -u -z 1 -a -C $CVSIMPORTED -o cvshead src'
+
+test_expect_success \
+	'cvs commit' \
+	'( cd "$CVSWORK" &&
+	   cvs up -r branch &&
+	   sed -e 's/2/B/' a.txt >t &&
+	   mv t a.txt &&
+	   cvs commit -m "cvs commit on branch" &&
+	   cvs up -A &&
+	   sleep 2
+	)'
+
+test_expect_success \
+	'importing to git' \
+	'git-cvsimport -v -a -i -k -u -z 1 -a -C $CVSIMPORTED -o cvshead src'
+
+test_expect_success \
+	'merging' \
+    '( cd "$CVSWORK" &&
+	   cvs up -j branch
+	 ) &&
+	 (
+	   cd "$CVSIMPORTED" &&
+	   git-checkout cvshead &&
+	   git-merge branch
+	 ) &&
+	 diff -q "$CVSWORK/a.txt" "$CVSIMPORTED/a.txt"'
+
+CVSROOT=$(pwd)/cvsrootright
+CVSWORK=$(pwd)/cvsworkright
+CVSIMPORTED=$(pwd)/cvsimportedright
+export CVSROOT CVSWORK
+
+cvspscache="$HOME/.cvsps/$(echo $CVSROOT | sed -e 's%/%#%g')#src"
+rm -f $cvspscache
+
+rm -rf "$CVSROOT" "$CVSWORK"
+mkdir "$CVSROOT" &&
+cvs init &&
+mkdir "$CVSROOT/src"
+cvs -Q co -d "$CVSWORK" src &&
+rm -rf .git || 
+exit 1
+
+# sleeps are needed to fight cvsps' fuzz
+test_expect_success \
+	'initial cvs commits, tag, and branch' \
+	'( cd "$CVSWORK" &&
+	   echo "a: line 1" >>a.txt &&
+	   cvs add a.txt &&
+	   cvs commit -m "cvs commit 1" &&
+	   sleep 2 &&
+	   echo "a: line 2" >>a.txt &&
+	   echo "a: line 3" >>a.txt &&
+	   echo "a: line 4" >>a.txt &&
+	   echo "a: line 5" >>a.txt &&
+	   cvs commit -m "cvs commit 2" &&
+	   cvs tag split &&
+	   cvs tag -b branch &&
+	   sleep 2
+	)'
+
+test_expect_success \
+	'importing to git' \
+	'git-cvsimport -v -a -i -k -u -z 1 -a -C $CVSIMPORTED -o cvshead src'
+
+test_expect_success \
+	'cvs commit' \
+	'( cd "$CVSWORK" &&
+	   cvs up -r branch &&
+	   sed -e 's/2/B/' a.txt >t &&
+	   mv t a.txt &&
+	   cvs commit -m "cvs commit on branch" &&
+	   cvs up -A &&
+	   sleep 2
+	)'
+
+test_expect_success \
+	'importing to git' \
+	'git-cvsimport -v -a -i -k -u -z 1 -a -C $CVSIMPORTED -o cvshead src'
+
+test_expect_success \
+	'cvs commit' \
+	'( cd "$CVSWORK" &&
+	   echo "a: line 6" >>a.txt &&
+	   cvs commit -m "cvs commit 2" &&
+	   sleep 2
+	)'
+
+test_expect_success \
+	'cvs commit' \
+	'( cd "$CVSWORK" &&
+	   echo "a: line 7" >>a.txt &&
+	   cvs commit -m "cvs commit 3" &&
+	   sleep 2
+	)'
+
+test_expect_success \
+	'importing to git' \
+	'git-cvsimport -v -a -i -k -u -z 1 -a -C $CVSIMPORTED -o cvshead src'
+
+test_expect_success \
+	'merging' \
+    '( cd "$CVSWORK" &&
+	   cvs up -j branch
+	 ) &&
+	 (
+	   cd "$CVSIMPORTED" &&
+	   git-checkout cvshead &&
+	   git-merge branch
+	 ) &&
+	 diff -q "$CVSWORK/a.txt" "$CVSIMPORTED/a.txt"'
+
+test_done
-- 
1.5.2.2.315.gc649a
Next: Steffen Prohaska
Message 1 of 20 in “cvsimport: test case for severe branch import problem”
  1. cvsimport: test case for severe branch import problemSteffen Prohaska, Jun 23, 2007
  2. Steffen ProhaskaJun 23, 2007
  3. transplant: move a series of commits to a different parentSteffen Prohaska, Jun 23, 2007
  4. Johannes SchindelinJun 23, 2007
  5. Steffen ProhaskaJun 24, 2007
  6. Alex RiesenJun 23, 2007
  7. Steffen ProhaskaJun 24, 2007
  8. Alex RiesenJun 24, 2007
  9. Johannes SchindelinJun 24, 2007
  10. Steffen ProhaskaJun 24, 2007
  11. Johannes SixtJun 25, 2007
  12. Steffen ProhaskaJun 25, 2007
  13. Johannes SixtJun 25, 2007
  14. Alex RiesenJun 24, 2007
  15. Steffen ProhaskaJun 24, 2007
  16. Alex RiesenJun 24, 2007
  17. Steffen ProhaskaJun 24, 2007
  18. Alex RiesenJun 24, 2007
  19. Steffen ProhaskaJun 24, 2007
  20. Alex RiesenJun 24, 2007

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.