Search code examples
gitgit-fetchremote-branchremote-repository

`git fetch origin foo` vs `git fetch origin foo:origin/foo`


I have 2 remote branches, foo and bar.

Neither foo nor bar exist locally. They appear in neither of the following

  • git branch # local branches
  • git branch -r # remote-tracking branches

I did git fetch origin foo and it printed

remote: MyRepo
remote: Found 33 objects to send. (3121 ms)
Unpacking objects: 100% (33/33), 10.01 KiB | 140.00 KiB/s, done.
From https://example.com/repos/_git/MyRepo
 * branch                      foo -> FETCH_HEAD

I also did git fetch origin bar:origin/bar and it printed

remote: MyRepo
remote: Found 1320 objects to send. (3314 ms)
Receiving objects: 100% (1320/1320), 1.44 MiB | 3.25 MiB/s, done.
Resolving deltas: 100% (528/528), completed with 275 local objects.
From https://example.com/repos/_git/MyRepo
 * branch                      bar -> FETCH_HEAD
 * [new ref]                   HEAD       -> bar

What do the last 2 lines mean?

* branch                      bar -> FETCH_HEAD
* [new ref]                   HEAD       -> bar

I do git branch --show-current and it is not bar, so why does it say HEAD -> bar?


As before neither foo nor bar appear in git branch. But bar does appear in git branch -r, but foo doesn't.

Also a file was created for bar; the file being: .git\remotes\refs\origin\bar, but no file was created for foo.

Neither foo nor bar appear in .git\packed-refs.


What is the purpose of git fetch origin foo if it doesn't create a corresponding branch?

Other than updating FETCH_HEAD, does git fetch origin foo have no effect if foo doesn't exist locally already?


Solution

  • What is the purpose of git fetch origin foo if it doesn't create a corresponding branch?

    It doesn't create a corresponding branch, but it does create a corresponding ref, namely FETCH_HEAD.

    Thus, at that moment, you can (for example) start a local branch off of FETCH_HEAD, so you can check it out and test out the code in your working tree. Or you might at that moment merge FETCH_HEAD into some existing local branch (the manual equivalent, therefore, of git pull).

    This kind of behavior is not unusual in funny situations like when you've done some sort of branch-limited shallow clone to start with. (It is more common, however, if your goal is to work for a while with a branch that was not part of your original branch-limited shallow clone, to use git remote set-branches --add to temporarily add another branch to your branch-limited shallow clone.)

    Other than updating FETCH_HEAD, does git fetch origin foo have no effect if foo doesn't exist locally already?

    Well, it doesn't have no effect; it fetches some commits! But if you don't do something to refer to them (as I just described), you won't have any way of getting at them locally.