@@ -642,10 +642,9 @@ static int is_main_worktree_path(const char *path)
642
642
* be able to infer the gitdir by manually reading /path/to/worktree/.git,
643
643
* extracting the <id>, and checking if <repo>/worktrees/<id> exists.
644
644
*/
645
- static char * infer_backlink (const char * gitfile )
645
+ static int infer_backlink (const char * gitfile , struct strbuf * inferred )
646
646
{
647
647
struct strbuf actual = STRBUF_INIT ;
648
- struct strbuf inferred = STRBUF_INIT ;
649
648
const char * id ;
650
649
651
650
if (strbuf_read_file (& actual , gitfile , 0 ) < 0 )
@@ -658,17 +657,18 @@ static char *infer_backlink(const char *gitfile)
658
657
id ++ ; /* advance past '/' to point at <id> */
659
658
if (!* id )
660
659
goto error ;
661
- strbuf_git_common_path (& inferred , the_repository , "worktrees/%s" , id );
662
- if (!is_directory (inferred .buf ))
660
+ strbuf_reset (inferred );
661
+ strbuf_git_common_path (inferred , the_repository , "worktrees/%s" , id );
662
+ if (!is_directory (inferred -> buf ))
663
663
goto error ;
664
664
665
665
strbuf_release (& actual );
666
- return strbuf_detach ( & inferred , NULL ) ;
666
+ return 1 ;
667
667
668
668
error :
669
669
strbuf_release (& actual );
670
- strbuf_release ( & inferred );
671
- return NULL ;
670
+ strbuf_reset ( inferred ); /* clear invalid path */
671
+ return 0 ;
672
672
}
673
673
674
674
/*
@@ -680,10 +680,11 @@ void repair_worktree_at_path(const char *path,
680
680
{
681
681
struct strbuf dotgit = STRBUF_INIT ;
682
682
struct strbuf realdotgit = STRBUF_INIT ;
683
+ struct strbuf backlink = STRBUF_INIT ;
684
+ struct strbuf inferred_backlink = STRBUF_INIT ;
683
685
struct strbuf gitdir = STRBUF_INIT ;
684
686
struct strbuf olddotgit = STRBUF_INIT ;
685
- char * backlink = NULL ;
686
- char * inferred_backlink = NULL ;
687
+ char * dotgit_contents = NULL ;
687
688
const char * repair = NULL ;
688
689
int err ;
689
690
@@ -699,23 +700,23 @@ void repair_worktree_at_path(const char *path,
699
700
goto done ;
700
701
}
701
702
702
- inferred_backlink = infer_backlink (realdotgit .buf );
703
- backlink = xstrdup_or_null (read_gitfile_gently (realdotgit .buf , & err ));
704
- if (err == READ_GITFILE_ERR_NOT_A_FILE ) {
703
+ infer_backlink (realdotgit .buf , & inferred_backlink );
704
+ dotgit_contents = xstrdup_or_null (read_gitfile_gently (realdotgit .buf , & err ));
705
+ if (dotgit_contents ) {
706
+ strbuf_addstr (& backlink , dotgit_contents );
707
+ } else if (err == READ_GITFILE_ERR_NOT_A_FILE ) {
705
708
fn (1 , realdotgit .buf , _ ("unable to locate repository; .git is not a file" ), cb_data );
706
709
goto done ;
707
710
} else if (err == READ_GITFILE_ERR_NOT_A_REPO ) {
708
- if (inferred_backlink ) {
711
+ if (inferred_backlink . len ) {
709
712
/*
710
713
* Worktree's .git file does not point at a repository
711
714
* but we found a .git/worktrees/<id> in this
712
715
* repository with the same <id> as recorded in the
713
716
* worktree's .git file so make the worktree point at
714
- * the discovered .git/worktrees/<id>. (Note: backlink
715
- * is already NULL, so no need to free it first.)
717
+ * the discovered .git/worktrees/<id>.
716
718
*/
717
- backlink = inferred_backlink ;
718
- inferred_backlink = NULL ;
719
+ strbuf_swap (& backlink , & inferred_backlink );
719
720
} else {
720
721
fn (1 , realdotgit .buf , _ ("unable to locate repository; .git file does not reference a repository" ), cb_data );
721
722
goto done ;
@@ -743,13 +744,11 @@ void repair_worktree_at_path(const char *path,
743
744
* in the "copy" repository. In this case, point the "copy" worktree's
744
745
* .git file at the "copy" repository.
745
746
*/
746
- if (inferred_backlink && fspathcmp (backlink , inferred_backlink )) {
747
- free (backlink );
748
- backlink = inferred_backlink ;
749
- inferred_backlink = NULL ;
747
+ if (inferred_backlink .len && fspathcmp (backlink .buf , inferred_backlink .buf )) {
748
+ strbuf_swap (& backlink , & inferred_backlink );
750
749
}
751
750
752
- strbuf_addf (& gitdir , "%s/gitdir" , backlink );
751
+ strbuf_addf (& gitdir , "%s/gitdir" , backlink . buf );
753
752
if (strbuf_read_file (& olddotgit , gitdir .buf , 0 ) < 0 )
754
753
repair = _ ("gitdir unreadable" );
755
754
else {
@@ -763,9 +762,10 @@ void repair_worktree_at_path(const char *path,
763
762
write_file (gitdir .buf , "%s" , realdotgit .buf );
764
763
}
765
764
done :
766
- free (backlink );
767
- free (inferred_backlink );
765
+ free (dotgit_contents );
768
766
strbuf_release (& olddotgit );
767
+ strbuf_release (& backlink );
768
+ strbuf_release (& inferred_backlink );
769
769
strbuf_release (& gitdir );
770
770
strbuf_release (& realdotgit );
771
771
strbuf_release (& dotgit );
0 commit comments