Skip to content

Commit bb4a883

Browse files
calebdwgitster
authored andcommitted
worktree: refactor infer_backlink() to use *strbuf
This lays the groundwork for the next patch, which needs the backlink returned from infer_backlink() as a `strbuf`. It seemed inefficient to convert from `strbuf` to `char*` and back to `strbuf` again. This refactors infer_backlink() to return an integer result and use a pre-allocated `strbuf` for the inferred backlink path, replacing the previous `char*` return type and improving efficiency. Signed-off-by: Caleb White <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 58d8805 commit bb4a883

File tree

1 file changed

+24
-24
lines changed

1 file changed

+24
-24
lines changed

worktree.c

Lines changed: 24 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -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

668668
error:
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
}
765764
done:
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

Comments
 (0)