@@ -19,54 +19,25 @@ void free_worktrees(struct worktree **worktrees)
1919 free (worktrees );
2020}
2121
22- /*
23- * read 'path_to_ref' into 'ref'. Also if is_detached is not NULL,
24- * set is_detached to 1 (0) if the ref is detached (is not detached).
25- *
26- * $GIT_COMMON_DIR/$symref (e.g. HEAD) is practically outside $GIT_DIR so
27- * for linked worktrees, `resolve_ref_unsafe()` won't work (it uses
28- * git_path). Parse the ref ourselves.
29- *
30- * return -1 if the ref is not a proper ref, 0 otherwise (success)
31- */
32- static int parse_ref (char * path_to_ref , struct strbuf * ref , int * is_detached )
33- {
34- if (is_detached )
35- * is_detached = 0 ;
36- if (!strbuf_readlink (ref , path_to_ref , 0 )) {
37- /* HEAD is symbolic link */
38- if (!starts_with (ref -> buf , "refs/" ) ||
39- check_refname_format (ref -> buf , 0 ))
40- return -1 ;
41- } else if (strbuf_read_file (ref , path_to_ref , 0 ) >= 0 ) {
42- /* textual symref or detached */
43- if (!starts_with (ref -> buf , "ref:" )) {
44- if (is_detached )
45- * is_detached = 1 ;
46- } else {
47- strbuf_remove (ref , 0 , strlen ("ref:" ));
48- strbuf_trim (ref );
49- if (check_refname_format (ref -> buf , 0 ))
50- return -1 ;
51- }
52- } else
53- return -1 ;
54- return 0 ;
55- }
56-
5722/**
58- * Add the head_sha1 and head_ref (if not detached) to the given worktree
23+ * Update head_sha1, head_ref and is_detached of the given worktree
5924 */
60- static void add_head_info (struct strbuf * head_ref , struct worktree * worktree )
25+ static void add_head_info (struct worktree * wt )
6126{
62- if (head_ref -> len ) {
63- if (worktree -> is_detached ) {
64- get_sha1_hex (head_ref -> buf , worktree -> head_sha1 );
65- } else {
66- resolve_ref_unsafe (head_ref -> buf , 0 , worktree -> head_sha1 , NULL );
67- worktree -> head_ref = strbuf_detach (head_ref , NULL );
68- }
69- }
27+ int flags ;
28+ const char * target ;
29+
30+ target = refs_resolve_ref_unsafe (get_worktree_ref_store (wt ),
31+ "HEAD" ,
32+ RESOLVE_REF_READING ,
33+ wt -> head_sha1 , & flags );
34+ if (!target )
35+ return ;
36+
37+ if (flags & REF_ISSYMREF )
38+ wt -> head_ref = xstrdup (target );
39+ else
40+ wt -> is_detached = 1 ;
7041}
7142
7243/**
@@ -77,9 +48,7 @@ static struct worktree *get_main_worktree(void)
7748 struct worktree * worktree = NULL ;
7849 struct strbuf path = STRBUF_INIT ;
7950 struct strbuf worktree_path = STRBUF_INIT ;
80- struct strbuf head_ref = STRBUF_INIT ;
8151 int is_bare = 0 ;
82- int is_detached = 0 ;
8352
8453 strbuf_add_absolute_path (& worktree_path , get_git_common_dir ());
8554 is_bare = !strbuf_strip_suffix (& worktree_path , "/.git" );
@@ -91,13 +60,10 @@ static struct worktree *get_main_worktree(void)
9160 worktree = xcalloc (1 , sizeof (* worktree ));
9261 worktree -> path = strbuf_detach (& worktree_path , NULL );
9362 worktree -> is_bare = is_bare ;
94- worktree -> is_detached = is_detached ;
95- if (!parse_ref (path .buf , & head_ref , & is_detached ))
96- add_head_info (& head_ref , worktree );
63+ add_head_info (worktree );
9764
9865 strbuf_release (& path );
9966 strbuf_release (& worktree_path );
100- strbuf_release (& head_ref );
10167 return worktree ;
10268}
10369
@@ -106,8 +72,6 @@ static struct worktree *get_linked_worktree(const char *id)
10672 struct worktree * worktree = NULL ;
10773 struct strbuf path = STRBUF_INIT ;
10874 struct strbuf worktree_path = STRBUF_INIT ;
109- struct strbuf head_ref = STRBUF_INIT ;
110- int is_detached = 0 ;
11175
11276 if (!id )
11377 die ("Missing linked worktree name" );
@@ -127,19 +91,14 @@ static struct worktree *get_linked_worktree(const char *id)
12791 strbuf_reset (& path );
12892 strbuf_addf (& path , "%s/worktrees/%s/HEAD" , get_git_common_dir (), id );
12993
130- if (parse_ref (path .buf , & head_ref , & is_detached ) < 0 )
131- goto done ;
132-
13394 worktree = xcalloc (1 , sizeof (* worktree ));
13495 worktree -> path = strbuf_detach (& worktree_path , NULL );
13596 worktree -> id = xstrdup (id );
136- worktree -> is_detached = is_detached ;
137- add_head_info (& head_ref , worktree );
97+ add_head_info (worktree );
13898
13999done :
140100 strbuf_release (& path );
141101 strbuf_release (& worktree_path );
142- strbuf_release (& head_ref );
143102 return worktree ;
144103}
145104
@@ -334,8 +293,6 @@ const struct worktree *find_shared_symref(const char *symref,
334293 const char * target )
335294{
336295 const struct worktree * existing = NULL ;
337- struct strbuf path = STRBUF_INIT ;
338- struct strbuf sb = STRBUF_INIT ;
339296 static struct worktree * * worktrees ;
340297 int i = 0 ;
341298
@@ -345,6 +302,11 @@ const struct worktree *find_shared_symref(const char *symref,
345302
346303 for (i = 0 ; worktrees [i ]; i ++ ) {
347304 struct worktree * wt = worktrees [i ];
305+ const char * symref_target ;
306+ unsigned char sha1 [20 ];
307+ struct ref_store * refs ;
308+ int flags ;
309+
348310 if (wt -> is_bare )
349311 continue ;
350312
@@ -359,25 +321,15 @@ const struct worktree *find_shared_symref(const char *symref,
359321 }
360322 }
361323
362- strbuf_reset (& path );
363- strbuf_reset (& sb );
364- strbuf_addf (& path , "%s/%s" ,
365- get_worktree_git_dir (wt ),
366- symref );
367-
368- if (parse_ref (path .buf , & sb , NULL )) {
369- continue ;
370- }
371-
372- if (!strcmp (sb .buf , target )) {
324+ refs = get_worktree_ref_store (wt );
325+ symref_target = refs_resolve_ref_unsafe (refs , symref , 0 ,
326+ sha1 , & flags );
327+ if ((flags & REF_ISSYMREF ) && !strcmp (symref_target , target )) {
373328 existing = wt ;
374329 break ;
375330 }
376331 }
377332
378- strbuf_release (& path );
379- strbuf_release (& sb );
380-
381333 return existing ;
382334}
383335
0 commit comments