setup_git_directory_gently_1(): avoid die()ing

This function now has a new caller in addition to setup_git_directory(): the newly introduced discover_git_directory(). That function wants to discover the current .git/ directory, and in case of a corrupted one simply pretend that there is none to be found. Example: if a stale .git file exists in the parent directory, and the user calls `git -p init`, we want Git to simply *not* read any repository config for the pager (instead of aborting with a message that the .git file is corrupt). Let's actually pretend that there was no GIT_DIR to be found in that case when being called from discover_git_directory(), but keep the previous behavior (i.e. to die()) for the setup_git_directory() case. Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Johannes Schindelin committed Mar 13, 2017 at 21:11 UTC 01017dce5469660191f926e35a3d9e88cbcb8537
1 file changed +17 -8
setup.c
+17 -8
@@ -825,7 +825,8 @@ enum discovery_result {
825 GIT_DIR_BARE,
826 /* these are errors */
827 GIT_DIR_HIT_CEILING = -1,
828 - GIT_DIR_HIT_MOUNT_POINT = -2
828 + GIT_DIR_HIT_MOUNT_POINT = -2,
829 + GIT_DIR_INVALID_GITFILE = -3
830 };
831
832 /*
@@ -842,7 +843,8 @@ enum discovery_result {
843 * is relative to `dir` (i.e. *not* necessarily the cwd).
844 */
845 static enum discovery_result setup_git_directory_gently_1(struct strbuf *dir,
845 - struct strbuf *gitdir)
846 + struct strbuf *gitdir,
847 + int die_on_error)
848 {
849 const char *env_ceiling_dirs = getenv(CEILING_DIRECTORIES_ENVIRONMENT);
850 struct string_list ceiling_dirs = STRING_LIST_INIT_DUP;
@@ -890,14 +892,21 @@ static enum discovery_result setup_git_directory_gently_1(struct strbuf *dir,
892 if (one_filesystem)
893 current_device = get_device_or_die(dir->buf, NULL, 0);
894 for (;;) {
893 - int offset = dir->len;
895 + int offset = dir->len, error_code = 0;
896
897 if (offset > min_offset)
898 strbuf_addch(dir, '/');
899 strbuf_addstr(dir, DEFAULT_GIT_DIR_ENVIRONMENT);
898 - gitdirenv = read_gitfile(dir->buf);
899 - if (!gitdirenv && is_git_directory(dir->buf))
900 - gitdirenv = DEFAULT_GIT_DIR_ENVIRONMENT;
900 + gitdirenv = read_gitfile_gently(dir->buf, die_on_error ?
901 + NULL : &error_code);
902 + if (!gitdirenv) {
903 + if (die_on_error ||
904 + error_code == READ_GITFILE_ERR_NOT_A_FILE) {
905 + if (is_git_directory(dir->buf))
906 + gitdirenv = DEFAULT_GIT_DIR_ENVIRONMENT;
907 + } else if (error_code != READ_GITFILE_ERR_STAT_FAILED)
908 + return GIT_DIR_INVALID_GITFILE;
909 + }
910 strbuf_setlen(dir, offset);
911 if (gitdirenv) {
912 strbuf_addstr(gitdir, gitdirenv);
@@ -934,7 +943,7 @@ const char *discover_git_directory(struct strbuf *gitdir)
943 return NULL;
944
945 cwd_len = dir.len;
937 - if (setup_git_directory_gently_1(&dir, gitdir) <= 0) {
946 + if (setup_git_directory_gently_1(&dir, gitdir, 0) <= 0) {
947 strbuf_release(&dir);
948 return NULL;
949 }
@@ -994,7 +1003,7 @@ const char *setup_git_directory_gently(int *nongit_ok)
1003 die_errno(_("Unable to read current working directory"));
1004 strbuf_addbuf(&dir, &cwd);
1005
997 - switch (setup_git_directory_gently_1(&dir, &gitdir)) {
1006 + switch (setup_git_directory_gently_1(&dir, &gitdir, 1)) {
1007 case GIT_DIR_NONE:
1008 prefix = NULL;
1009 break;