{"thread":{"id":"37525","subject":"[ANNOUNCE] git-as-svn: subversion frontend server for git repository","startedAt":"2014-09-09T11:19:04Z","lastAt":"2014-09-09T19:30:23Z","messageCount":4,"participants":["Marat Radchenko","Junio C Hamano"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"249074","messageId":"20140909111903.GA13137@seldon","threadId":"37525","inReplyTo":null,"subject":"[ANNOUNCE] git-as-svn: subversion frontend server for git repository","fromName":"Marat Radchenko","fromEmail":"marat@slonopotamus.org","sentAt":"2014-09-09T11:19:04Z","receivedAt":"2014-09-09T11:19:04Z","isPatch":false,"sender":{"key":"marat@slonopotamus.org","avatar":"https://avatars.githubusercontent.com/u/92637?v=4"},"body":"Some time ago I complained [1] about troubles using Git\non a project with high ratio of non-programmers.\n\nSince then, a conclusion was made: Git is too complex.\nWhile Git provides many nice advanced stuff, its simplest\nworkflow isn't simple enough.\n\nSo we examined other options:\n\n  * Splitting project in two repos (Git + SVN). It was\n    thought to be the worst idea because we lost commit\n    atomicity\n\n  * Use GitHub SVN integration [2]. Rejected due to security\n    considerations: our closed-source project isn't allowed to be\n    hosted outside.\n\n  * Use GitHub Enterprise: rejected due to pricing\n\n  * Use SubGit [3]: rejected because of its architecture.\n\nThen, a lost'n'forgotten git_svn_server [4] was found. After playing\nwith it, we found out that its approach can work, though several\ndecisions (Python and extensive forking of `git`) made it very slow.\n\nSo we thought \"we're programmers, after all\".\n\nAnd that's when *git-as-svn* [5] was born. It is a daemon that sits\non top of Git repository and talks svn:// protocol.\n\nFeatures supported:\n\n  * checkout/update\n\n  * log\n\n  * blame\n                                                                                                                                                             \n  * commit (!)                                                                                                                                               \n                                                                                                                                                             \n  * rename detection (though a bit slow yet)                                                                                                                 \n                                                                                                                                                             \n  * svn:eol-style                                                                                                                                            \n                                                                                                                                                             \n  * Git pre-receive hooks                                                                                                                                    \n                                                                                                                                                             \n  * simple or LDAP authentication                                                                                                                            \n                                                                                                                                                             \n  * partial checkout                                                                                                                                         \n                                                                                                                                                             \n  * sparse working copy (svn --depth/--set-depth)                                                                                                            \n                                                                                                                                                             \n  * git submodules                                                                                                                                           \n                                                                                                                                                             \nCurrent limitations:                                                                                                                                         \n                                                                                                                                                             \n  * Only a single Git branch from a single repository\n\n  * Needs at least one commit in Git\n\n  * Parses whole history on startup and doesn't cache it anywhere\n\n  * You must not do 'inverted merges'. Old HEAD must be reachable from\n    new HEAD by first-parent traversal.\n\n[1]: http://marc.info/?l=git&m=139866660018802\n[2]: https://help.github.com/articles/support-for-subversion-clients\n[3]: http://subgit.com/\n[4]: http://git.q42.co.uk/git_svn_server.git\n[5]: https://github.com/bozaro/git-as-svn/\n"},{"id":"249076","messageId":"xmqqy4tsloxs.fsf@gitster.dls.corp.google.com","threadId":"37525","inReplyTo":"20140909111903.GA13137@seldon","subject":"Re: [ANNOUNCE] git-as-svn: subversion frontend server for git repository","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2014-09-09T16:49:03Z","receivedAt":"2014-09-09T16:49:03Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Marat Radchenko <marat@slonopotamus.org> writes:\n\n> Some time ago I complained [1] about troubles using Git\n> on a project with high ratio of non-programmers.\n> ...\n> Then, a lost'n'forgotten git_svn_server [4] was found.\n> ...\n\nInteresting.\n\n> Current limitations:\n> ...\n>   * You must not do 'inverted merges'. Old HEAD must be reachable from\n>     new HEAD by first-parent traversal.\n\nI am not sure what you mean by this to properly assess how\nsignificant this limitation is.  Care to draw a simple picture?\n"},{"id":"249084","messageId":"20140909185711.GA14554@seldon","threadId":"37525","inReplyTo":"xmqqy4tsloxs.fsf@gitster.dls.corp.google.com","subject":"Re: [ANNOUNCE] git-as-svn: subversion frontend server for git repository","fromName":"Marat Radchenko","fromEmail":"marat@slonopotamus.org","sentAt":"2014-09-09T18:57:11Z","receivedAt":"2014-09-09T18:57:11Z","isPatch":false,"sender":{"key":"marat@slonopotamus.org","avatar":"https://avatars.githubusercontent.com/u/92637?v=4"},"body":"On Tue, Sep 09, 2014 at 09:49:03AM -0700, Junio C Hamano wrote:\n> Marat Radchenko <marat@slonopotamus.org> writes:\n> \n> > Some time ago I complained [1] about troubles using Git\n> > on a project with high ratio of non-programmers.\n> > ...\n> > Then, a lost'n'forgotten git_svn_server [4] was found.\n> > ...\n> \n> Interesting.\n\nActually, no. As I said, git_svn_server made several ineffective\narchitectural choices. It can be viewed as a proof-of-concept work though.\n\n> > Current limitations:\n> > ...\n> >   * You must not do 'inverted merges'. Old HEAD must be reachable from\n> >     new HEAD by first-parent traversal.\n> \n> I am not sure what you mean by this to properly assess how\n> significant this limitation is.  Care to draw a simple picture?\n\nSVN doesn't support nonlinear history (except merge-info crutch).\n\nThus, we only expose \"main\" history line to SVN where \"main\" means\n\"reachable through first-parent traversal from branch tip\".\n\nTo keep SVN history consistent, commits that once became visible to SVN\nhave to remain visible. This limitation will be removed when git-as-svn\ngets persistent storage and will be able to remember what *was* main line.\n\nImagine you had following history:\n\n--- time --->\n\nA -- B -- C\n\nNow you merge (via Git) a feature branch:\n\nA -- B -- C -- G\n \\            /\n  D -- E --- F\n\nFor SVN, history will look this way:\n\nA -- B -- C -- F\n\nWe might introduce merge-info support for this one day.\n\nAnd now the *bad* case. You have the same initial history but do *inverted merge*:\n\nA -- D -- E -- F -- G'\n \\                 /\n  B -- C ---------/\n       ^\n       |\n    Previous branch tip\n\nThat's where things brake because for SVN, history transforms from\n\nA -- B -- C\n\nto\n\nA -- D -- E -- F -- G'\n\nAnd all users who checked out revisions B & C get their working copies screwed.\n\nThis also means that push --force also must not be performed.\n\nQuoting my initial post [1] about inverted merges (you might call them\n\"merges with swapped parents\").\n\n> I call it \"swapped/reverse merge problem\".\n>\n> In short:\n> 1. Hack, hack, hack\n> 2. Commit\n> 3. Push, woops, reject (non-ff)\n> 4. Pull\n> 5. Push\n>\n> The root of evil is step #4 that creates a merge commit with \"swapped\" parents - \n> local commits become first parent, remote commits become second. If one would want to \n> make proper parent order, he would have to: 1. git fetch\n> 2. git checkout origin/master -b tmp\n> 3. git merge master\n> 4. git push\n> 5. git checkout master\n> 6. git merge origin/master\n> 7. git branch -d tmp\n> \n> And all this branch dance produces exactly the same commit (content-wise) as simple\n> \"pull, push\" sequence with the only difference in parent order. And things become\n> even worse if comeone pushes more commits to remote repo while you perform this\n> dance.\n>\n> We can't expect all developers (especially, designers and artist) to do it. They\n> don't want to use branches and just work on mainline. This is especially important on\n> early development stages when new features (that designers' work depends upon) are\n> added every day.\n>\n> Additionally, many git-related tools depend on first-parent convention and show wrong\n> graphs/diffs.\n\n[1] http://marc.info/?l=git&m=139866660018802\n"},{"id":"249090","messageId":"xmqqiokwk2wg.fsf@gitster.dls.corp.google.com","threadId":"37525","inReplyTo":"20140909185711.GA14554@seldon","subject":"Re: [ANNOUNCE] git-as-svn: subversion frontend server for git repository","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2014-09-09T19:30:23Z","receivedAt":"2014-09-09T19:30:23Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Marat Radchenko <marat@slonopotamus.org> writes:\n\n>> >   * You must not do 'inverted merges'. Old HEAD must be reachable from\n>> >     new HEAD by first-parent traversal.\n>> \n>> I am not sure what you mean by this to properly assess how\n>> significant this limitation is.  Care to draw a simple picture?\n>\n> SVN doesn't support nonlinear history (except merge-info crutch).\n> ...\n> And now the *bad* case. You have the same initial history but do *inverted merge*:\n\nThat is a bad way to answer a question that asks \"what do you mean\nby an 'inverted merge', which is not in our normal lexicon?\" ;-)\n\n\tYou must not merge the current tip of SVN server *into* the\n\twork you did on top of a past state you obtained from the\n\tSVN server.  Check out the current state from the SVN side,\n\tand merge your work into it instead.\n\nor something like that is what people would understand without\nintroducing a new/unused word to the world.  And\n\n> A -- D -- E -- F -- G'\n>  \\                 /\n>   B -- C ---------/\n>        ^\n>        |\n>     Previous branch tip\n\nthis illustrates the topology you meant reasonably well, especially\nif you marked D, E and F as \"your own work\" (as opposed to what the\nserver side did in the meantime while you worked, i.e. B and C).\n\nThanks for a clarification.\n"}]}