This has been bothering me about git. I have a repository with multiple remotes, and I need to apply hotfixes to the remotes' master branches. So, I try doing:
git fetch remote1 master
git checkout remote1/master
But, I always end up in a detached head state. What is the correct way to checkout the master of a remote and apply a patch?
None of those commands will give you a detached head. Is there something else that you're doing that you haven't written down in your question?
git fetch remote1
This will fetch anything matching the default refspec for remote1
. That typically means all branches on remote1
unless you've configured it differently.
git fetch remote1 master
The above command fetches master
from remote1
and stores it as FETCH_HEAD
.
git pull remote1/master
This command will error out because remote1/master
is not the name of a repository.
There are a few ways you could approach the problem, but it really depends on what you're trying to accomplish. The typical approach would be to create a local branch for the remote branch you want to update, and merge the corresponding branch:
git checkout -b r1-master remote1/master
git merge other/master
git push
But, it's unclear whether that's an acceptable workflow for you. Can you post more information about what you're trying to accomplish?
Thanks for updating your question with the actual commands used.
git fetch remote1 master
The above command grabs the latest content of master and stores it in FETCH_HEAD
. You want to leave off the master
here and let Git update your remote references: git fetch remote1
. At this pointer, remote1/master
should be up-to-date with what's on the server.
git checkout remote1/master
This is the command that gives you a detached HEAD
. Remote refs aren't treated the same as local branches (refs in refs/heads
). When you checkout a remote ref, Git puts you in a detached HEAD state. I believe the idea behind this is to keep you from corrupting your view of the remote branches. The remote refs are there to serve as a snapshot of the state of the remote repository the last time you fetched. Letting you commit to them would ruin that view. Local branches are where edits need to be made.
Let's make a couple of assumptions. First, I'm going to assume that remote1
is not origin
and that you have added this remote to interact with a different repository other than the primary one. Secondly, I'm assuming that you have the ability to push code to remote1
.
Before going an further, let's make sure that push.default
is set to a reasonable value. Run git config --global push.default
. If nothing is returned, or it says matching
, then let's change it. The default configuration (matching
) will attempt to update all refs on a push for a particular remote. This has the side effect of removing people's work if you don't keep the local versions of your branches up-to-date. A better default is upstream
, which will only push the branch that you are on. Set it with:
git config --global push.default upstream
The typical way to add a patch in Git is to create a branch, make your patch, merge it into the local representation of the remote branch, and then push the result to the remote branch.
Let's start by creating a local branch of the remote master:
git checkout -b r1-master remote1/master
Now we have a local branch called r1-master
that we can update (HEAD
will not be detached on this branch).
Next, do your work. This typically involves creating another branch and adding your series of patches to it:
git checkout -b fix-bugs r1-master
# Edit and commit
Next, you'll need to checkout r1-master
again. While making your changes, someone could have introduced new commits on remote1/master
, so let's make sure we're up-to-date:
git fetch remote1
Next, merge in the bug fix branch:
git merge fix-bugs
This will pop open an editor. Add a sensible log message about what the merge fixes, and then save and exit.
At this point, r1-master
has your fix in it, but it's not on the remote server. We need to push our newly introduced fix to the remote server:
git push
At this point, r1-master
and remote1/master
should point to the same thing, and the remote server has been updated with your fix.
For what it's worth, it looks like you're new to Git, so let me point you at a couple of tutorials. The first is Try Git. I like it because you can try the commands right there on the web page, but it's not very in-depth. Git Immersion goes more in depth, and has an excellent presentation of the concepts behind Git. NDP Software's Git Cheatsheet is also an excellent reference on how commands affect the local and remote repository. Finally, Pro Git is a good book to get you started. The online version is free.
git fetch remote1 master
will fetch the master branch of remote and store it in FETCH_HEAD
, not in remote1/master
. - You simply want git fetch remote1
, or git fetch --all
.
git checkout remote1/master
will always put you in detached head mode, because you did not specify a local branch. - You want something like git checkout -b master remote1/master
.
Please read git help fetch
and git help checkout
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With