{"thread":{"id":"2223","subject":"Towards CVS code-exchange and gateways","startedAt":"2005-10-25T20:57:14Z","lastAt":"2005-10-26T20:51:30Z","messageCount":6,"participants":["Martin Langhoff","Junio C Hamano","Petr Baudis"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"10607","messageId":"46a038f90510251357l23886747s8024a4326ad4e392@mail.gmail.com","threadId":"2223","inReplyTo":null,"subject":"Towards CVS code-exchange and gateways","fromName":"Martin Langhoff","fromEmail":"martin.langhoff@gmail.com","sentAt":"2005-10-25T20:57:14Z","receivedAt":"2005-10-25T20:57:14Z","isPatch":false,"sender":{"key":"martin.langhoff@gmail.com","avatar":"https://gravatar.com/avatar/1e3f311b6c4c15836501901ca58f8c0b0667246488084ba524d8bc9867e22fd9?d=mp&s=160"},"body":"Now that I have a few cvs2git gateways (git-cvsimport running on cron)\nfor the projects we work on, I am starting to need tools to \"replay\"\nchunks of git history against external CVS repositories. So I am\nthinking of writing two new scripts which expect to be executed inside\na CVS working copy:\n\n + \"git-cvsapplypatch < patchfile\" takes a patch as formatted by\ngit-format-patch, apply using patch (with options to be strict of\nfuzzy), prepares the commit message and (optionally) autocommit if\npatch returned clean.\n\n + \"GIT_DIR=~/foo/bar/.git git-cvsreplaycommit parent:child\" takes a\npair of git revisions that must be parent/child, applies the diff on\ntext files and changes on binary objects. Prepares the commit message\nand (optionally) autocommits if the merge was clean.\n\nWhich should lead later to a git-cvsapplymbox script to automate the\nprocess further. This part of the automation is actually a bit scary:\nwith git, all your scripted merges take place in your private repo,\nand you review the result of the whole patchrun before pushing it out\nto a public repo. With cvs, if the merge turns out to apply cleanly\nbut be a really bad idea... it'll be way too late. I hope to be able\nto find a smart way to run it in \"test\" mode.\n\nIs there anyone working on a git -> cvs gateway or similar scripts?\n\ncheers,\n\n\nmartin\n"},{"id":"10634","messageId":"7vr7a9azvn.fsf@assigned-by-dhcp.cox.net","threadId":"2223","inReplyTo":"46a038f90510251357l23886747s8024a4326ad4e392@mail.gmail.com","subject":"Re: Towards CVS code-exchange and gateways","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2005-10-26T00:25:00Z","receivedAt":"2005-10-26T00:25:00Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Martin Langhoff <martin.langhoff@gmail.com> writes:\n\n> Is there anyone working on a git -> cvs gateway or similar scripts?\n\nWorking on, no, but I was thinking about something like that at\nwork (today is my non-git day but I use git on top of CVS to\ntrack my private changes in my CVS work tree which is my git\nrepo there).\n\nI maintain at 'cvs' and 'master' branch (and other git branches)\nthere, and always 'git-checkout cvs' before doing 'cvs update',\nand do 'git-commit' to slurp in the changes to the cvs side.\nThen 'git checkout master ; git pull . cvs' to sync the master\nside, work on a bit, commit.  Showing what I've done to the CVS\nside, currently I do something like this:\n\n      $ git-checkout cvs\n      $ git pull . master\n      $ git log ORIG_HEAD.. >L\n      $ cvs commit -F L\n\nThis isn't that bad because I do not care much about how the\ndevelopment history on the CVS side looks like.  But propagating\neach git commit separately to CVS side would be much better, and\nwhat you outlined should work nicely.\n"},{"id":"10636","messageId":"46a038f90510252035yb4167e1w2ee54d82896e5906@mail.gmail.com","threadId":"2223","inReplyTo":"46a038f90510251357l23886747s8024a4326ad4e392@mail.gmail.com","subject":"Re: Towards CVS code-exchange and gateways","fromName":"Martin Langhoff","fromEmail":"martin.langhoff@gmail.com","sentAt":"2005-10-26T03:35:41Z","receivedAt":"2005-10-26T03:35:41Z","isPatch":false,"sender":{"key":"martin.langhoff@gmail.com","avatar":"https://gravatar.com/avatar/1e3f311b6c4c15836501901ca58f8c0b0667246488084ba524d8bc9867e22fd9?d=mp&s=160"},"body":"Update here: Sven sent me a cool 4 line shell script that has the\nbasics. Next thing I know, and I was dumped into a boring presentation\n-- so I turned it into a more complete Perl script. Still incomplete &\nextremely untested, but showing the basics.\n\nGive me a couple more boring presentations and we'll be done ;-)\n\ncheers,\n\n\nmartin\n---\n#!/usr/bin/perl -w\n\nuse strict;\nuse Getopt::Std;\n\nunless ($ENV{GIT_DIR} && -r $ENV{GIT_DIR}){\n    die \"GIT_DIR is not defined or is unreadable\";\n}\n\nour ($opt_h, $opt_p);\n\ngetopt('hp');\n\n$opt_h && usage();\n\ndie \"Need at least one commit identifier!\" unless @ARGV;\n\n# resolve target commit\nmy $commit;\n$commit = pop @ARGV;\n$commit = `git-rev-parse --verify \"$commit\"^0\"`;\nchomp $commit;\nif ($?) {\n    die \"The commit reference did not resolve!\";\n}\n\n# resolve what parent we want\nmy $parent;\nif (@ARGV) {\n    $parent = pop @ARGV;\n    $parent =  `git-rev-parse --verify \"$parent\"^0\"`;\n    chomp $parent;\n    if ($?) {\n\tdie \"The parent reference did not resolve!\";\n    }\n}\n\n# parents from the commit itself\nmy @parents = `git-cat-file commmit $commit | grep -E '^parent\n\\\\w{40}\\$' | sed -e 's/^parent //'`;\n@parents = map { chomp } @parents;\n\nif ($parent) {\n    # double check that it's a valid parent\n    foreach my $p (@parents) {\n\tmy $found;\n\tif ($p eq $parent) {\n\t    $found = 1;\n\t    last;\n\t}; # found it\n\tdie \"Did not find $parent in the parents for this commit!\";\n    }\n} else { # we don't have a parent from the cmdline...\n    if (@parents == 1) { # it's safe to get it from the commit\n\t$parent = $parents[0];\n    } else { # or perhaps not!\n\tdie \"This commit has more than one parent -- please name the parent\nyou want to use explicitly\";\n    }\n}\n\n# grab the commit message\n`git-cat-file commit $commit | sed -e '1,/^$/d' > .msg`;\n$? && die \"Error extraction the commit message\";\n\nmy @files = `git-diff-tree -r $parent $commit | cut -f 2`;\n$? && die \"Error in git-diff-tree\";\n@files = map { chomp } @files;\n\n# check that the files are clean and up to date according to cvs\nmy $dirty;\nforeach my $f (@files) {\n    # TODO:we need to handle removed in cvs and/or new (from git)\n    my $status = `cvs status $f`;\n\n    unless ($status =~ m/Up to date/) {\n\t$dirty = 1;\n\twarn \"File $f not up to date!\\n\";\n    }\n}\nif ($dirty) {\n    die \"Exiting: your CVS tree is not clean for this merge.\";\n}\n\n###\n### NOTE: if you are planning to die() past this point\n###       you MUST call cleanupcvs(@files) before die()\n###\n\n## apply changes to binary files\nmy @bfiles = `git-diff-tree -p $parent $commit | grep '^Binary'`;\n@bfiles = map { chomp } @bfiles;\nforeach my $f (@bfiles) {\n    # check that the file in cvs matches the \"old\" file\n\n    # replace with the new file\n\n}\n\n## apply non-binary changes\n## (git-diff-tree -p $1 | patch -p1) && cvs commit -F .msg\n\n\nsub usage {\n\tprint STDERR <<END;\nUsage: GIT_DIR=/path/to/.gi ${\\basename $0}      # fetch/update GIT from CVS\n       [-h] [-p] [ parent ] commit\nEND\n\texit(1);\n}\n\n# ensure cvs is clean before we die\nsub cleanupcvs {\n    my @files = @_;\n    foreach my $f (@files) {\n\t`cvs -q update -C \"$f\"`;\n\tif ($?) {\n\t    warn \"Warning! Failed to cleanup state of $f\\n\";\n\t}\n    }\n}\n"},{"id":"10647","messageId":"20051026085302.GF30889@pasky.or.cz","threadId":"2223","inReplyTo":"46a038f90510252035yb4167e1w2ee54d82896e5906@mail.gmail.com","subject":"Re: Towards CVS code-exchange and gateways","fromName":"Petr Baudis","fromEmail":"pasky@suse.cz","sentAt":"2005-10-26T08:53:02Z","receivedAt":"2005-10-26T08:53:02Z","isPatch":false,"sender":{"key":"pasky@ucw.cz","avatar":"https://avatars.githubusercontent.com/u/18439?v=4"},"body":"Dear diary, on Wed, Oct 26, 2005 at 05:35:41AM CEST, I got a letter\nwhere Martin Langhoff <martin.langhoff@gmail.com> told me that...\n> Update here: Sven sent me a cool 4 line shell script that has the\n> basics. Next thing I know, and I was dumped into a boring presentation\n> -- so I turned it into a more complete Perl script. Still incomplete &\n> extremely untested, but showing the basics.\n> \n> Give me a couple more boring presentations and we'll be done ;-)\n\nCan I then import from the CVS incrementally later? I guess from the\ncvsimport code that it just tries to always import everything but the\nalready imported commits get the same hashes so it magically imports\n\"incrementally\"... (The code could use some descriptive comments, it is\nrather spaggetish.)\n\nIf someone really desperately needs this, BTW, you might be able to\nmerge two Monotone branches (.git and .cvssync) to get two-way\nincremental GIT and CVS interface, and then do that through Monotone.\n;-))\n\n-- \n\t\t\t\tPetr \"Pasky\" Baudis\nStuff: http://pasky.or.cz/\nVI has two modes: the one in which it beeps and the one in which\nit doesn't.\n"},{"id":"10650","messageId":"46a038f90510260211i47c8a4e1oca8be8d0833f4b68@mail.gmail.com","threadId":"2223","inReplyTo":"20051026085302.GF30889@pasky.or.cz","subject":"Re: Towards CVS code-exchange and gateways","fromName":"Martin Langhoff","fromEmail":"martin.langhoff@gmail.com","sentAt":"2005-10-26T09:11:49Z","receivedAt":"2005-10-26T09:11:49Z","isPatch":false,"sender":{"key":"martin.langhoff@gmail.com","avatar":"https://gravatar.com/avatar/1e3f311b6c4c15836501901ca58f8c0b0667246488084ba524d8bc9867e22fd9?d=mp&s=160"},"body":"On 10/26/05, Petr Baudis <pasky@suse.cz> wrote:\n> Dear diary, on Wed, Oct 26, 2005 at 05:35:41AM CEST, I got a letter\n> where Martin Langhoff <martin.langhoff@gmail.com> told me that...\n> > Update here: Sven sent me a cool 4 line shell script that has the\n> > basics. Next thing I know, and I was dumped into a boring presentation\n> > -- so I turned it into a more complete Perl script. Still incomplete &\n> > extremely untested, but showing the basics.\n> >\n> > Give me a couple more boring presentations and we'll be done ;-)\n>\n> Can I then import from the CVS incrementally later? I guess from the\n> cvsimport code that it just tries to always import everything but the\n> already imported commits get the same hashes so it magically imports\n> \"incrementally\"... (The code could use some descriptive comments, it is\n> rather spaggetish.)\n\nYes -- the cvsimport script does incremental imports. If you use\ncvsimport to bring in the commits from CVS, you must treat those\nbranches as \"read only\". But you can open new heads from them and do\nyour \"local\" work there.\n\nThat's what we do with Moodle, as you can see here:\nhttp://locke.catalyst.net.nz/gitweb?p=moodle.git;a=summary the\nbranches in uppercase are imported from CVS by a cronjob. The branches\nthat begin with \"mdl\" open off those, and we merge the cvs updates\noften.\n\nThe goal for this script that I'm drafting is to be able to push\ncommits back into cvs in a format that maximises the chance of\ngit-cherry identifying them when they are echoed back (and thus\navoiding bogus conflicts).\n\n> If someone really desperately needs this, BTW, you might be able to\n> merge two Monotone branches (.git and .cvssync) to get two-way\n> incremental GIT and CVS interface, and then do that through Monotone.\n> ;-))\n\nI'm really scared by the concept ;-)\n\nThe script has moved forward quite a bit -- and I suspect it might\neven work. Current (untested) version attached.\n\ncheers,\n\nmartin\n"},{"id":"10686","messageId":"20051026205130.GA20563@pasky.or.cz","threadId":"2223","inReplyTo":"46a038f90510260211i47c8a4e1oca8be8d0833f4b68@mail.gmail.com","subject":"Re: Towards CVS code-exchange and gateways","fromName":"Petr Baudis","fromEmail":"pasky@suse.cz","sentAt":"2005-10-26T20:51:30Z","receivedAt":"2005-10-26T20:51:30Z","isPatch":false,"sender":{"key":"pasky@ucw.cz","avatar":"https://avatars.githubusercontent.com/u/18439?v=4"},"body":"Dear diary, on Wed, Oct 26, 2005 at 11:11:49AM CEST, I got a letter\nwhere Martin Langhoff <martin.langhoff@gmail.com> told me that...\n> The goal for this script that I'm drafting is to be able to push\n> commits back into cvs in a format that maximises the chance of\n> git-cherry identifying them when they are echoed back (and thus\n> avoiding bogus conflicts).\n\nAha, so you are not aiming for proper two-way incremental i/e, and one\nwill have to cherrypick to import after an export... well, I guess that\ncan be good enough for many cases. But to use Linus' words, the really\ninteresting problem is to have the proper revision tree in the CVS heads\nas well, so that you could do normal merges. And it shouldn't be _that_\nhard either...\n\n> > If someone really desperately needs this, BTW, you might be able to\n> > merge two Monotone branches (.git and .cvssync) to get two-way\n> > incremental GIT and CVS interface, and then do that through Monotone.\n> > ;-))\n> \n> I'm really scared by the concept ;-)\n\nI *think* someone actually really did something like that. ;-)\n\n-- \n\t\t\t\tPetr \"Pasky\" Baudis\nStuff: http://pasky.or.cz/\nVI has two modes: the one in which it beeps and the one in which\nit doesn't.\n"}]}