threads / discuss / 46254

Migration from CVS to Git looses merges

Subject: Migration from CVS to Git looses merges

## tl;dr

3 messages between Jun 25, 2017 and Jun 25, 2017.

replies: 2people: 2as markdown or json

Urs Thuermann· Jun 25, 2017, 07:12 UTC · lore

I want to convert several old CVS repositories to Git. Some of these CVS repositories contain branches, which have later been merged to the main trunk. When I try to convert using cvs2git or git cvsimport the branches appear in the new git repository but they are not merged to the master branch.

Here is an example of how the branches in the CVS repository were created and merged:

    cd /tmp
    export CVSROOT=$PWD/CVS
    cvs init
    mkdir CVS/foo
    cvs co foo
    cd foo
    (date; seq 10; date) > bar
    cvs add bar
    cvs ci -m msg1                              # rev 1.1
    sleep 1
    printf "1c\n%s\n.\nwq\n" "`date`" | ed bar
    cvs ci -m msg2                              # rev 1.2
    sleep 1
    cvs tag -b a-branch
    sleep 1
    printf "1c\n%s\n.\nwq\n" "`date`" | ed bar
    cvs ci -m msg3                              # rev 1.3
    sleep 1
    cvs up -r a-branch
    printf "12c\n%s\n.\nwq\n" "`date`" | ed bar
    cvs ci -m msg-b1                            # rev 1.2.2.1
    sleep 1
    printf "12c\n%s\n.\nwq\n" "`date`" | ed bar
    cvs ci -m msg-b2                            # rev 1.2.2.2
    sleep 1
    cvs up -A
    cvs up -j a-branch
    cvs ci -m "Merge branch a-branch"           # rev 1.4
Now I have tried 2 ways to convert this to git:
1. mkdir g; cd g; git cvsimport -A <file> -m foo
2. mkdir g; cd g; git init;
   cvs2git --blobfile=foo.blob --dumpfile=foo.dump --username=urs ../CVS/foo
   cat foo.blob foo.dump | git fast-import

In both cases, the branch "a-branch" is in the git repository but is not merged with the master branch, i.e. rev 1.4 has only parent 1.3 but not 1.2.2.2. I also tried cvsimport with several regexes passed using -M to match "Merge branch a-branch", but still the same result.

How should the CVS repository be converted to git, so that the commit corresponding to rev 1.4 has two parents, 1.3 and 1.2.2.2?

urs
Andreas Schwab· Jun 25, 2017, 08:13 UTC · re: Urs Thuermann · lore

Re: Migration from CVS to Git looses merges

On Jun 25 2017, Urs Thuermann <urs@isnogud.escape.de> wrote:
> In both cases, the branch "a-branch" is in the git repository but is
> not merged with the master branch, i.e. rev 1.4 has only parent 1.3
> but not 1.2.2.2.  I also tried cvsimport with several regexes passed
> using -M to match "Merge branch a-branch", but still the same result.

Merges are recognized purely by matching the commit message, and the regexp must capture the branch name in the first subexpr. The -m option enables some default regexps but won't match your example. You can use -M 'Merge branch ([-\w]+)' to match it.

Andreas.
-- 
Andreas Schwab, schwab@linux-m68k.org
GPG Key fingerprint = 58CA 54C7 6D53 942B 1756  01D3 44D5 214B 8276 4ED5
"And now for something completely different."
Urs Thuermann· Jun 25, 2017, 09:30 UTC · re: Andreas Schwab · lore

Re: Migration from CVS to Git looses merges

Andreas Schwab <schwab@linux-m68k.org> writes:
> Merges are recognized purely by matching the commit message, and the
> regexp must capture the branch name in the first subexpr.  The -m option
> enables some default regexps but won't match your example.  You can use
> -M 'Merge branch ([-\w]+)' to match it.

Thanks, I tried again and now it works. I misread the man page and also tried enclosing the regexp in //, also tried to escape the parentheses (as in BRE), and I thought I also tried 'Merge branch (.*)'. Obviously, I missed that one since it now works.

BTW, I now looked up the regexes for -m in git-cvsimport.perl. Should probably in the man page.

I also suggest the following patch, so that -m would work with my not so uncommon merge commit message:

diff --git a/git-cvsimport.perl b/git-cvsimport.perl
index 1e4e65a..1f8044b 100755
--- a/git-cvsimport.perl
+++ b/git-cvsimport.perl
@@ -207,7 +207,7 @@ if ($#ARGV == 0) {
 
 our @mergerx = ();
 if ($opt_m) {
-	@mergerx = ( qr/\b(?:from|of|merge|merging|merged) ([-\w]+)/i );
+	@mergerx = ( qr/\b(?:from|of|merge|merging|merged) (?:branch )?([-\w]+)/i );
 }
 if (@opt_M) {
 	push (@mergerx, map { qr/$_/ } @opt_M);


urs

← back to recent threads