ifiht
ifiht

Reputation: 638

Why does git submodule update fail with "fatal: remote error: upload-pack: not our ref"?

I have a git repo with multiple submodules. I have tried deleting and adding the submodule in question (scopatz's nanorc), however the error persists across the deletion and re-addition. When I clone the repo to a new location I automatically update it with git submodule update --init --recursive, which is when this fails, but only for this submodule... Below is the relevant output from the command with GIT_TRACE=2:

23:01:26.918691 run-command.c:1569      run_processes_parallel: preparing to run up to 1 tasks
23:01:26.933567 run-command.c:1601      run_processes_parallel: done
23:01:26.934373 run-command.c:646       trace: run_command: git gc --auto
23:01:26.966805 git.c:344               trace: built-in: git gc --auto
23:01:26.991059 git.c:344               trace: built-in: git rev-parse --local-env-vars
23:01:27.015684 git.c:344               trace: built-in: git rev-parse --local-env-vars
23:01:27.032282 git.c:344               trace: built-in: git symbolic-ref -q HEAD
23:01:27.053948 git.c:344               trace: built-in: git config --get branch.master.remote
23:01:27.073636 git.c:344               trace: built-in: git fetch origin 151d94a8754b0a612315fc191c5373cc0055c13d
23:01:27.079657 run-command.c:646       trace: run_command: git-remote-https origin https://github.com/scopatz/nanorc.git
23:01:28.441725 run-command.c:646       trace: run_command: git rev-list --objects --stdin --not --all --quiet
23:01:28.452267 run-command.c:646       trace: run_command: git fetch-pack --stateless-rpc --stdin --lock-pack --thin https://github.com/scopatz/nanorc.git/
23:01:28.467757 git.c:344               trace: built-in: git fetch-pack --stateless-rpc --stdin --lock-pack --thin https://github.com/scopatz/nanorc.git/
fatal: remote error: upload-pack: not our ref 151d94a8754b0a612315fc191c5373cc0055c13d
fatal: The remote end hung up unexpectedly
Fetched in submodule path 'submodules/nano', but it did not contain 151d94a8754b0a612315fc191c5373cc0055c13d. Direct fetching of that commit failed.

hoping someone here can help, I'm mostly lost at this point.

=== EDIT: Solution Steps Below ===

cd {submodule path}
git reset --hard origin/master
cd -
git clean -n
git add {submodule path}
git commit
git submodule update --init --recursive

No errors, awesome.

Upvotes: 46

Views: 48063

Answers (9)

VonC
VonC

Reputation: 1323343

Git 2.48 (Q1 2025), batch 5 documents another possible cause for this error message: a "git fetch from"(man) the superproject going down to a submodule used a wrong remote when the default remote names are set differently between them. It comes with a fatal: transport 'file' not allowed.

See commit 0c1a998 (09 Oct 2024) by Daniel Black (grooverdan).
(Merged by Taylor Blau -- ttaylorr -- in commit 6cbcc68, 25 Oct 2024)

submodule: correct remote name with fetch

Signed-off-by: Daniel Black

The code fetches the submodules remote based on the superproject remote name instead of the submodule remote name (see this thread.

Instead of grabbing the default remote of the superproject repository, ask the default remote of the submodule we are going to run 'git fetch'(man) in.

The reproducible case was:

It happens that my default remote isn't "origin" (long story), it's "github", but in the submodule it's of course "origin", there's no "github" remote there.
As a result, git submodule update runs the command

git fetch github ${commit_hash}

in the submodule, and that's interpreted as 'file' transport.

To repeat this, you need a repository where the default remote isn't "origin", and a submodule where the commit cannot be fetched by simply git fetch and needs a direct fetch.

Upvotes: 0

Christoph S
Christoph S

Reputation: 773

I had a similar issue but with the additional pitfall that it worked locally, but I could not push the fix to GitHub, git would not show any changes. The problem was that the submodules were configured with ignore=all. This works like a gitignore for submodules and therefore no changes visible. It was enough to temporarily remove that line

[submodule "csl-styles"]
  path = src/main/resources/csl-styles
  url = https://github.com/citation-style-language/styles.git
  ignore = all # remove temporarily to be able to push correct 
  shallow = true
[submodule "csl-locales"]
  path = src/main/resources/csl-locales
  url = https://github.com/citation-style-language/locales.git
  ignore = all
  shallow = true

Upvotes: 0

focus zheng
focus zheng

Reputation: 380

git submodule update --remote

then

git commit && git push

Everything will be ok

Upvotes: 6

hobbydev
hobbydev

Reputation: 1709

Please try this git submodule foreach --recursive git reset --hard

Upvotes: 16

This can happen if you don't fully commit and push your local changes to the submodules.

I got this error while cloning one of our repos with a submodule, while the original local repo was working fine. The problem was because I forgot the push the submodule changes.

So, make sure to commit and push all your submodule changes.

Upvotes: 10

Lutz Prechelt
Lutz Prechelt

Reputation: 39296

If you made commits on the submodule

...then a common problem is that you

  • ...added that commit to the superproject,
  • pushed the superproject,
  • but did not push the submodule.

So everything is fine in your local workspace, but the superproject is referring to a submodule commit that does not (yet) exist on the remote machine. This fact is what leads to the message.

Solution

git push --recurse-submodules=on-demand

Upvotes: 1

ALBlancoIV
ALBlancoIV

Reputation: 11

I had the same error with our Submodules. Since the project is publicly available, to fixed this, I replace all the values in urls in .git/config and in their individual submodule config with the projects https instead of the ssh

Upvotes: 0

hagits
hagits

Reputation: 369

I faced this issue when I tried to update submodules on a branch that I created before branching some of the submodules. So I had repo1 branch-x, which has some submodlues, and only after that branch-x was created on some of the submodlues. My solution was to loop the submodules and reset the branches:

cd the-main-repo-dir
foreach submodlue in submodules do {
   cd {submodule path}
   git reset --hard origin/brnach-x
   cd -
}
git submodule update --init --recursive
git push origin/branch-x

Upvotes: 1

torek
torek

Reputation: 487775

With Git and submodules, you start with a minimum of two Git repositories. One is "your" repository—the main one, which Git will call the superproject. The second Git repository is some other Git repository: there is nothing special about it at all. It's just that your superproject has in it these two parts:

  • Instructions for cloning the submodule. That lets your Git run git clone if needed, during git submodule update --init for instance.

  • The raw hash ID of some commit that should be in that other Git repository. Your main repository will, after cloning or running git fetch if appropriate in your clone of the other Git repository, run git checkout hash using this raw hash ID.

Your superproject is asking for the hash ID 151d94a8754b0a612315fc191c5373cc0055c13d in the Git repository you can clone from https://github.com/scopatz/nanorc.git. That commit simply does not exist in that repository, so it's not in any clone you make either.

Do you know why your superproject lists this commit hash ID, even though it does not exist? (I certainly don't.) You cannot get it from their Git, because they don't have it. That's what all these error messages are telling you.

You can try searching other repositories (or Google) for 151d94a8754b0a612315fc191c5373cc0055c13d (I just tried with Google and they can't find it). Or, if you don't really care specifically for that commit, try telling your own Git—your superproject—that it should get some other commit, one that does exist and therefore you can get.

Which commit should you get? I have no idea: that's up to you. Note that the place where your superproject lists the raw commit hash from the submodule is: in each commit. You can git checkout some commit, probably the tip of some branch, in your superproject. Then you can enter the submodule, pick a commit you like, use git checkout in that submodule—it's another Git clone, after all, so you can do any Git command there—to check out the desired commit. Then, exit the submodule (change directories back to your superproject) and run git add on the submodule path and git commit to record the new desired hash ID. This new commit now asks for that particular hash ID.

Upvotes: 23

Related Questions