Jeff King <peff@xxxxxxxx> writes: > I think the problem is in verify_clean_subdirectory, which checks that > we do not have untracked files in the subdirectory, nor modifications > between the index and working tree. But I do not see it checking whether > we have modifications from the HEAD. I actually think "comparison with HEAD" is a red herring. As long as the version in the index matches the version in the other branch we are checking out, it does not matter if the version in the index is different from the version in HEAD (case 4). Also if the version in the index is new and neither HEAD nor the other branch has it, we should keep it (case 2). And we should error out if these are not possible. I did a bit more digging on this; even though I am not going to continue it further today, here is a snapshot of my current thinking. After replacing "something" with "something/f1" in the index, attempting to "read-tree -m -u master b" (which is what checkout is about) decides that the regular file "something" should not exist, because it is in "master" but not in "b", so it calls deleted_entry(ce = master's version, old = NULL) where "old" is the version of "something" in the index, i.e. "does not exist". This in turn calls verify_absent(ce) to make sure that it is OK to remove regular file "something". verify_absent() checks the path "something" with lstat(), and it would be happy if there weren't "something", as there won't be anything necessary to do in that case. But it finds a directory. It calls check_ok_to_remove() on it. This is where things go wrong. This function is to see if it is ok to nuke the entire directory "something", for the more common case where we are about to create a different "something" there. It is an appropriate check if we were trying to create a version of regular file "something" from the branch we are trying to check out, but it is a wrong thing to do when we are not interested in touching "something" in any way. We do not have regular file "something" now, and after checking out the branch, we do not want to have regular file "something" there, either ---so all we have to do is to do nothing! Instead, it says "Ah, something/f1 is clean", sets o->cache_bottom to skip it, and the machinery loses sight of that path. Probably we need to vet the caller of verify_absent() to see why each caller wants to call it. Some may be about to create a new thing there, and really want to make sure there is nothing there after they are done. But this caller, when it _knows_ the path is already removed (it can tell in check_ok_to_remove() after lstat() says there is a directory "something" there---at that point we know the regular file "something" cannot be there), should just be happy and let the later callers to look at the remaining cache entries without marking everything under something/* has been processed. Or something like that. -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html