moving to git and preserving monticello history
Hi, we would like to switch our project over to git, however is it possible to preserve the history? I.e. to convert mcz (or wherever monticello stores it) to git commits, or do I have to start from scratch? Thanks, Peter
Hi, I believe that there should be a better solution, but if no one else answers, here is a script for moving between MC repositories, maybe if you make destination to be filetree repo it will work. https://gist.github.com/Uko/6898022 <https://gist.github.com/Uko/6898022> Uko
On 18 Feb 2015, at 19:18, Peter Uhnák <i.uhnak@gmail.com> wrote:
Hi,
we would like to switch our project over to git, however is it possible to preserve the history? I.e. to convert mcz (or wherever monticello stores it) to git commits, or do I have to start from scratch?
Thanks,
Peter
Le 18/02/2015 19:18, Peter Uhnák a écrit :
Hi,
we would like to switch our project over to git, however is it possible to preserve the history? I.e. to convert mcz (or wherever monticello stores it) to git commits, or do I have to start from scratch?
Hi Peter, if you use a Gofer script to move from Monticello to Git via GitFileTree, such as the script proposed by Yuriy, it will recreates a commit for each mcz, from oldest to newest. Git will not keep the merge information contained in the mcz if you did any, but that history will still be stored in the metadata for each package in the git repository, and you can recover it, if needs be. If you do the copy over a filetree repository, you will loose all versions except the last one. Regards, Thierry
Hi, thank you both, I've semi-successfully managed to convert it to git. However there were some problems I've encountered (mostly because I wanted more than was provided :)). So there are some changes that might be worth considering for integration. 1) it will NOT recreate a commit for each mcz from oldest to newest In fact the order seems to be random (just like all Pharo directory operations) I ended up sorting it manually; it is not perfect because it groups by packages; but the alternative (by ancestry) is much more work. ===================================================================== sortBlock := [ :x : y | (x second = y second) ifTrue: [ x fourth asNumber <= y fourth asNumber ] ifFalse: [ x second < y second ]. ]. "My-Package-Author.Number" re := '^(.+)-([^-]+)\.(\d+)$' asRegex. fileBlocks := source allVersionNames collect: [ :each | re search: each. { re subexpression: 1. "first - full string" re subexpression: 2. "second - package name" re subexpression: 3. "third - author name" re subexpression: 4. "fourth - commit name" } ]. filesSorted := fileBlocks asSortedCollection: sortBlock. files := (filesSorted collect: [ :x | x first ]) asArray. ===================================================================== 2) Git by default doesn't accept empty messages While Monticello does so I ran into a trouble. (Not sure how we ended up with empty message but whatever). This can be easily remedied with --allow-empty-message (see further down) 3) The author and date is not preserved. Obviously for collaborated project I can't just appropriate someone else's code. Also having the original date is nice. With author there's an issue that git requires an email, this can be solved with having external mapping class (or having something on MCFileTreeGitRepository class-side). 4) Ignored .class directories If you are dummy like me, use Java and have *.class in your system-wide ignore file... there's a nasty surprise waiting. :) 2+3 code) in "MCFileTreeGitRepository>>basicStoreVersion: aVersion" I moved the command to separate methods ===================================================================== c := PipeableOSProcess command: self cdCommand, (self gitAddCommand: packageDirectoryString), (self gitCommitCommand: aVersion directory: packageDirectoryString). ===================================================================== and new methods ===================================================================== MCFileTreeGitRepository>>cdCommand ^ 'cd "{1}";' format: {(self fileUtils directoryPathString: directory)} MCFileTreeGitRepository>>gitAddCommand: packageDirectoryString ^ 'git add ' , packageDirectoryString , ';' MCFileTreeGitRepository>>gitCommitCommand: aVersion directory: packageDirectoryString ^ 'git commit --allow-empty-message -m "{1}" --author="{2}" --date="{3}" -- {4};' format: {(self escapeForShell: aVersion info message convertToSystemString). (self escapeForShell: (GitAuthorConverter gitNameFor: aVersion info author)). (self escapeForShell: aVersion info timeStamp truncated asString convertToSystemString). packageDirectoryString} ===================================================================== GitAuthorConverter is just a dummy class to map Monticello author (so a global Dictionary). ===================================================================== GitAuthorConverter map: 'PeterUhnak' to: 'Peter Uhnak <i.uhnak@gmail.com>'. GitAuthorConverter gitNameFor: 'PeterUhnak' "--> returns Peter Uhnak < i.uhnak@gmail.com>'. ===================================================================== Peter
Hi Peter, thanks for raising all those issues. A few comments inlined... 2015-02-20 11:14 GMT+01:00 Peter Uhnák <i.uhnak@gmail.com>:
Hi,
thank you both, I've semi-successfully managed to convert it to git. However there were some problems I've encountered (mostly because I wanted more than was provided :)). So there are some changes that might be worth considering for integration.
1) it will NOT recreate a commit for each mcz from oldest to newest In fact the order seems to be random (just like all Pharo directory operations)
Oups. Last time I did it, it was in order :(
I ended up sorting it manually; it is not perfect because it groups by packages; but the alternative (by ancestry) is much more work. ===================================================================== sortBlock := [ :x : y | (x second = y second) ifTrue: [ x fourth asNumber <= y fourth asNumber ] ifFalse: [ x second < y second ]. ].
"My-Package-Author.Number" re := '^(.+)-([^-]+)\.(\d+)$' asRegex. fileBlocks := source allVersionNames collect: [ :each | re search: each. { re subexpression: 1. "first - full string" re subexpression: 2. "second - package name" re subexpression: 3. "third - author name" re subexpression: 4. "fourth - commit name" } ]. filesSorted := fileBlocks asSortedCollection: sortBlock.
files := (filesSorted collect: [ :x | x first ]) asArray. =====================================================================
2) Git by default doesn't accept empty messages While Monticello does so I ran into a trouble. (Not sure how we ended up with empty message but whatever). This can be easily remedied with --allow-empty-message (see further down)
Good point. Bad programmers do commits without messages :):)
3) The author and date is not preserved. Obviously for collaborated project I can't just appropriate someone else's code. Also having the original date is nice. With author there's an issue that git requires an email, this can be solved with having external mapping class (or having something on MCFileTreeGitRepository class-side).
Well, original history and author name is still there (if you reread the monticello.meta/version file), it does not appear in the git history. But, yes, some mapping may be usefull (or an automatic, fetch name from version) and a differentiation between the author name and the commiter name (I remember seeing both in git).
4) Ignored .class directories If you are dummy like me, use Java and have *.class in your system-wide ignore file... there's a nasty surprise waiting. :)
:) Try .package in the .ignore file :)
2+3 code) in "MCFileTreeGitRepository>>basicStoreVersion: aVersion" I moved the command to separate methods ===================================================================== c := PipeableOSProcess command: self cdCommand, (self gitAddCommand: packageDirectoryString), (self gitCommitCommand: aVersion directory: packageDirectoryString). =====================================================================
and new methods
===================================================================== MCFileTreeGitRepository>>cdCommand ^ 'cd "{1}";' format: {(self fileUtils directoryPathString: directory)}
MCFileTreeGitRepository>>gitAddCommand: packageDirectoryString ^ 'git add ' , packageDirectoryString , ';'
MCFileTreeGitRepository>>gitCommitCommand: aVersion directory: packageDirectoryString ^ 'git commit --allow-empty-message -m "{1}" --author="{2}" --date="{3}" -- {4};' format: {(self escapeForShell: aVersion info message convertToSystemString). (self escapeForShell: (GitAuthorConverter gitNameFor: aVersion info author)). (self escapeForShell: aVersion info timeStamp truncated asString convertToSystemString). packageDirectoryString} =====================================================================
GitAuthorConverter is just a dummy class to map Monticello author (so a global Dictionary).
===================================================================== GitAuthorConverter map: 'PeterUhnak' to: 'Peter Uhnak <i.uhnak@gmail.com
'. GitAuthorConverter gitNameFor: 'PeterUhnak' "--> returns Peter Uhnak < i.uhnak@gmail.com>'. =====================================================================
Peter
I rewrote all the git command subsystems to solve two issues, so the structure is a lot nicer now. It doesn't cd anymore, instead it uses git -C <target-working-directory>which should help getting it to work on windows (and you can also set a different git executable path in a setting). I'll add issues for the points you raise in the filetree repository; for now, the very latest code is available this way, if you want to experiment: Metacello new baseline: 'FileTree'; repository: 'github://dalehenrich/filetree:issue_142/repository'; load: 'Git' Thanks, Thierry
On 20 February 2015 at 11:31, Thierry Goubier <thierry.goubier@gmail.com> wrote:
Good point. Bad programmers do commits without messages :):)
That could be easily remedied by integrating MC with http://whatthecommit.com :D
Le 29/04/2015 14:32, Damien Pollet a écrit :
On 20 February 2015 at 11:31, Thierry Goubier <thierry.goubier@gmail.com <mailto:thierry.goubier@gmail.com>> wrote:
Good point. Bad programmers do commits without messages :):)
That could be easily remedied by integrating MC with http://whatthecommit.com :D
Got 'made it compile' on the first try. Yep, that would be allways true ;) Thierry
Peter Uhnák wrote
So there are some changes that might be worth considering for integration. ...
Were these incorporated into GitFileTree? If not, it may be good to put this somewhere a bit more permanent. Would it warrant adding to https://github.com/SquareBracketAssociates/PharoInProgress/tree/master/GitAn... ? ----- Cheers, Sean -- View this message in context: http://forum.world.st/moving-to-git-and-preserving-monticello-history-tp4806... Sent from the Pharo Smalltalk Users mailing list archive at Nabble.com.
Hi Sean, Le 29/04/2015 00:41, Sean P. DeNigris a écrit :
Peter Uhnák wrote
So there are some changes that might be worth considering for integration. ...
Were these incorporated into GitFileTree? If not, it may be good to put this somewhere a bit more permanent. Would it warrant adding to https://github.com/SquareBracketAssociates/PharoInProgress/tree/master/GitAn... ?
They were all integrated. Thierry
participants (5)
-
Damien Pollet -
Peter Uhnák -
Sean P. DeNigris -
Thierry Goubier -
Yuriy Tymchuk