74

I have a large git repo (created from an SVN repo) and I want to push it to github. Given it's large, I can't just try and push it directly, as it fails with a "pack too large" error.

All good so far, I can push the repo one commit at a time. But when I try to do this what happens is:

git push origin 86c310d8a680d6d0e052fa7db89adb25348f3e54:master
error: unable to push to unqualified destination: master
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.

So, there is no master branch at the remote repo yet, but I'm trying to push to it and it fails.

How do I fix this? Or how do I create an empty master branch at the remote so I can push to it?

Maurício Linhares
  • 39,901
  • 14
  • 121
  • 158

4 Answers4

135

Push to refs/heads/master, just this one time.

git push origin whatever:refs/heads/master

That will create it unambiguously as a branch, and you'll be able to push to it normally in the future.

This works because there's no remote ref named master (it hasn't been created yet), the target ref isn't fully-qualified with refs/ so git can't figure it out based on that, and the source ref is a hash rather than a name, so it can't figure it out based on that either. By pushing to refs/heads/master it works because the second condition is true, and then afterwards master exists on the remote so the first condition is true

xssChauhan
  • 2,728
  • 2
  • 25
  • 36
hobbs
  • 223,387
  • 19
  • 210
  • 288
  • 16
    @hobbs Could you explain a little more about how/why this works and why the problem exists in the first place? Your solution fixed the problem but I don't know why :X – SleepyCal Aug 18 '15 at 09:20
  • 1
    What do you mean by push to `refs/heads/master`, what is the command you execute ? – xApple Jan 22 '16 at 14:55
  • 5
    @xapple `git push origin whatever:refs/heads/master` – hobbs Jan 22 '16 at 16:40
  • 2
    @sleepycal the exact reason is in the error message. There's no remote ref named `master` (it hasn't been created yet), the target ref isn't fully-qualified with `refs/` so git can't figure it out based on that, and the source ref is a hash rather than a name, so it can't figure it out based on that either. By pushing to `refs/heads/master` it works because the second condition is true, and then afterwards `master` exists on the remote so the first condition is true. – hobbs Jul 26 '17 at 20:36
  • 4
    @sleepycal https://git-scm.com/book/en/v2/Git-Internals-Git-References talks about the 3 types of references seen in your `.git/refs`: heads, tags, and remotes. @hobbs mentioned why git couldn't infer what the ref should be to update or create in the remote repo. You can use these commands to list the current known refs: `git show-ref` for your loco repo, including any remote refs it knows about, and `git ls-remote ` for the remote's references. (Too bad the names don't mirror each other better.) – qix Jul 26 '17 at 20:55
  • Thank you SO much, I was sick of having to make local branches for this crap. – Guido Jul 30 '18 at 21:53
  • @qix, your comment was helpful. When you push in this way, git has no way to know which type of ref you are creating. You could be creating a branch, a tag, or even a remote branch on the remote. By qualifying the ref in `refs/heads/` git knows to create a local branch. – cdosborn Jul 26 '19 at 12:37
  • The problem is not that git wouldn't know the type of thing pointed by the SHA-1 in local or remote repo. Usually when one tries to do this, the SHA-1 points to exactly one *commit* with unique history so that part is clear. However, git supports pushing a single commit SHA-1 + label as a *branch* **or** as a *lightweight tag*. And due historical reasons, the way to specify if *you* mean branch or tag is to *prefix* the remote side with `refs/heads/` or `refs/tags/`. – Mikko Rantalainen May 07 '20 at 06:29
  • Also consider a case where you have a commit that is pointed by both local branch called `test` and a tag called `foo`. If you do `git push origin SHA1:bar` what would you expect to happen? As far as git knows, most of the time all SHA-1 are pointed by multiple things (e.g. reflog, stash, HEAD, FETCH_HEAD, ORIG_HEAD, any tag, any local branch, any remote branch). Pointing to a single commit with SHA-1 does not specify what you mean. Git *could* have been designed to always mean branch unless tag already exists locally and its name has been referenced instead of SHA-1. – Mikko Rantalainen May 07 '20 at 06:36
3

You can also create a new branch with

git checkout -b branchName

and then push your git repository to that branch

git push origin whatever:branchName
M.Ferru
  • 400
  • 1
  • 6
  • 20
1

This worked for me: I created the remote branch on github UI and then pushed my local branch which had the same name to it. Try it in case other ways dont work. Other way would be creating a new branch locally and pushing an empty branch and later cherry-pick your commit and push again to your remote.

Check this as well similar issue: When deleting remote git branch "error: unable to push to unqualified destination"

Nutan
  • 1,287
  • 11
  • 15
0

I had this same error and found that I'd spelled the name of my branch wrong. So you could find that double checking the branch name to ensure any capital letters etc are in the right place.

TBone
  • 19
  • 5