New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Remove empty (sub-)directories when deleting refs #4833
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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
goto cleanup; | ||
} | ||
|
||
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We're cleaning up file
twice now, aren't we?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.