Remove empty (sub-)directories when deleting refs#4833
Remove empty (sub-)directories when deleting refs#4833pks-t merged 1 commit intolibgit2:masterfrom csware:drop-empty-dirs
Conversation
pks-t
left a comment
There was a problem hiding this comment.
Thanks for tackling this! I've accidentally also implemented a fix yesterday, but didn't yet upload it. I think essentially, both fixes boiled down to the same thing: using the rmdir_r function that's already available. I already got enough PRs open right now that I have to handle, so I'm going to favour yours :)
src/refdb_fs.c
Outdated
| git_buf base_path = GIT_BUF_INIT; | ||
| git_buf relative_path = GIT_BUF_INIT; | ||
| int just_delete = 1; | ||
| int error = 0; |
There was a problem hiding this comment.
No need to initialize error = 0, as you immediately set it in the first statement
src/refdb_fs.c
Outdated
| const char *ref_name, | ||
| const char *ref_path, | ||
| bool reflog | ||
| ) |
There was a problem hiding this comment.
The opening bracket belongs on the last line
src/refdb_fs.c
Outdated
|
|
||
| while (*start_ptr == '/') /* drop multiple path separators */ | ||
| ++start_ptr; | ||
| } |
There was a problem hiding this comment.
I think this is a bit too lenient. E.g. if I'm creating a thing "foo/bar/x", it will just skip "foo/bar". I think we should instead explicitly special-case precious directories:
git_buf_sets(&buf, ref_name);
git_path_squash_slashes(&buf);
if ((commonlen = git_path_common_dirlen("refs/heads/", buf.ptr)) ||
(commonlen = git_path_common_dirlen("refs/tags/", buf.ptr)) ||
...) {
git_buf base = GIT_BUF_INIT;
git_buf_printf(&base, "%s/%.*s", backend->commonpath, commonlen, buf.ptr);
git_futils_rmdir_r(ref_path + commonlen, base.ptr, GIT_RMDIR_EMPTY_PARENTS|GIT_RMDIR_REMOVE_FILES|GIT_RMDIR_SKIP_ROOT);
} else {
p_unlink(ref_path);
}
Something like the above. It's completely untested and out of my head, but I guess it's sufficient to demonstrate what I imagine.
src/refdb_fs.c
Outdated
|
|
||
| error = packed_write(backend); | ||
| /* unlock here, so that we can delete the all empty parents */ | ||
| git_filebuf_cleanup(file); |
There was a problem hiding this comment.
We're cleaning up file twice now, aren't we?
There was a problem hiding this comment.
We need to close the lock file before we can remove the possibly empty parents, otherwise it won't work. And we still need it in the cleanup path. As cleanup disposes the internal buffer, calling it twice doesn't cause problems.
src/refdb_fs.c
Outdated
| /* unlock here, so that we can delete the all empty parents */ | ||
| git_filebuf_cleanup(file); | ||
|
|
||
| error = refdb_fs_backend__delete_empty_parents(backend, ref_name, git_buf_cstr(&loose_path), false); |
There was a problem hiding this comment.
I think we should rename this function. It doesn't only remove parents, but also the reference itself.
|
@pks-t Updated... |
|
/rebuild |
|
Okay, @tiennou, I started to rebuild this pull request. |
|
/rebuild |
|
Sorry @csware, you're not allowed to do that. |
|
@ethomson: shouldn't PR owners be allowed to rebuild their own PRs? |
|
Sure, I'll track that at
ethomson/probot-azure-pipelines#5
…On Thu, Oct 11, 2018 at 12:06 PM Patrick Steinhardt < ***@***.***> wrote:
@ethomson <https://github.com/ethomson>: shouldn't PR owners be allowed
to rebuild their own PRs?
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#4833 (comment)>, or mute
the thread
<https://github.com/notifications/unsubscribe-auth/ABE-HsQKbGIQigUpQvWkZl0fctQq38JSks5ujyYfgaJpZM4XKDLJ>
.
|
|
@pks-t Any new comments? |
|
Huh, CI is still failing. Let's try it again |
|
/rebuild |
|
Okay, @pks-t, I started to rebuild this pull request. |
|
@ethomson: seems like CI is currently having problems? |
|
The CI is not having problems, the code simply doesn't compile. |
I see Docker issues: |
|
It's reporting the first things that hit stderr. Expand the section. |
|
Ooh, that's why. I've also only spotted the Docker issues, didn't even think it might hide the relevant information. |
|
Yeah, unfortunately since we're running inside docker we can't just push all its noisy stderr to stdout, since we'd also be doing that for the things being executed in the container. :/ But I'm going to investigate this a big more since having the relevant problems up-front (and not "behind the fold") would be a big improvement. |
tests/refs/branches/delete.c
Outdated
| cl_git_pass(git_oid_fromstr(&commit_id, "a65fedf39aefe402d3bb6e24df4d4f5fe4547750")); | ||
| cl_git_pass(git_commit_lookup(&commit, repo, &commit_id)); | ||
| cl_git_pass(git_branch_create(&branch, repo, "some/deep/ref", commit, 0)); | ||
| git_commit_free(&commit); |
There was a problem hiding this comment.
Ci says:
/src/tests/refs/branches/delete.c: In function 'test_refs_branches_delete__removes_empty_folders':
/src/tests/refs/branches/delete.c:163:2: warning: passing argument 1 of 'git_commit_free' from incompatible pointer type [enabled by default]
git_commit_free(&commit);
^
In file included from /src/include/git2.h:20:0,
from /src/tests/clar_libgit2.h:5,
from /src/tests/refs/branches/delete.c:1:
/src/include/git2/commit.h:70:18: note: expected 'struct git_commit *' but argument is of type 'struct git_commit **'
GIT_EXTERN(void) git_commit_free(git_commit *commit);
^
So you probably want to pass commit rather than &commit.
I wonder why this doesn't result in a compilation failure...
Signed-off-by: Sven Strickroth <email@cs-ware.de>
|
@pks-t |
|
Indeed they are. Thanks for being patient and for your work! |
Fixes issue #4806.