On Mon, Jan 14, 2019 at 07:34:56PM +0100, Martin Ågren wrote: > If `read_repository_format()` encounters an error, `format->version` > will be -1 and all other fields of `format` will be undefined. However, > in `setup_git_directory_gently()`, we use `repo_fmt.hash_algo` > regardless of the value of `repo_fmt.version`. > > This can be observed by adding this to the end of > `read_repository_format()`: > > if (format->version == -1) > format->hash_algo = 0; /* no-one should peek at this! */ > > This causes, e.g., "git branch -m q q2 without config should succeed" in > t3200 to fail with "fatal: Failed to resolve HEAD as a valid ref." > because it has moved .git/config out of the way and is now trying to use > a bad hash algorithm. > > Check that `version` is non-negative before using `hash_algo`. > > This patch adds no tests, but do note that if we skip this patch, the > next patch would cause existing tests to fail as outlined above. I'm still somewhat confused about how this breaks. If we move ".git/config" out of the way, then we have no version indicator and presumably we should guess GIT_HASH_SHA1. Which is what's happening if we fail to call repo_set_hash_algo(), no? In other words, wouldn't repo_set_hash_algo() always be a noop in that case? I get why adding the code snippet above would cause that assumption to break, but I am just not sure why we would add that code snippet. ;) I also get why read_repository_format() doing this in patch 3 would be a problem: + if (format->version == -1) { + clear_repository_format(format); + format->version = -1; + } but doesn't that point out that clear_repository_format() should be setting hash_algo to GIT_HASH_SHA1 as the default (and likewise "bare = -1", etc, that is done in that function)? -Peff