1

I have branch "dev". Last branch dev have empty folder libtai-mutoso. I use Gitbash for Windows. I have finish working on another branch and I am tring to switch the git to branch "dev". But git do not checkout:

$ git checkout dev -f
error: invalid object 160000 0000000000000000000000000000000000000000 for 'Src/time/libtai-mutoso'
error: invalid object 160000 0000000000000000000000000000000000000000 for 'Src/time/libtai-mutoso'
error: cache entry has null sha1: Src/time/libtai-mutoso
fatal: unable to write new index file

How can I switch to dev branch now? Thank you for help, masters!

Daemon Painter
  • 3,208
  • 3
  • 29
  • 44

1 Answers1

2

Last branch dev have empty folder libtai-mutoso.

Git literally cannot store an empty folder, and yours is not doing so. What has happened is that someone has tried to trick your Git into storing an empty folder ... and the trick has failed.

There are two related tricks, both described in How can I add an empty directory to a Git repository? One is to use the special empty tree hash, as described in this answer. It doesn't really work right, as the answer itself notes. The other is to use an empty submodule as described in this answer. This method does work (with some limitations).

It looks like whoever built the repository you have cloned and are trying to use now, tried to use the submodule trick, but got it wrong.

The submodule trick uses the fact that when Git stores information about a submodule—in a so-called gitlink, which is the entity with mode 160000 that you see in the error message—the superproject Git will create a directory / folder, and then—later, when you tell it to—make a .git in that directory and clone the submodule and use the submodule clone to fill in that directory with contents.

Note that this new directory / folder is not empty in the end: it contains a .git, and then your superproject Git runs git checkout as well, at some point, to fill in the folder with the contents of some commit in the submodule. But all that happens later, when you tell your Git to do it. If you never get around to telling your Git fill in my submodules, it never even gets to the step of creating the .git.1

The information your Git needs, to say what Git repository your superproject Git should clone and the commit that it should check out afterward, are contained in two places in the superproject:

  • the name and URL for the submodule repository are in .gitmodules, and
  • the commit hash ID, that the superproject Git should git checkout in the submodule, is the hash ID you see in the error message above.

The hash ID must be the valid hash ID of some commit that actually exists in that submodule repository. The superproject Git doesn't normally actually check that it's valid—not yet anyway: that check happens later. But there is one special case, and you have just seen it.

Specifically, the hash ID 0000000000000000000000000000000000000000 (40 zeros) in Git is reserved, and is called the null hash ID or null sha1 in some places, including the error message you saw:

error: cache entry has null sha1

A cache entry can only have this null hash ID in some special cases, and this isn't one of those special cases.

The right information needs to exist at the time your Git does a git checkout of the superproject commit, so that your Git doesn't complain that there is something wrong and refuse to check out the commit. But in the repository you have cloned, the information in the commit you are trying to check out is wrong.

So, to summarize the problem: someone has tried to use the submodule trick, but got it wrong. The result is a commit that your Git refuses to check out.

How can I switch to dev branch now?

Get whoever made the repository to stop using submodules incorrectly.

Your (and their) best bet is not to bother trying to store an empty folder at all. It's not worth the hassle. If they meant to store a real submodule—which is possible—have them fix their repository so that it has a correct submodule.


1If and when you do tell your superproject Git to update submodules, if you have used use the "empty submodule" trick that works, the repository you clone has no files in its commit. The sample in that answer uses commit e84d7b81f0033399e325b8037ed2b801a5c994e0. So the directory ends up with one entry in it, named .git. In a modern Git, this .git is a file containing a single line. In older Git versions, it's a directory containing the clone of the empty-submodule repository, which contains the one commit with no files in it.

torek
  • 448,244
  • 59
  • 642
  • 775
  • 1
    Thank you for answer! But there is no one submodule in my project. Trouble is in the situation when dev branch have empty folder and branch already commited with empty folder. Checkout to the commit having empty folder invoke the error! – Evgeny Voropaev May 01 '21 at 04:03
  • I did not understand the decision but when I done same checkout operation by git embedded into eclipse the branch dev was switched on even with empty folder in the commit. Unfortunately git under eclipse do not print used commands. So, I did not understand the decision. – Evgeny Voropaev May 01 '21 at 04:09
  • Looks like Eclipse (which has its own entire in-Java implementation of Git) may have made this a special Eclipse-only feature, perhaps. Perhaps that's why it doesn't work in Git. – torek May 01 '21 at 04:48