@@ -642,10 +642,9 @@ static int is_main_worktree_path(const char *path)
642642 * be able to infer the gitdir by manually reading /path/to/worktree/.git,
643643 * extracting the <id>, and checking if <repo>/worktrees/<id> exists.
644644 */
645- static char * infer_backlink (const char * gitfile )
645+ static int infer_backlink (const char * gitfile , struct strbuf * inferred )
646646{
647647 struct strbuf actual = STRBUF_INIT ;
648- struct strbuf inferred = STRBUF_INIT ;
649648 const char * id ;
650649
651650 if (strbuf_read_file (& actual , gitfile , 0 ) < 0 )
@@ -658,17 +657,18 @@ static char *infer_backlink(const char *gitfile)
658657 id ++ ; /* advance past '/' to point at <id> */
659658 if (!* id )
660659 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 ))
663663 goto error ;
664664
665665 strbuf_release (& actual );
666- return strbuf_detach ( & inferred , NULL ) ;
666+ return 1 ;
667667
668668error :
669669 strbuf_release (& actual );
670- strbuf_release ( & inferred );
671- return NULL ;
670+ strbuf_reset ( inferred ); /* clear invalid path */
671+ return 0 ;
672672}
673673
674674/*
@@ -680,10 +680,11 @@ void repair_worktree_at_path(const char *path,
680680{
681681 struct strbuf dotgit = STRBUF_INIT ;
682682 struct strbuf realdotgit = STRBUF_INIT ;
683+ struct strbuf backlink = STRBUF_INIT ;
684+ struct strbuf inferred_backlink = STRBUF_INIT ;
683685 struct strbuf gitdir = STRBUF_INIT ;
684686 struct strbuf olddotgit = STRBUF_INIT ;
685- char * backlink = NULL ;
686- char * inferred_backlink = NULL ;
687+ char * dotgit_contents = NULL ;
687688 const char * repair = NULL ;
688689 int err ;
689690
@@ -699,23 +700,23 @@ void repair_worktree_at_path(const char *path,
699700 goto done ;
700701 }
701702
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 ) {
705708 fn (1 , realdotgit .buf , _ ("unable to locate repository; .git is not a file" ), cb_data );
706709 goto done ;
707710 } else if (err == READ_GITFILE_ERR_NOT_A_REPO ) {
708- if (inferred_backlink ) {
711+ if (inferred_backlink . len ) {
709712 /*
710713 * Worktree's .git file does not point at a repository
711714 * but we found a .git/worktrees/<id> in this
712715 * repository with the same <id> as recorded in the
713716 * 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>.
716718 */
717- backlink = inferred_backlink ;
718- inferred_backlink = NULL ;
719+ strbuf_swap (& backlink , & inferred_backlink );
719720 } else {
720721 fn (1 , realdotgit .buf , _ ("unable to locate repository; .git file does not reference a repository" ), cb_data );
721722 goto done ;
@@ -743,13 +744,11 @@ void repair_worktree_at_path(const char *path,
743744 * in the "copy" repository. In this case, point the "copy" worktree's
744745 * .git file at the "copy" repository.
745746 */
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 );
750749 }
751750
752- strbuf_addf (& gitdir , "%s/gitdir" , backlink );
751+ strbuf_addf (& gitdir , "%s/gitdir" , backlink . buf );
753752 if (strbuf_read_file (& olddotgit , gitdir .buf , 0 ) < 0 )
754753 repair = _ ("gitdir unreadable" );
755754 else {
@@ -763,9 +762,10 @@ void repair_worktree_at_path(const char *path,
763762 write_file (gitdir .buf , "%s" , realdotgit .buf );
764763 }
765764done :
766- free (backlink );
767- free (inferred_backlink );
765+ free (dotgit_contents );
768766 strbuf_release (& olddotgit );
767+ strbuf_release (& backlink );
768+ strbuf_release (& inferred_backlink );
769769 strbuf_release (& gitdir );
770770 strbuf_release (& realdotgit );
771771 strbuf_release (& dotgit );
0 commit comments