@@ -57,6 +57,8 @@ typedef struct refdb_fs_backend {
5757 git_repository * repo ;
5858 /* path to git directory */
5959 char * gitpath ;
60+ /* path to common objects' directory */
61+ char * commonpath ;
6062
6163 git_sortedcache * refcache ;
6264 int peeling_mode ;
@@ -363,18 +365,32 @@ static const char *loose_parse_symbolic(git_buf *file_content)
363365 return refname_start ;
364366}
365367
368+ static bool is_per_worktree_ref (const char * ref_name )
369+ {
370+ return strcmp ("HEAD" , ref_name ) == 0 ||
371+ strcmp ("FETCH_HEAD" , ref_name ) == 0 ||
372+ strcmp ("MERGE_HEAD" , ref_name ) == 0 ||
373+ strcmp ("ORIG_HEAD" , ref_name ) == 0 ;
374+ }
375+
366376static int loose_lookup (
367377 git_reference * * out ,
368378 refdb_fs_backend * backend ,
369379 const char * ref_name )
370380{
371381 git_buf ref_file = GIT_BUF_INIT ;
372382 int error = 0 ;
383+ const char * ref_dir ;
373384
374385 if (out )
375386 * out = NULL ;
376387
377- if ((error = loose_readbuffer (& ref_file , backend -> gitpath , ref_name )) < 0 )
388+ if (is_per_worktree_ref (ref_name ))
389+ ref_dir = backend -> gitpath ;
390+ else
391+ ref_dir = backend -> commonpath ;
392+
393+ if ((error = loose_readbuffer (& ref_file , ref_dir , ref_name )) < 0 )
378394 /* cannot read loose ref file - gah */ ;
379395 else if (git__prefixcmp (git_buf_cstr (& ref_file ), GIT_SYMREF ) == 0 ) {
380396 const char * target ;
@@ -485,12 +501,12 @@ static int iter_load_loose_paths(refdb_fs_backend *backend, refdb_fs_iter *iter)
485501 git_iterator_options fsit_opts = GIT_ITERATOR_OPTIONS_INIT ;
486502 const git_index_entry * entry = NULL ;
487503
488- if (!backend -> gitpath ) /* do nothing if no gitpath for loose refs */
504+ if (!backend -> commonpath ) /* do nothing if no commonpath for loose refs */
489505 return 0 ;
490506
491507 fsit_opts .flags = backend -> iterator_flags ;
492508
493- if ((error = git_buf_printf (& path , "%s/refs" , backend -> gitpath )) < 0 ||
509+ if ((error = git_buf_printf (& path , "%s/refs" , backend -> commonpath )) < 0 ||
494510 (error = git_iterator_for_filesystem (& fsit , path .ptr , & fsit_opts )) < 0 ) {
495511 git_buf_free (& path );
496512 return error ;
@@ -1410,6 +1426,7 @@ static void refdb_fs_backend__free(git_refdb_backend *_backend)
14101426
14111427 git_sortedcache_free (backend -> refcache );
14121428 git__free (backend -> gitpath );
1429+ git__free (backend -> commonpath );
14131430 git__free (backend );
14141431}
14151432
@@ -1420,6 +1437,8 @@ static int setup_namespace(git_buf *gitpath, git_repository *repo)
14201437 /* Not all repositories have a gitpath */
14211438 if (repo -> path_repository == NULL )
14221439 return 0 ;
1440+ if (repo -> commondir == NULL )
1441+ return 0 ;
14231442
14241443 /* Load the path to the repo first */
14251444 git_buf_puts (gitpath , repo -> path_repository );
@@ -1446,7 +1465,7 @@ static int setup_namespace(git_buf *gitpath, git_repository *repo)
14461465 git__free (parts );
14471466
14481467 /* Make sure that the folder with the namespace exists */
1449- if (git_futils_mkdir_relative (git_buf_cstr (gitpath ), repo -> path_repository ,
1468+ if (git_futils_mkdir_relative (git_buf_cstr (gitpath ), repo -> commondir ,
14501469 0777 , GIT_MKDIR_PATH , NULL ) < 0 )
14511470 return -1 ;
14521471
@@ -1960,9 +1979,11 @@ int git_refdb_backend_fs(
19601979 if (setup_namespace (& gitpath , repository ) < 0 )
19611980 goto fail ;
19621981
1963- backend -> gitpath = git_buf_detach (& gitpath );
1982+ backend -> gitpath = backend -> commonpath = git_buf_detach (& gitpath );
1983+ if (repository -> commondir )
1984+ backend -> commonpath = git__strdup (repository -> commondir );
19641985
1965- if (git_buf_joinpath (& gitpath , backend -> gitpath , GIT_PACKEDREFS_FILE ) < 0 ||
1986+ if (git_buf_joinpath (& gitpath , backend -> commonpath , GIT_PACKEDREFS_FILE ) < 0 ||
19661987 git_sortedcache_new (
19671988 & backend -> refcache , offsetof(struct packref , name ),
19681989 NULL , NULL , packref_cmp , git_buf_cstr (& gitpath )) < 0 )
@@ -2002,6 +2023,7 @@ int git_refdb_backend_fs(
20022023fail :
20032024 git_buf_free (& gitpath );
20042025 git__free (backend -> gitpath );
2026+ git__free (backend -> commonpath );
20052027 git__free (backend );
20062028 return -1 ;
20072029}
0 commit comments