Skip to content

Commit 775af01

Browse files
committed
worktree: report errors when unable to read locking reason
Git worktree's have the ability to be locked in order to spare them from deletion, e.g. if a worktree is absent due to being located on a removable disk it is a good idea to lock it. When locking such worktrees, it is possible to give a locking reason in order to help the user later on when inspecting status of any such locked trees. The function `git_worktree_is_locked` serves to read out the locking status. It currently does not properly report any errors when reading the reason file, and callers are unexpecting of any negative return values, too. Fix this by converting callers to expect error codes and checking the return code of `git_futils_readbuffer`.
1 parent 2288a71 commit 775af01

File tree

1 file changed

+44
-28
lines changed

1 file changed

+44
-28
lines changed

src/worktree.c

Lines changed: 44 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -136,11 +136,11 @@ static int open_worktree_dir(git_worktree **out, const char *parent, const char
136136
goto out;
137137
}
138138

139-
if ((wt->name = git__strdup(name)) == NULL
140-
|| (wt->commondir_path = git_worktree__read_link(dir, "commondir")) == NULL
141-
|| (wt->gitlink_path = git_worktree__read_link(dir, "gitdir")) == NULL
142-
|| (parent && (wt->parent_path = git__strdup(parent)) == NULL)
143-
|| (wt->worktree_path = git_path_dirname(wt->gitlink_path)) == NULL) {
139+
if ((wt->name = git__strdup(name)) == NULL ||
140+
(wt->commondir_path = git_worktree__read_link(dir, "commondir")) == NULL ||
141+
(wt->gitlink_path = git_worktree__read_link(dir, "gitdir")) == NULL ||
142+
(parent && (wt->parent_path = git__strdup(parent)) == NULL) ||
143+
(wt->worktree_path = git_path_dirname(wt->gitlink_path)) == NULL) {
144144
error = -1;
145145
goto out;
146146
}
@@ -149,7 +149,10 @@ static int open_worktree_dir(git_worktree **out, const char *parent, const char
149149
goto out;
150150
wt->gitdir_path = git_buf_detach(&gitdir);
151151

152-
wt->locked = !!git_worktree_is_locked(NULL, wt);
152+
if ((error = git_worktree_is_locked(NULL, wt)) < 0)
153+
goto out;
154+
wt->locked = !!error;
155+
error = 0;
153156

154157
*out = wt;
155158

@@ -403,37 +406,44 @@ int git_worktree_add(git_worktree **out, git_repository *repo,
403406
int git_worktree_lock(git_worktree *wt, const char *reason)
404407
{
405408
git_buf buf = GIT_BUF_INIT, path = GIT_BUF_INIT;
406-
int err;
409+
int error;
407410

408411
assert(wt);
409412

410-
if ((err = git_worktree_is_locked(NULL, wt)) < 0)
413+
if ((error = git_worktree_is_locked(NULL, wt)) < 0)
414+
goto out;
415+
if (error) {
416+
error = GIT_ELOCKED;
411417
goto out;
418+
}
412419

413-
if ((err = git_buf_joinpath(&path, wt->gitdir_path, "locked")) < 0)
420+
if ((error = git_buf_joinpath(&path, wt->gitdir_path, "locked")) < 0)
414421
goto out;
415422

416423
if (reason)
417424
git_buf_attach_notowned(&buf, reason, strlen(reason));
418425

419-
if ((err = git_futils_writebuffer(&buf, path.ptr, O_CREAT|O_EXCL|O_WRONLY, 0644)) < 0)
426+
if ((error = git_futils_writebuffer(&buf, path.ptr, O_CREAT|O_EXCL|O_WRONLY, 0644)) < 0)
420427
goto out;
421428

422429
wt->locked = 1;
423430

424431
out:
425432
git_buf_dispose(&path);
426433

427-
return err;
434+
return error;
428435
}
429436

430437
int git_worktree_unlock(git_worktree *wt)
431438
{
432439
git_buf path = GIT_BUF_INIT;
440+
int error;
433441

434442
assert(wt);
435443

436-
if (!git_worktree_is_locked(NULL, wt))
444+
if ((error = git_worktree_is_locked(NULL, wt)) < 0)
445+
return error;
446+
if (!error)
437447
return 1;
438448

439449
if (git_buf_joinpath(&path, wt->gitdir_path, "locked") < 0)
@@ -454,22 +464,25 @@ int git_worktree_unlock(git_worktree *wt)
454464
int git_worktree_is_locked(git_buf *reason, const git_worktree *wt)
455465
{
456466
git_buf path = GIT_BUF_INIT;
457-
int ret;
467+
int error, locked;
458468

459469
assert(wt);
460470

461471
if (reason)
462472
git_buf_clear(reason);
463473

464-
if ((ret = git_buf_joinpath(&path, wt->gitdir_path, "locked")) < 0)
474+
if ((error = git_buf_joinpath(&path, wt->gitdir_path, "locked")) < 0)
475+
goto out;
476+
locked = git_path_exists(path.ptr);
477+
if (locked && reason &&
478+
(error = git_futils_readbuffer(reason, path.ptr)) < 0)
465479
goto out;
466-
if ((ret = git_path_exists(path.ptr)) && reason)
467-
git_futils_readbuffer(reason, path.ptr);
468480

481+
error = locked;
469482
out:
470483
git_buf_dispose(&path);
471484

472-
return ret;
485+
return error;
473486
}
474487

475488
const char *git_worktree_name(const git_worktree *wt)
@@ -502,7 +515,6 @@ int git_worktree_pruneinit_options(git_worktree_prune_options *opts,
502515
int git_worktree_is_prunable(git_worktree *wt,
503516
git_worktree_prune_options *opts)
504517
{
505-
git_buf reason = GIT_BUF_INIT;
506518
git_worktree_prune_options popts = GIT_WORKTREE_PRUNE_OPTIONS_INIT;
507519

508520
GIT_ERROR_CHECK_VERSION(
@@ -512,20 +524,24 @@ int git_worktree_is_prunable(git_worktree *wt,
512524
if (opts)
513525
memcpy(&popts, opts, sizeof(popts));
514526

515-
if ((popts.flags & GIT_WORKTREE_PRUNE_LOCKED) == 0 &&
516-
git_worktree_is_locked(&reason, wt))
517-
{
518-
if (!reason.size)
519-
git_buf_attach_notowned(&reason, "no reason given", 15);
520-
git_error_set(GIT_ERROR_WORKTREE, "not pruning locked working tree: '%s'", reason.ptr);
521-
git_buf_dispose(&reason);
527+
if ((popts.flags & GIT_WORKTREE_PRUNE_LOCKED) == 0) {
528+
git_buf reason = GIT_BUF_INIT;
529+
int error;
522530

523-
return 0;
531+
if ((error = git_worktree_is_locked(&reason, wt)) < 0)
532+
return error;
533+
534+
if (error) {
535+
if (!reason.size)
536+
git_buf_attach_notowned(&reason, "no reason given", 15);
537+
git_error_set(GIT_ERROR_WORKTREE, "not pruning locked working tree: '%s'", reason.ptr);
538+
git_buf_dispose(&reason);
539+
return 0;
540+
}
524541
}
525542

526543
if ((popts.flags & GIT_WORKTREE_PRUNE_VALID) == 0 &&
527-
git_worktree_validate(wt) == 0)
528-
{
544+
git_worktree_validate(wt) == 0) {
529545
git_error_set(GIT_ERROR_WORKTREE, "not pruning valid working tree");
530546
return 0;
531547
}

0 commit comments

Comments
 (0)