@@ -314,6 +314,44 @@ static int check_repository_format_gently(int *nongit_ok)
314314 return 0 ;
315315}
316316
317+ /*
318+ * Try to read the location of the git directory from the .git file,
319+ * return path to git directory if found.
320+ */
321+ const char * read_gitfile_gently (const char * path )
322+ {
323+ char * buf ;
324+ struct stat st ;
325+ int fd ;
326+ size_t len ;
327+
328+ if (stat (path , & st ))
329+ return NULL ;
330+ if (!S_ISREG (st .st_mode ))
331+ return NULL ;
332+ fd = open (path , O_RDONLY );
333+ if (fd < 0 )
334+ die ("Error opening %s: %s" , path , strerror (errno ));
335+ buf = xmalloc (st .st_size + 1 );
336+ len = read_in_full (fd , buf , st .st_size );
337+ close (fd );
338+ if (len != st .st_size )
339+ die ("Error reading %s" , path );
340+ buf [len ] = '\0' ;
341+ if (prefixcmp (buf , "gitdir: " ))
342+ die ("Invalid gitfile format: %s" , path );
343+ while (buf [len - 1 ] == '\n' || buf [len - 1 ] == '\r' )
344+ len -- ;
345+ if (len < 9 )
346+ die ("No path in gitfile: %s" , path );
347+ buf [len ] = '\0' ;
348+ if (!is_git_directory (buf + 8 ))
349+ die ("Not a git repository: %s" , buf + 8 );
350+ path = make_absolute_path (buf + 8 );
351+ free (buf );
352+ return path ;
353+ }
354+
317355/*
318356 * We cannot decide in this function whether we are in the work tree or
319357 * not, since the config can only be read _after_ this function was called.
@@ -323,6 +361,7 @@ const char *setup_git_directory_gently(int *nongit_ok)
323361 const char * work_tree_env = getenv (GIT_WORK_TREE_ENVIRONMENT );
324362 static char cwd [PATH_MAX + 1 ];
325363 const char * gitdirenv ;
364+ const char * gitfile_dir ;
326365 int len , offset ;
327366
328367 /*
@@ -377,15 +416,23 @@ const char *setup_git_directory_gently(int *nongit_ok)
377416
378417 /*
379418 * Test in the following order (relative to the cwd):
419+ * - .git (file containing "gitdir: <path>")
380420 * - .git/
381421 * - ./ (bare)
422+ * - ../.git
382423 * - ../.git/
383424 * - ../ (bare)
384425 * - ../../.git/
385426 * etc.
386427 */
387428 offset = len = strlen (cwd );
388429 for (;;) {
430+ gitfile_dir = read_gitfile_gently (DEFAULT_GIT_DIR_ENVIRONMENT );
431+ if (gitfile_dir ) {
432+ if (set_git_dir (gitfile_dir ))
433+ die ("Repository setup failed" );
434+ break ;
435+ }
389436 if (is_git_directory (DEFAULT_GIT_DIR_ENVIRONMENT ))
390437 break ;
391438 if (is_git_directory ("." )) {
0 commit comments