Reputation: 41
I have a git repo for my dotfiles that I use like so
100 ~$ git --git-dir=$HOME/.cfg/ --work-tree=$HOME [command]
When I list my branches I would expect to see another branch * origin/master
but it does not appear
101 ~$ git --git-dir=$HOME/.cfg/ --work-tree=$HOME branch --all
* master
In most other forum posts etc that I found, this was usually solved by adding the remote, but my remote has already been added. remote show origin
confirms:
102 ~$ git --git-dir=$HOME/.cfg/ --work-tree=$HOME remote show origin
* remote origin
Fetch URL: [email protected]:myusername/dotfiles.git
Push URL: [email protected]:myusername/dotfiles.git
HEAD branch: master
Local branch configured for 'git pull':
master merges with remote master
Local ref configured for 'git push':
master pushes to master (up to date)
Also, when I create commits I can push them to master on my remote with no issue. So what exactly is the origin/master
branch, why is it seemingly automatically present on other local git repos I've worked with, and why is it not in this case?
Edit: I've included some more output from my terminal to clarify what isn't working
619 ~$ git --git-dir=$HOME/.cfg/ --work-tree=$HOME fetch origin
From https://bitbucket.org/myusername/dotfiles
* branch master -> FETCH_HEAD
620 ~$ git --git-dir=$HOME/.cfg/ --work-tree=$HOME push origin master
Everything up-to-date
621 ~$ git --git-dir=$HOME/.cfg/ --work-tree=$HOME branch -a
* master
622 ~$ git --git-dir=$HOME/.cfg/ --work-tree=$HOME branch -r
623 ~$
Upvotes: 0
Views: 2855
Reputation: 41
The fix, as torek pointed out in a reply to his answer, was to set remote.origin.fetch. I ran [git] config --edit
and changed the relevant section from
...
[remote "origin"]
url = https://[email protected]/myusername/dotfiles.git
[status]
...
to
...
[remote "origin"]
url = https://[email protected]/myusername/dotfiles.git
fetch = +refs/heads/*:refs/remotes/origin/*
[status]
...
After this, running [git] status
informed me that
On branch master
Your branch is based on 'origin/master', but the upstream is gone.
Then after running [git] push
I finally see the remote when I run [git] status
and [git] branch -r
* For simplicity's sake, where I actually ran git --git-dir=$HOME/.cfg/ --work-tree=$HOME
in my repo, I shortened it to [git]
in the text above.
Upvotes: 3
Reputation: 487745
Most likely you just need to run:
git fetch origin
(or even just git fetch
): call up Git on Bitbucket and have the Bitbucket Git talk with your Git, with them sending things to you. Or you might need to run:
git push origin master
which has your Git call up their Git and have a similar talk, in the "other direction". Your Git sends them any commits you have on your master
that they don't, and then asks them—politely, "pretty please, if it's OK"—to set their master
to the same commit that is the tip of your branch.
Git terminology is confusing. The name origin/master
is not a branch name; it's a remote-tracking branch name. Just as the pair of words "branch name" is often shortened to "branch", the phrase remote-tracking branch name is often shortened to "remote-tracking branch". I have been experimenting with using "remote-tracking name" instead, because remote-tracking names aren't quite branches at all. In particular, you can't get "on" a remote-tracking name the way you can get "on" a branch ... and while you can have your Git create remote-tracking names directly, you shouldn't.
The purpose of these remote-tracking names is for your Git to remember what their Git said they had, the last time your Git talked with their Git. So you should have your Git call up their Git. The two Gits can then talk, and yours can create, update, and even "prune" these remote-tracking things.
Running either of git fetch
or git push
has your Git call up another Git. To do so, your Git needs the URL of the other Git. Rather than making you type [email protected]:myusername/dotfiles.git
all the time, your Git lets you use a short name like origin
. (You can choose or change the name; origin
is just the default you get when you git clone
by URL, as your clone origin-ated from the other Git.)
This short name is a remote. It's also used as the prefix for each of the remote-tracking names, because you can add more than one remote, and each Git at each URL has its own set of branches, so for your Git to remember the branches at, say, both origin
and fred
, you will want your Git to store one memory under origin/master
and another under fred/master
. Of course if you only have one remote, this is overkill, but harmless.
Anyway, git fetch origin
has them send you all of their branch names, and your Git then downloads any commits they have that you don't, and sets up your origin/*
names to match their names. Similarly, git push origin <name>
has your Git send them commits you have that they don't—new ones you made—and then asks them to set their <name>
to the same as your <name>
. Note that there's no funky renaming here: you ask them to set their master, not their jason/master
. So push is not quite the exact opposite of fetch, it's just as near as Git gets to the opposite.
git pull
What about git pull
? Shouldn't pull
be the opposite of push
?
Well, not quite: pull was there first, but it turns out to do too much and/or the wrong thing sometimes. So it got split into fetch
followed by either rebase
or merge
. After you git fetch
, you often—but not always—will want to integrate whatever you got from another Git into your own branches. At this point you will need a second Git command. Using git pull
will run both commands for you. That's essentially all it does, and you can do that, but until you're familiar with how each of the various individual commands works—and more importantly, how they fail sometimes, and what to do about it—I find it's better to stick with the underlying commands. Otherwise, git pull
may have one of the two commands fail, and then you won't know which command failed, much less what to do about it.
Upvotes: 4