Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I tell git-svn about a remote branch created after I fetched the repo?

Tags:

git

git-svn

People also ask

Can I use git and SVN at the same time?

No interaction between them. Just ignore the . git folder for SVN and the . svn folder for Git and you should be fine.

What does git SVN fetch do?

This retrieves all the changes from the SVN repository and applies them on top of your local commits in your current branch. You can also use git svn fetch to retrieve the changes from the SVN repository but without applying them to your local branch.


You can manually add the remote branch,

git config --add svn-remote.newbranch.url https://svn/path_to_newbranch/
git config --add svn-remote.newbranch.fetch :refs/remotes/newbranch
git svn fetch newbranch [-r<rev>]
git checkout -b local-newbranch -t newbranch
git svn rebase newbranch

If you want to track ALL the remote svn branches, then the solution is as simple as:

git svn fetch

This will fetch ALL the remote branches that have not been fetched yet.

Extra tip: if you checked out only the trunk at first, and later you want to track ALL branches, then edit .git/config to look like this and re-run git svn fetch:

[svn-remote "svn"]
        url = https://svn/path_to_repo_root/
        fetch = path_to_trunk:refs/remotes/git-svn
        branches = path_to_branches/*:refs/remotes/*

The key points are url should point to the repository root, and the paths defined in fetch and branches should be relative to url.

If you want to fetch only specific branches instead of ALL, there is a nice example in git svn --help:

[svn-remote "huge-project"]
        url = http://server.org/svn
        fetch = trunk/src:refs/remotes/trunk
        branches = branches/{red,green}/src:refs/remotes/branches/*
        tags = tags/{1.0,2.0}/src:refs/remotes/tags/*

With older versions of git-svn, once you specified branches like this, you might not be able to get new branches with git svn fetch. One workaround is adding more fetch lines, like this:

[svn-remote "huge-project"]
        url = http://server.org/svn
        fetch = trunk/src:refs/remotes/trunk
        fetch = branches/blue:refs/remotes/branches/blue
        fetch = branches/yellow:refs/remotes/branches/yellow
        branches = branches/{red,green}/src:refs/remotes/branches/*

Another workaround by @AndyEstes: edit .git/svn/.metadata and change the value of branches-maxRev or tags-maxRev to a revision before any newly-specified branches or tags were created. Once you've done this, run git svn fetch to track the new svn remote branch.


It appears I just needed to git svn fetch; somehow I had convinced myself that would fetch the entire repo instead of just the changes.


Maybe I messed it up somehow but I followed the instructions in vjangus' answer and it almost worked. The only problem was that newbranch didn't appear to be branched from the trunk. In gitk, it was kind of "floating" all on its own; it had no common ancestor with the trunk.

The solution to this was:

  1. Find the SHA1 of the last commit that happened on trunk before the branch was created.
  2. Find the SHA1 of the first commit on the new branch (message is probably "Created new branch, copied from trunk@12345" or something)
  3. git diff-tree <sha1 from step 1> <sha1 from step 2> -- there should be no output. If there is output, you may have selected the wrong commits.
  4. git checkout local-newbranch then git rebase <sha1 from step 1>. This will rebase local-newbranch onto the new tree but remotes/newbranch will still be disconnected.
  5. Go to the file .git/refs/remotes/newbranch and edit it to contain the full SHA1 of the new commit (on the rebased newbranch) that corresponds to the old commit it's currently pointing at. (Or maybe use git-update-ref refs/remotes/newbranch <new-SHA>. Thank you inger.)
  6. The next time you git svn dcommit to newbranch, you'll get a bunch of messages about it updating some log. This is normal I think.

I recommend keeping gitk --all open the whole time and refreshing it often to keep track of what you're doing. I'm still sort of new to git and git svn so please suggest improvements to this method.


A simplification of vjangus' answer:

If you're using the standard layout in SVN and have done the usual svn init, git-svn will do the config stuff for you. Just:

  1. Find branch-copy revision in SVN
  2. Fetch that revision with git-svn
  3. Create new local branch tracking remote

An example. SVN url is svn+ssh://[email protected]/repo. SVN branch I'm looking for is newbranch. Local git branch (tracking remote newbranch) will be git-newbranch.

Step 1: find the branch-copy revision

    # svn log --stop-on-copy svn+ssh://[email protected]/repo/branches/newbranch | tail -4
    r7802 | someone | 2014-03-21 18:54:58 +0000 (Fri, 21 Mar 2014) | 1 line

    branching HEAD to newbranch
    ------------------------------------------------------------------------

So the branch point in SVN is revision 7802.

Step 2: Fetch the revision

    # git svn fetch -r 7802
    Found possible branch point: svn+ssh://[email protected]/repo/trunk => svn+ssh://[email protected]/repo/branches/newbranch, 7801
    Found branch parent: (refs/remotes/trunk) 8dcf3c5793ff1a8a79dc94d268c91c2bf388894a
    Following parent with do_switch
    Successfully followed parent
    r7802 = 9bbd4194041675ca5c9c6f3917e05ca5654a8a1e (refs/remotes/newbranch)

git-svn did all the work and now knows about the remote:

    # git show-ref | grep newbranch
    2df23af4733f36f5ad3c14cc1fa582ceeb3edb5c refs/remotes/newbranch

Step 3: Create your new local branch tracking the remote one:

    # git checkout -b git-newbranch -t newbranch
    Checking out files: 100% (413/413), done.
    Branch git-newbranch set up to track local ref refs/remotes/newbranch.
    Switched to a new branch 'git-newbranch'