0

Here's the situation:

$ git branch --all -vv
* feature/crvc11-93-add-pec                93fe8bc ...
  release/19.3.0-cv011                     4012d42 [origin/release/19.3.0-cv011] ...
  remotes/origin/feature/crvc11-93-add-pec 93fe8bc ...
  remotes/origin/release/19.3.0-cv011      4012d42 ...

I don't know why feature/crvc11-93-add-pec did not track the remote-tracking branch origin/feature/crvc11-93-add-pec when I checked it out, but now I want to add it as the upstream manually:

$ git branch --set-upstream-to origin/feature/crvc11-93-add-pec
fatal: Cannot setup tracking information; starting point 'origin/feature/crvc11-93-add-pec' is not a branch.

What does Git mean here? Yes, it is a branch, it's the remote-tracking branch. If I remove the origin prefix then we get

$ git branch --set-upstream-to feature/crvc11-93-add-pec
warning: Not setting branch feature/crvc11-93-add-pec as its own upstream.

How do I make feature/crvc11-93-add-pec track origin/feature/crvc11-93-add-pec? They are the same commit, this should just work. Am I not "spelling" the branch name correctly? Inserting the = doesn't seem to make any difference.


MORE INFO I suspect the issue has something to do with this being a shallow depth-1 one-branch clone (release/19.3.0-cv011). I think there are special rules about fetching and remote-tracking branches when you do that. .git/config contains this line:

fetch = +refs/heads/release/19.3.0-cv011:refs/remotes/origin/release/19.3.0-cv011

...and I have a feeling that that changes the whole game in some way. If so, it's unfortunate, as I really don't want the entire history occupying space on my computer.

matt
  • 447,615
  • 74
  • 748
  • 977

1 Answers1

1

You need to make your shallow, single-branch clone become a shallow, two-branch clone. :-)

More precisely, add another tracking name using git remote set-branches --add. This doesn't affect any depth settings (which have to be repeated on later git fetch operations since they are not stored anywhere) but does alter the fetch setting you quoted in your MORE INFO section. Each branch you add, adds one more fetch = +refs/heads/name:refs/remotes/remote/name line. These lines direct your Git to create or update the corresponding remote-tracking name, so that you can now pass that name to git branch --set-upstream-to.

You will need to run git fetch after you add the additional branch(es) you'd like tracked, and you probably want to do this with a small --depth value (perhaps just 1 again). You are likely to get better overall results (better git fetch compression and pack files and such) in the future if you make the depth enough to get all the commit subgraph pieces to join up. This will also give you enough information to do normal Git operations in that region of the graph. Exactly how deep (with git fetch's --deepen or --depth) to go is not possible to compute from "your side" until you get deep enough, so a common technique1 is to add 50 or 100 commits at a time until you get "deep enough".


1Ideally we'd have the other side compute this for us, but it won't.

If fetches were free, deepening each subgraph one commit level at a time would perhaps be the way to go, but fetches are not free, so we need to amortize the fetch cost vs the carrying cost of excess data—a pretty standard graph optimization problem!

torek
  • 330,127
  • 43
  • 437
  • 552
  • Yes, this sounds like just the technique I want! This is a massive repo with dozens of independent companies working on their own branches, of which there are hundreds, and it is just wasteful and confusing for me to possess any unnecessary remote tracking branches or to follow the parent chain too far back. We contribute to just one branch via pull requests. Basically I want to be able to try out a pull request branch and then get rid of it later. So this should give me a strategy for doing that. – matt Apr 29 '21 at 07:32