Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can different git-svn clones of the same svn repository expect to be able to share changes then git svn dcommit?

I've read a great deal of "go from svn to git" and other "git-svn workflow" articles on the web, and still I think they often deal with overly simple situations. They are often targeted at guys who just want to use git and hack locally, without using the full power of git, like pull, fetch, merge and the like between multiple developers who would all have cloned the svn repository with git-svn, then still expect to be able to push their changes any time to the (official) svn repository, and get back to working in git and sharing their stuff etc.

Whenever these articles admit you can't do everything you'd do in pure git, the consequences and possible screw ups are never clearly explained (or maybe it's just me ?). Even the git-svn man page mentions caveats, but not really in an extensive manner.

Based on what I've read, I feel there could be problems when git-svn is used in that specific way, which I'll describe below. Can someone tell me if I'm right about this ?

Here is the "wanted" way of doing things:

  1. We have a project in a svn repository
  2. Developer A git-svn-clone's the svn repo. He begins to hack things locally
  3. Developer B git-svn-clone's the same svn repo. He begins to hack things on his own.
  4. After doing that for some time, possibly adding devs C/D/..., and having other developers who do "standard" svn commits to the original repo, the git users would want to share their code and do all kinds of git magic.
  5. Any one of those git users would like to be able to push the now merged changes to svn (dcommit?)

My question is: am I dreaming? I read some time ago, in a git book I think, that git-svn-clone could create git repositories that are of course a "mirror" of the svn repo, but that git repos created that way by different developers would have different "ids" and commits would have different hashes. So my understanding was that those git repos wouldn't share any common git ancestor, and thus wouldn't be able to use all the git commands you need to share, merge, and so on. Is it true, are we going to face problems with this workflow ?

Sometimes I read this could be done, using at least an "official" bare git repository, that would be the only one to be git-svn-cloned, and all git users would have to start form this one. Then you need someone who is in charge of this central git repo, and gathers the changes between the git devs, before dcommiting everything to the svn repo. This would be the only way for git users to be "unaware" that the original git repo comes from svn, and would let them use all git commands as they like. The only person who would need to be fluent in both git and svn (and know about git-svn caveats) would be the "merge manager" (or whatever he's called).

Am I completely misunderstanding git-svn caveats ? Is there any simpler way of doing this ?

like image 316
Ced-le-pingouin Avatar asked Dec 10 '09 11:12

Ced-le-pingouin


People also ask

What does Git SVN clone do?

The git svn clone command transforms the trunk, branches, and tags in your SVN repository into a new Git repository. Depending on the structure of your SVN repo, the command needs to be configured differently.

How do I clone a Git repository in SVN?

# Clone a repo with standard SVN directory layout (like git clone): git svn clone http://svn.example.com/project --stdlayout --prefix svn/ # Or, if the repo uses a non-standard directory layout: git svn clone http://svn.example.com/project -T tr -b branch -t tag --prefix svn/ # View all branches and tags you have ...


2 Answers

I've been experimenting a lot with this lately, and think I managed to come up with a setup that somewhat works. Yes, it's a strict rebase-only regime, yes it's complicated, but you do get to use Git for working locally (speed, history, stash, index, etc).

You can use branches behind the scenes when you collaborate with other Git users in your team I think, but haven't personally experimented too much with this. As long as you linearize the log before dcommitting it should work.

Here's the short version (repeats a lot what's been already said):

  1. Clone the Subversion repo into a "fetching" repo on a central server
  2. Init a "bare" repo on the same server
  3. Push from the fecthing repo to the bare repo
  4. Have developers clone the bare repo and then
    1. git svn init svnurl to configure the git-svn remote, and
    2. git update-ref refs/remotes/git-svn refs/remotes/origin/master so git-svn has a pointer to a revision
  5. Automatically (commit hook) have the "fetching" repo svn rebase, and push to the bare repo
  6. Developers pull from the bare repo with git pull --rebase
  7. Developers running git svn dcommit first have to repeat the update-ref above in case of newer revisions coming from SVN.

There's an illustration of the workflow on this page (I need more reputation points before I can inline the image). Update: Here we go:

like image 186
Thomas Ferris Nicolaisen Avatar answered Oct 08 '22 17:10

Thomas Ferris Nicolaisen


The problem is step 4 of course. A dcommit tries to replay your local history to the server. Dcommit pretends that you're a SVN client. Now, if the code you're dcommitting isn't only from you, that's something that is hard to dcommit to SVN.

Here's what the guru writes on the matter:

  • For the sake of simplicity and interoperating with SVN, it is recommended that all git-svn users clone, fetch and dcommit directly from the SVN server (the remote SVN repository that is), and avoid all git-clone/pull/merge/push operations between git repositories and branches which are either retrieved via git svn clone and which are also used to push back changesets into the remote SVN repository.
  • The recommended method of exchanging code between git branches and users is git format-patch and git am, or just git svn dcommit to the SVN repository.
  • Since git svn dcommit uses git svn rebase internally, any git branches we git push to before git svn dcommit on them will require forcing an overwrite of the existing ref on the remote repository. This is generally considered bad practice, see the git-push documentation for details.
  • Running git merge or git pull is not recommended on a branch we plan to git svn dcommit from. SVN does not represent merges in any reasonable or useful fashion so users using SVN cannot see any merges we have made. Furthermore, if we git merge or git pull from a git branch that is a mirror of an SVN branch, git svn dcommit may commit to the wrong branch.
  • git clone does not clone branches under the refs/remotes/ hierarchy or any git-svn metadata, or config. So repositories created and managed with using git-svn should use rsync for cloning, if cloning is to be done at all.
  • We should not use the --amend option of git commit on a change we have already dcommitted. It is considered bad practice to --amend commits we have already pushed to a remote repository for other users, and dcommit with SVN is analogous to that. More information on this can be found at Modifying a single commit and Problems with rewriting history.
like image 38
nes1983 Avatar answered Oct 08 '22 18:10

nes1983