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

匿名 (未验证) 提交于 2019-12-03 01:31:01

问题:

I'm using git-svn to work against my company's central svn repository. We've recently created a new feature branch in the central repo. How do I tell git about it? When I run git branch -r I can only see the branches that existed when I ran fetch against the svn repo to initialize my git repo?

回答1:

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] git checkout -b local-newbranch -t newbranch git svn rebase newbranch 


回答2:

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.



回答3:

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.



回答4:

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 -- there should be no output. If there is output, you may have selected the wrong commits.
  4. git checkout local-newbranch then git rebase . 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 . 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.



回答5:

I have not found any documentation about this feature, but looks like git svn configuration supports multiple fetch entries. This way you can also add branches separately without need to add another remote svn repository entry to your config nor using wildcards to get all branches of certain directory.

Assume that your SVN tree is really nasty having lots of branches without any logic how they are located, e.g. having branches and sub-directories containing more branched.

i.e.

trunk branches   -> branch1   -> sub-dir1     -> branch2     -> branch3   -> sub-dir2     -> branch4     -> sub-dir3       -> branchX  <... hundreds="" more="" ...="">

and you just want to hand pick some of the branches to be included to your git repository.

You may first init your repository with only trunk without any additional branches:

git svn clone -r 10000:HEAD https://svn.com/MyRepo myrepo --prefix=svn/ --trunk=trunk  

After that you should see following configuration:

localhost: elhigu$ git config --get-regexp "svn-remote." svn-remote.svn.url https://svn.com/MyRepo svn-remote.svn.fetch trunk:refs/remotes/svn/trunk 

when ever you want to fetch new branch from MyRepo you can just add new fetch entries to configuration by:

git config --add svn-remote.svn.fetch branches/sub-dir2/branch4:refs/remotes/svn/branches/sub-dir2/branch4 

Or you may edit the same configuration in .git/config

To fetch the new branches after adding them to config just run:

git svn fetch -r 10000:HEAD 

[Edit] Sometimes it seems to be necessary to run fetch with --all parameter to fetch newly added branches:

git svn fetch --all -r 10000:HEAD 


回答6:

Instead of dealing with the git-svn quirks you may try SubGit.

One has to install SubGit into Subversion repository. After that one can use standard git workflow instead of using special git-svn commands:

  1. Pushing new commits:

    git-svn:

    $ git commit $ git svn rebase $ git svn dcommit 

    SubGit:

    $ git commit $ git push 
  2. Fetching incoming changes

    git-svn:

    $ git svn rebase 

    SubGit:

    $ git pull [--rebase] 
  3. Creating a new branch:

    git-svn:

    $ git svn branch foo $ git checkout -b foo -t remotes/foo $ git commit $ git svn dcommit 

    SubGit:

    $ git checkout -b foo $ git commit $ git push 

See SubGit documentation for more details.



回答7:

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://gil@svn.myplace.com/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://gil@svn.myplace.com/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://gil@svn.myplace.com/repo/trunk => svn+ssh://gil@svn.myplace.com/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' 


回答8:

To add to vjangus' answer, which helped me, I also found it useful to add use git grafts to tie the branches to the trunk at the appropriate point - allowing git to see the history and perform merges correctly.

This is simply a case of adding a line to .git/info/grafts with the hashes:

eg.

378b0ae0902f5c2d2ba230c429a47698810532e5 6c7144991381ce347d4e563e9912465700be0638 

Credit to http://evan-tech.livejournal.com/255341.html

(I'd add this as a comment, but I've not enough reputation.)



回答9:

If you don't check out with a valid layout, you won't be able to checkout a remote branch.

This is what I do:

git svn init -s  local_repo cd local_repo git svn fetch  ## wait 

After that, you can switch to a remote branch:

git checkout --track -b branch_name branch_name 

Then you will automatically be switched to your branch.



易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!