How to set upstream branch in git-svn?
Asked Answered
T

4

13

While working on a usual git repository a local branch usually tracks a corresponding remote upstream branch. This way I can easily see, whether I am ahead or behind of my upstream branch and therefore if I need to push or pull to bring them in sync. Also my prompt immediately shows this state, which is very convenient.

Now I am working on a SVN repository using git-svn. I used --prefix=svn for the clone, therefore git branch -r lists svn/trunk as a remote branch, but (although git svn rebase works without problems) it is not configured as an upstream branch for my master branch.

I tried to set the tracking information manually but it failed:

$ git branch -r
  svn/trunk
$ git branch --set-upstream-to=svn/trunk
fatal: Cannot setup tracking information; starting point 'svn/trunk' is not a branch.

Is there some way to track an svn upstream branch?

Is there some other easy way to know whether I am ahead or behind to that branch? (Looking at gitk --all is currently the only way I am aware of.)

Is there even some way to make my (bash __git_ps1) prompt show that information?


$ git --version
git version 1.9.0.msysgit.0
Tensity answered 6/3, 2014 at 15:44 Comment(1)
FWIW, I see the same behavior with 1.9.2 and without a manually selected prefix IIRC (i got a remotes/trunk).Julissajulita
B
5

This seems to be a bug introduced in git 1.9, since --set-upstream-to worked before exactly as you mention.
And strace displays correct locating and reading of the upstream branch ref, then however it's ignored for some reason.


My workaround for this issue is manual editing of .git/config:

$ cat >> .git/config << EOF

[branch "master"]
        remote = .
        merge = refs/svn/trunk
        rebase = true
EOF

— which should be equivalent to:

git branch --set-upstream-to=svn/trunk master

&& git config branch.master.rebase true (which you'll want with svn anyway)

— but is not, because of a bug! "Of course my refs/svn/trunk is a branch!" you say, and edit the config directly (with just a little bit of gentle force).

Your svn trunk could be named differently in git depending on how you cloned the repo (-s, -T, --prefix options to git svn clone). Just do a git branch -avv and find the correct one. For example, one possible name is refs/remotes/git-svn; or refs/svn/trunk as above; or even something else.


Update Nov 2015

I still reproduce this on git version 2.1.4. Anyone to bother file a bug report?

Brewington answered 12/8, 2014 at 17:47 Comment(6)
By default there is no entry for the master branch in .git/config and adding one has no effect. The svn upstream branches seem to be stored elsewhere.Acrophobia
@Acrophobia I don't quite understand your comment. Yes, a special .git/svn subdir does maintain some data on git-svn remotes; it's mostly human-readable by the way. And yet no, svn remote branches are stored in .git/refs as usual... you can see from above that with --prefix=svn the trunk ref is in .git/refs/svn/trunk — note it's not .git/svn/... anything. It's just a usual git ref. Also, having edited .git/config as shown, I do see the desired Your branch is up-to-date with 'svn/trunk' in git status. Oh, and what do you mean by "svn upstream branches" ?Brewington
By "svn upstream branches" I meant the svn branch that gets updated when I run git svn dcommit. Editing .git/config as you suggest above does not change which branch dcommit affects for me. However when I use git rebase ... as in my answer below I do see a change. I might have misunderstood how this works, or it's a different issue - but my problem seem to only be solved by the answer I gave.Acrophobia
@Acrophobia configuring upstream branch (either by git branch --set-upstream-to as OP shows, or by equivalent editing of .git/config as above) should not affect where git svn dcommit goes (it does affect where git push goes — but with git-svn this isn't used). You're certainly confused about how this works. In particular, blindly rebasing won't help you much. man git-svn: ... note the following rule: git svn dcommit will attempt to commit on top of the SVN commit named in git log --grep=^git-svn-id: --first-parent -1git-svn-id tags determine where dcommit goes.Brewington
@Acrophobia I'm 95% sure you're looking at the wrong question. If you want, email me your repo setup (ulidtko at gmail), so we might come up with something helpful.Brewington
Right, if it's only based on that git-svn-id: in the commit message then I understand. I guess when I rebase that is changing, I can verify the next time I have the problem. But since I already have a solution for my issue there is nothing more to solve for me - I was simply curious why we had different solutions.Acrophobia
D
2

git-svn will store the configuration data in .git/config, for example in one of my repo the config is like:

[core]
    repositoryformatversion = 0
    filemode = true
    bare = false
    logallrefupdates = true
[svn-remote "svn"]
    url = http://svn.repo.com/repos/myrepo
    fetch = trunk:refs/remotes/trunk
    branches = branches/*:refs/remotes/*
    tags = tags/*:refs/remotes/tags/*

In the [svn-remote "svn"] section you can see all the git-svn configurations. In the branches section you see all the branches on the remote svn repo.

When I need to follow a svn branch in my local git repo I usually do these steps:

  1. I check that the config is correctly configured with all the branches and the tags.
  2. I do a git svn fetch, in that way git will fetch all the data in the repo for all the branches
  3. I check that all the branches / tags are present as output of git branch -a, for example:

    master
    prod
    scenarioParametro
    remotes/tags/alpha-1
    remotes/trunk
    
  4. I create a local git branch to track a remote one with:

    git branch alpha-1 remotes/tags/alpha-1 --track
    

In this way the newly created alpha-1 branch will follow the remotes/tags/alpha-1, and you can do the rebase and dcommit commands.

Detached answered 6/3, 2014 at 17:54 Comment(4)
No, --track does not work on my repository. It will result in the same error message as shown in the question. (Cannot setup tracking information.) Does it really work on your repository? Which version of git and which OS?Tensity
@michas: It works for me, I'm using this procedure on something like 10 or more repos... btw, linux and git 1.7.9.5. Could you please post the result of git branch -a after you did a git svn fetch on your repo?Detached
I already gave the output of git branch -r in the question. git branch -a will only add my local master branch.Tensity
Tracking remote git-svn branches no longer works as of Git version 1.8.3.2.Proscription
A
1

This was still a problem for me using git 1.9.5.

And I did not get any of the solutions mentioned here to work, but this worked:

git rebase origin/remote-branch-name

After that git svn dcommit -n shows that it will indeed commit to that svn branch.


Update: I had the same problem again and this time the above didn't work. I just got the message: Current branch master is up to date. However using:

git rebase -i origin/remote-branch-name

forced the rebase anyway and after that the upstream was set correctly.

Acrophobia answered 20/8, 2015 at 13:14 Comment(0)
R
0

Since nobody answered this:

Is there some other easy way to know whether I am ahead or behind to that branch?

Yes, it is. You can just use the general notion GIT uses for comparing refs also in this case. It’s ref_from..ref_to

E.g.:

git log master..svn/trunk – will give you all commits from svn/trunk that are missing in your master. I.e. incomming changes.

git log svn/trunk..master – will give you all commits from master that are missing in svn/trunk. I.e. outgoing changes.

Further explanation of the general syntax: here on SO and in the official GIT documentation

Reversible answered 17/10, 2019 at 8:17 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.