Download raw body.
got branch -d doesn't remove empty parent directory in reference
got branch -d doesn't remove empty parent directory in reference
On Sat, Sep 12, 2026 at 04:42:30PM +0200, Martijn van Duren wrote:
> martijn@
Thanks, here is a fix. Does it work for you?
Please already push your test to got.gameoftrees.org if you have time.
Otherwise I'll send it along with my fix.
M lib/reference.c | 11+ 1-
1 file changed, 11 insertions(+), 1 deletion(-)
commit - 8d7e66e9566a7274917590c6670ea30972d39172
commit + 12c30af2c8a873c913fd1073d99e2f60c08fb60d
blob - 40573c4679ab45fe6119a377d17ee557b87498f2
blob + 50259bff0ca1b0164f56f26dbebb54e36bd1b73d
--- lib/reference.c
+++ lib/reference.c
@@ -1535,7 +1535,7 @@ delete_loose_ref(struct got_reference *ref, struct got
{
const struct got_error *err = NULL, *unlock_err = NULL;
const char *name = got_ref_get_name(ref);
- char *path_refs = NULL, *path = NULL;
+ char *path_refs = NULL, *path = NULL, *parent = NULL;
struct got_lockfile *lf = NULL;
path_refs = get_refs_dir_path(repo, name);
@@ -1549,6 +1549,10 @@ delete_loose_ref(struct got_reference *ref, struct got
goto done;
}
+ err = got_path_dirname(&parent, path);
+ if (err)
+ goto done;
+
if (ref->lf == NULL) {
err = got_lockfile_lock(&lf, path, -1);
if (err)
@@ -1563,8 +1567,14 @@ done:
if (ref->lf == NULL && lf)
unlock_err = got_lockfile_unlock(lf, -1);
+ /* Remove empty directories to make parent reference name available. */
+ if (err == NULL && unlock_err == NULL &&
+ rmdir(parent) == -1 && errno != ENOTEMPTY && errno != ENOENT)
+ err = got_error_from_errno2("rmdir", path);
+
free(path_refs);
free(path);
+ free(parent);
return err ? err : unlock_err;
}
>
> diff /home/martijn/src/got
> path + /home/martijn/src/got
> commit - f85c55bef56ccf3f41b8de4fc0482423541066c7
> blob - 6b14508b86ae76b06c4b422f9dddcb726e665798
> file + regress/cmdline/branch.sh
> --- regress/cmdline/branch.sh
> +++ regress/cmdline/branch.sh
> @@ -672,6 +672,45 @@ test_branch_list_worktree_state() {
> test_done "$testroot" "$ret"
> }
>
> +test_branch_del_child_create_parent() {
> + local testroot=$(test_init branch_del_child_create_parent)
> + local wt="$testroot/wt"
> +
> + set -- "$(git_show_head "$testroot/repo")"
> +
> + got checkout "$testroot/repo" "$wt" > /dev/null
> + ret=$?
> + if [ $ret -ne 0 ]; then
> + echo "checkout failed unexpectedly" >&2
> + test_done "$testroot" "$ret"
> + return 1
> + fi
> +
> + (cd "$wt" && got br -n a/b > /dev/null)
> + ret=$?
> + if [ $ret -ne 0 ]; then
> + echo "branch a/b failed unexpectedly" >&2
> + test_done "$testroot" "$ret"
> + return 1
> + fi
> + (cd "$wt" && got br -d a/b > /dev/null)
> + ret=$?
> + if [ $ret -ne 0 ]; then
> + echo "branch deletion a/b failed unexpectedly" >&2
> + test_done "$testroot" "$ret"
> + return 1
> + fi
> + (cd "$wt" && got br -n a > /dev/null)
> + ret=$?
> + if [ $ret -ne 0 ]; then
> + echo "branch a failed unexpectedly" >&2
> + test_done "$testroot" "$ret"
> + return 1
> + fi
> +
> + test_done "$testroot" "$ret"
> +}
> +
> test_parseargs "$@"
> run_test test_branch_create
> run_test test_branch_list
> @@ -682,3 +721,4 @@ run_test test_branch_show
> run_test test_branch_packed_ref_collision
> run_test test_branch_commit_keywords
> run_test test_branch_list_worktree_state
> +run_test test_branch_del_child_create_parent
>
>
got branch -d doesn't remove empty parent directory in reference
got branch -d doesn't remove empty parent directory in reference