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.uh...@gmail.com>'. GitAuthorConverter gitNameFor: 'PeterUhnak' "--> returns Peter Uhnak < i.uh...@gmail.com>'. ===================================================================== Peter