@@ -573,12 +573,13 @@ int other_head_refs(each_ref_fn fn, void *cb_data)
573
573
* pointing at <repo>/worktrees/<id>.
574
574
*/
575
575
static void repair_gitfile (struct worktree * wt ,
576
- worktree_repair_fn fn , void * cb_data )
576
+ worktree_repair_fn fn , void * cb_data ,
577
+ int use_relative_paths )
577
578
{
578
579
struct strbuf dotgit = STRBUF_INIT ;
580
+ struct strbuf gitdir = STRBUF_INIT ;
579
581
struct strbuf repo = STRBUF_INIT ;
580
582
struct strbuf backlink = STRBUF_INIT ;
581
- struct strbuf tmp = STRBUF_INIT ;
582
583
char * dotgit_contents = NULL ;
583
584
const char * repair = NULL ;
584
585
int err ;
@@ -594,6 +595,7 @@ static void repair_gitfile(struct worktree *wt,
594
595
595
596
strbuf_realpath (& repo , git_common_path ("worktrees/%s" , wt -> id ), 1 );
596
597
strbuf_addf (& dotgit , "%s/.git" , wt -> path );
598
+ strbuf_addf (& gitdir , "%s/gitdir" , repo .buf );
597
599
dotgit_contents = xstrdup_or_null (read_gitfile_gently (dotgit .buf , & err ));
598
600
599
601
if (dotgit_contents ) {
@@ -611,18 +613,20 @@ static void repair_gitfile(struct worktree *wt,
611
613
repair = _ (".git file broken" );
612
614
else if (fspathcmp (backlink .buf , repo .buf ))
613
615
repair = _ (".git file incorrect" );
616
+ else if (use_relative_paths == is_absolute_path (dotgit_contents ))
617
+ repair = _ (".git file absolute/relative path mismatch" );
614
618
615
619
if (repair ) {
616
620
fn (0 , wt -> path , repair , cb_data );
617
- write_file (dotgit . buf , " gitdir: %s" , relative_path ( repo . buf , wt -> path , & tmp ) );
621
+ write_worktree_linking_files (dotgit , gitdir , use_relative_paths );
618
622
}
619
623
620
624
done :
621
625
free (dotgit_contents );
622
626
strbuf_release (& repo );
623
627
strbuf_release (& dotgit );
628
+ strbuf_release (& gitdir );
624
629
strbuf_release (& backlink );
625
- strbuf_release (& tmp );
626
630
}
627
631
628
632
static void repair_noop (int iserr UNUSED ,
@@ -633,15 +637,15 @@ static void repair_noop(int iserr UNUSED,
633
637
/* nothing */
634
638
}
635
639
636
- void repair_worktrees (worktree_repair_fn fn , void * cb_data )
640
+ void repair_worktrees (worktree_repair_fn fn , void * cb_data , int use_relative_paths )
637
641
{
638
642
struct worktree * * worktrees = get_worktrees_internal (1 );
639
643
struct worktree * * wt = worktrees + 1 ; /* +1 skips main worktree */
640
644
641
645
if (!fn )
642
646
fn = repair_noop ;
643
647
for (; * wt ; wt ++ )
644
- repair_gitfile (* wt , fn , cb_data );
648
+ repair_gitfile (* wt , fn , cb_data , use_relative_paths );
645
649
free_worktrees (worktrees );
646
650
}
647
651
@@ -757,16 +761,14 @@ static ssize_t infer_backlink(const char *gitfile, struct strbuf *inferred)
757
761
* the worktree's path.
758
762
*/
759
763
void repair_worktree_at_path (const char * path ,
760
- worktree_repair_fn fn , void * cb_data )
764
+ worktree_repair_fn fn , void * cb_data ,
765
+ int use_relative_paths )
761
766
{
762
767
struct strbuf dotgit = STRBUF_INIT ;
763
- struct strbuf realdotgit = STRBUF_INIT ;
764
768
struct strbuf backlink = STRBUF_INIT ;
765
769
struct strbuf inferred_backlink = STRBUF_INIT ;
766
770
struct strbuf gitdir = STRBUF_INIT ;
767
771
struct strbuf olddotgit = STRBUF_INIT ;
768
- struct strbuf realolddotgit = STRBUF_INIT ;
769
- struct strbuf tmp = STRBUF_INIT ;
770
772
char * dotgit_contents = NULL ;
771
773
const char * repair = NULL ;
772
774
int err ;
@@ -778,25 +780,25 @@ void repair_worktree_at_path(const char *path,
778
780
goto done ;
779
781
780
782
strbuf_addf (& dotgit , "%s/.git" , path );
781
- if (!strbuf_realpath (& realdotgit , dotgit .buf , 0 )) {
783
+ if (!strbuf_realpath (& dotgit , dotgit .buf , 0 )) {
782
784
fn (1 , path , _ ("not a valid path" ), cb_data );
783
785
goto done ;
784
786
}
785
787
786
- infer_backlink (realdotgit .buf , & inferred_backlink );
788
+ infer_backlink (dotgit .buf , & inferred_backlink );
787
789
strbuf_realpath_forgiving (& inferred_backlink , inferred_backlink .buf , 0 );
788
- dotgit_contents = xstrdup_or_null (read_gitfile_gently (realdotgit .buf , & err ));
790
+ dotgit_contents = xstrdup_or_null (read_gitfile_gently (dotgit .buf , & err ));
789
791
if (dotgit_contents ) {
790
792
if (is_absolute_path (dotgit_contents )) {
791
793
strbuf_addstr (& backlink , dotgit_contents );
792
794
} else {
793
- strbuf_addbuf (& backlink , & realdotgit );
795
+ strbuf_addbuf (& backlink , & dotgit );
794
796
strbuf_strip_suffix (& backlink , ".git" );
795
797
strbuf_addstr (& backlink , dotgit_contents );
796
798
strbuf_realpath_forgiving (& backlink , backlink .buf , 0 );
797
799
}
798
800
} else if (err == READ_GITFILE_ERR_NOT_A_FILE ) {
799
- fn (1 , realdotgit .buf , _ ("unable to locate repository; .git is not a file" ), cb_data );
801
+ fn (1 , dotgit .buf , _ ("unable to locate repository; .git is not a file" ), cb_data );
800
802
goto done ;
801
803
} else if (err == READ_GITFILE_ERR_NOT_A_REPO ) {
802
804
if (inferred_backlink .len ) {
@@ -809,11 +811,11 @@ void repair_worktree_at_path(const char *path,
809
811
*/
810
812
strbuf_swap (& backlink , & inferred_backlink );
811
813
} else {
812
- fn (1 , realdotgit .buf , _ ("unable to locate repository; .git file does not reference a repository" ), cb_data );
814
+ fn (1 , dotgit .buf , _ ("unable to locate repository; .git file does not reference a repository" ), cb_data );
813
815
goto done ;
814
816
}
815
817
} else {
816
- fn (1 , realdotgit .buf , _ ("unable to locate repository; .git file broken" ), cb_data );
818
+ fn (1 , dotgit .buf , _ ("unable to locate repository; .git file broken" ), cb_data );
817
819
goto done ;
818
820
}
819
821
@@ -835,39 +837,35 @@ void repair_worktree_at_path(const char *path,
835
837
* in the "copy" repository. In this case, point the "copy" worktree's
836
838
* .git file at the "copy" repository.
837
839
*/
838
- if (inferred_backlink .len && fspathcmp (backlink .buf , inferred_backlink .buf )) {
840
+ if (inferred_backlink .len && fspathcmp (backlink .buf , inferred_backlink .buf ))
839
841
strbuf_swap (& backlink , & inferred_backlink );
840
- }
841
842
842
843
strbuf_addf (& gitdir , "%s/gitdir" , backlink .buf );
843
844
if (strbuf_read_file (& olddotgit , gitdir .buf , 0 ) < 0 )
844
845
repair = _ ("gitdir unreadable" );
846
+ else if (use_relative_paths == is_absolute_path (olddotgit .buf ))
847
+ repair = _ ("gitdir absolute/relative path mismatch" );
845
848
else {
846
849
strbuf_rtrim (& olddotgit );
847
- if (is_absolute_path (olddotgit .buf )) {
848
- strbuf_addbuf (& realolddotgit , & olddotgit );
849
- } else {
850
- strbuf_addf (& realolddotgit , "%s/%s" , backlink .buf , olddotgit .buf );
851
- strbuf_realpath_forgiving (& realolddotgit , realolddotgit .buf , 0 );
850
+ if (!is_absolute_path (olddotgit .buf )) {
851
+ strbuf_insertf (& olddotgit , 0 , "%s/" , backlink .buf );
852
+ strbuf_realpath_forgiving (& olddotgit , olddotgit .buf , 0 );
852
853
}
853
- if (fspathcmp (realolddotgit .buf , realdotgit .buf ))
854
+ if (fspathcmp (olddotgit .buf , dotgit .buf ))
854
855
repair = _ ("gitdir incorrect" );
855
856
}
856
857
857
858
if (repair ) {
858
859
fn (0 , gitdir .buf , repair , cb_data );
859
- write_file ( gitdir . buf , "%s" , relative_path ( realdotgit . buf , backlink . buf , & tmp ) );
860
+ write_worktree_linking_files ( dotgit , gitdir , use_relative_paths );
860
861
}
861
862
done :
862
863
free (dotgit_contents );
863
864
strbuf_release (& olddotgit );
864
- strbuf_release (& realolddotgit );
865
865
strbuf_release (& backlink );
866
866
strbuf_release (& inferred_backlink );
867
867
strbuf_release (& gitdir );
868
- strbuf_release (& realdotgit );
869
868
strbuf_release (& dotgit );
870
- strbuf_release (& tmp );
871
869
}
872
870
873
871
int should_prune_worktree (const char * id , struct strbuf * reason , char * * wtpath , timestamp_t expire )
0 commit comments