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
michas
  • 25,361
  • 15
  • 76
  • 121
  • 1
    FWIW, I see the same behavior with 1.9.2 and without a manually selected prefix IIRC (i got a remotes/trunk). – stefanct May 03 '14 at 21:11

4 Answers4

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?

Community
  • 1
  • 1
ulidtko
  • 14,740
  • 10
  • 56
  • 88
  • 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. – Zitrax Nov 11 '15 at 08:47
  • @Zitrax 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" ? – ulidtko Nov 11 '15 at 19:29
  • 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. – Zitrax Nov 11 '15 at 23:34
  • 1
    @Zitrax 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 -1`* ← `git-svn-id` tags determine where `dcommit` goes. – ulidtko Nov 12 '15 at 12:09
  • @Zitrax 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. – ulidtko Nov 12 '15 at 12:20
  • 1
    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. – Zitrax Nov 13 '15 at 07:27
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.

michas
  • 25,361
  • 15
  • 76
  • 121
Atropo
  • 12,231
  • 6
  • 49
  • 62
  • 2
    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? – michas Mar 06 '14 at 18:40
  • @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? – Atropo Mar 07 '14 at 08:03
  • I already gave the output of `git branch -r` in the question. `git branch -a` will only add my local master branch. – michas Mar 07 '14 at 21:32
  • 6
    Tracking remote *git-svn* branches no longer works as of Git version 1.8.3.2. – seh Dec 04 '14 at 14:50
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.

Zitrax
  • 19,036
  • 20
  • 88
  • 110
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

Peter
  • 785
  • 2
  • 7
  • 18