@@ -422,10 +422,10 @@ static int read_gitfile(git_buf *path_out, const char *file_path)
422422}
423423
424424static int find_repo (
425- git_buf * repo_path ,
426- git_buf * parent_path ,
427- git_buf * link_path ,
428- git_buf * common_path ,
425+ git_buf * gitdir_path ,
426+ git_buf * workdir_path ,
427+ git_buf * gitlink_path ,
428+ git_buf * commondir_path ,
429429 const char * start_path ,
430430 uint32_t flags ,
431431 const char * ceiling_dirs )
@@ -440,7 +440,7 @@ static int find_repo(
440440 bool in_dot_git ;
441441 size_t ceiling_offset = 0 ;
442442
443- git_buf_free ( repo_path );
443+ git_buf_clear ( gitdir_path );
444444
445445 error = git_path_prettify (& path , start_path , NULL );
446446 if (error < 0 )
@@ -482,13 +482,13 @@ static int find_repo(
482482 if (S_ISDIR (st .st_mode )) {
483483 if (valid_repository_path (& path , & common_link )) {
484484 git_path_to_dir (& path );
485- git_buf_set (repo_path , path .ptr , path .size );
485+ git_buf_set (gitdir_path , path .ptr , path .size );
486486
487- if (link_path )
488- git_buf_attach (link_path ,
487+ if (gitlink_path )
488+ git_buf_attach (gitlink_path ,
489489 git_worktree__read_link (path .ptr , GIT_GITDIR_FILE ), 0 );
490- if (common_path )
491- git_buf_swap (& common_link , common_path );
490+ if (commondir_path )
491+ git_buf_swap (& common_link , commondir_path );
492492
493493 break ;
494494 }
@@ -498,12 +498,12 @@ static int find_repo(
498498 if (error < 0 )
499499 break ;
500500 if (valid_repository_path (& repo_link , & common_link )) {
501- git_buf_swap (repo_path , & repo_link );
501+ git_buf_swap (gitdir_path , & repo_link );
502502
503- if (link_path )
504- error = git_buf_put (link_path , path .ptr , path .size );
505- if (common_path )
506- git_buf_swap (& common_link , common_path );
503+ if (gitlink_path )
504+ error = git_buf_put (gitlink_path , path .ptr , path .size );
505+ if (commondir_path )
506+ git_buf_swap (& common_link , commondir_path );
507507 }
508508 break ;
509509 }
@@ -529,20 +529,20 @@ static int find_repo(
529529 break ;
530530 }
531531
532- if (!error && parent_path && !(flags & GIT_REPOSITORY_OPEN_BARE )) {
533- if (!git_buf_len (repo_path ))
534- git_buf_clear (parent_path );
532+ if (!error && workdir_path && !(flags & GIT_REPOSITORY_OPEN_BARE )) {
533+ if (!git_buf_len (gitdir_path ))
534+ git_buf_clear (workdir_path );
535535 else {
536- git_path_dirname_r (parent_path , path .ptr );
537- git_path_to_dir (parent_path );
536+ git_path_dirname_r (workdir_path , path .ptr );
537+ git_path_to_dir (workdir_path );
538538 }
539- if (git_buf_oom (parent_path ))
539+ if (git_buf_oom (workdir_path ))
540540 return -1 ;
541541 }
542542
543543 /* If we didn't find the repository, and we don't have any other error
544544 * to report, report that. */
545- if (!git_buf_len (repo_path ) && !error ) {
545+ if (!git_buf_len (gitdir_path ) && !error ) {
546546 giterr_set (GITERR_REPOSITORY ,
547547 "could not find repository from '%s'" , start_path );
548548 error = GIT_ENOTFOUND ;
@@ -758,15 +758,39 @@ static int _git_repository_open_ext_from_env(
758758 return error ;
759759}
760760
761+ static int repo_is_worktree (unsigned * out , const git_repository * repo )
762+ {
763+ git_buf gitdir_link = GIT_BUF_INIT ;
764+ int error ;
765+
766+ /* Worktrees cannot have the same commondir and gitdir */
767+ if (repo -> commondir && repo -> gitdir
768+ && !strcmp (repo -> commondir , repo -> gitdir )) {
769+ * out = 0 ;
770+ return 0 ;
771+ }
772+
773+ if ((error = git_buf_joinpath (& gitdir_link , repo -> gitdir , "gitdir" )) < 0 )
774+ return -1 ;
775+
776+ /* A 'gitdir' file inside a git directory is currently
777+ * only used when the repository is a working tree. */
778+ * out = !!git_path_exists (gitdir_link .ptr );
779+
780+ git_buf_free (& gitdir_link );
781+ return error ;
782+ }
783+
761784int git_repository_open_ext (
762785 git_repository * * repo_ptr ,
763786 const char * start_path ,
764787 unsigned int flags ,
765788 const char * ceiling_dirs )
766789{
767790 int error ;
768- git_buf path = GIT_BUF_INIT , parent = GIT_BUF_INIT ,
769- link_path = GIT_BUF_INIT , common_path = GIT_BUF_INIT ;
791+ unsigned is_worktree ;
792+ git_buf gitdir = GIT_BUF_INIT , workdir = GIT_BUF_INIT ,
793+ gitlink = GIT_BUF_INIT , commondir = GIT_BUF_INIT ;
770794 git_repository * repo ;
771795 git_config * config = NULL ;
772796
@@ -777,32 +801,29 @@ int git_repository_open_ext(
777801 * repo_ptr = NULL ;
778802
779803 error = find_repo (
780- & path , & parent , & link_path , & common_path , start_path , flags , ceiling_dirs );
804+ & gitdir , & workdir , & gitlink , & commondir , start_path , flags , ceiling_dirs );
781805
782806 if (error < 0 || !repo_ptr )
783807 return error ;
784808
785809 repo = repository_alloc ();
786810 GITERR_CHECK_ALLOC (repo );
787811
788- repo -> gitdir = git_buf_detach (& path );
812+ repo -> gitdir = git_buf_detach (& gitdir );
789813 GITERR_CHECK_ALLOC (repo -> gitdir );
790814
791- if (link_path .size ) {
792- repo -> gitlink = git_buf_detach (& link_path );
815+ if (gitlink .size ) {
816+ repo -> gitlink = git_buf_detach (& gitlink );
793817 GITERR_CHECK_ALLOC (repo -> gitlink );
794818 }
795- if (common_path .size ) {
796- repo -> commondir = git_buf_detach (& common_path );
819+ if (commondir .size ) {
820+ repo -> commondir = git_buf_detach (& commondir );
797821 GITERR_CHECK_ALLOC (repo -> commondir );
798822 }
799823
800- if ((error = git_buf_joinpath ( & path , repo -> gitdir , "gitdir" )) < 0 )
824+ if ((error = repo_is_worktree ( & is_worktree , repo )) < 0 )
801825 goto cleanup ;
802- /* A 'gitdir' file inside a git directory is currently
803- * only used when the repository is a working tree. */
804- if (git_path_exists (path .ptr ))
805- repo -> is_worktree = 1 ;
826+ repo -> is_worktree = is_worktree ;
806827
807828 /*
808829 * We'd like to have the config, but git doesn't particularly
@@ -822,13 +843,13 @@ int git_repository_open_ext(
822843
823844 if (config &&
824845 ((error = load_config_data (repo , config )) < 0 ||
825- (error = load_workdir (repo , config , & parent )) < 0 ))
846+ (error = load_workdir (repo , config , & workdir )) < 0 ))
826847 goto cleanup ;
827848 }
828849
829850cleanup :
830- git_buf_free (& path );
831- git_buf_free (& parent );
851+ git_buf_free (& gitdir );
852+ git_buf_free (& workdir );
832853 git_config_free (config );
833854
834855 if (error < 0 )
0 commit comments