Here's what I did:
Checked out a remote git repository.
Added to the [remote "origin]
section of .git/config
:
fetch = +refs/heads/release/BranchName:refs/remotes/origin/release/BranchName
git checkout origin/release/BranchName
After that git status
reported:
HEAD detached from origin/release/BranchName
Added and checked in some modifications.
Tries to git push
. This resulted in the error message:
fatal: You are not currently on a branch. To push the history leading to the current (detached HEAD) state now, use
git push origin HEAD:<name-of-remote-branch>
git push origin HEAD:origin/release/BranchName
and got the following:
error: unable to push to unqualified destination: origin/release/BranchName The destination refspec neither matches an existing ref on the remote nor begins with refs/, and we are unable to guess a prefix based on the source ref. error: failed to push some refs to 'RepositoryName`
Thus the questions: what did I do wrong? How to fix that and push the changes?
The string origin/release/BranchName
contains both the name of the remote (origin
) and the remote branch name (release/BranchName
). The suggested command had these as separate arguments, so you should run:
git push origin HEAD:release/BranchName
To understand what went wrong, you have to understand that in git, branches don't really exist; a branch is just a convenient pointer to some commit. With a local branch, there are some convenient mechanics for moving that pointer when you commit, but with a remote branch, that doesn't happen (because you don't update the remote pointer until you run push
).
When you ran:
git checkout origin/release/BranchName
Git looked up a remote branch, found out what commit it pointed to, and checked out that commit. However, it didn't create or update any local branch, so when you committed, no new pointer was created, just a bunch of commits. That's what "detached HEAD" means - you have something checked out, but it's not "attached" to any branch.
What you should instead have run was this:
git checkout -t origin/release/BranchName
Or this:
git checkout release/BranchName
(Or, in newer versions of git, replace git checkout
with git switch
- the functionality is the same in this case, but git switch
has fewer confusing extra meanings.)
In each case, assuming you don't already have a local branch called release/BranchName
, git will work out that what you want is a new local branch which "tracks" (is associated with for push
and pull
commands) the remote branch of the same name.
Then, when you commit, you will be committing to a normal branch, and won't get "detached head" errors.