Update _WIN32_IE to IE 8.0
[TortoiseGit.git] / ext / libgit2-0008-Remove-empty-directories-when-deleting-refs.patch
blob4240eb0ddc65c8af4b55a8bbd4185194f1c3257c
1 From 9f48dc3b73be1036da7b2a5a5e03346513aebf9a Mon Sep 17 00:00:00 2001
2 From: Sven Strickroth <email@cs-ware.de>
3 Date: Fri, 5 Oct 2018 12:47:32 +0200
4 Subject: [PATCH] Remove empty directories when deleting refs
6 Signed-off-by: Sven Strickroth <email@cs-ware.de>
7 ---
8 src/refdb_fs.c | 44 ++++++++++++++++++++++++++++++++--
9 tests/refs/branches/delete.c | 46 ++++++++++++++++++++++++++++++++++++
10 2 files changed, 88 insertions(+), 2 deletions(-)
12 diff --git a/src/refdb_fs.c b/src/refdb_fs.c
13 index 49b567c082..dfff5d3962 100644
14 --- a/src/refdb_fs.c
15 +++ b/src/refdb_fs.c
16 @@ -1305,6 +1305,43 @@ static int refdb_fs_backend__write_tail(
17 return error;
20 +static void refdb_fs_backend__try_delete_empty_ref_hierarchie(
21 + refdb_fs_backend *backend,
22 + const char *ref_name,
23 + bool reflog)
25 + git_buf relative_path = GIT_BUF_INIT;
26 + git_buf base_path = GIT_BUF_INIT;
27 + size_t commonlen;
29 + assert(backend && ref_name);
31 + if (git_buf_sets(&relative_path, ref_name) < 0)
32 + goto cleanup;
34 + git_path_squash_slashes(&relative_path);
35 + if ((commonlen = git_path_common_dirlen("refs/heads/", git_buf_cstr(&relative_path))) == strlen("refs/heads/") ||
36 + (commonlen = git_path_common_dirlen("refs/tags/", git_buf_cstr(&relative_path))) == strlen("refs/tags/") ||
37 + (commonlen = git_path_common_dirlen("refs/remotes/", git_buf_cstr(&relative_path))) == strlen("refs/remotes/")) {
39 + git_buf_truncate(&relative_path, commonlen);
41 + if (reflog) {
42 + if (git_buf_join3(&base_path, '/', backend->commonpath, GIT_REFLOG_DIR, git_buf_cstr(&relative_path)) < 0)
43 + goto cleanup;
44 + } else {
45 + if (git_buf_joinpath(&base_path, backend->commonpath, git_buf_cstr(&relative_path)) < 0)
46 + goto cleanup;
47 + }
49 + git_futils_rmdir_r(ref_name + commonlen, git_buf_cstr(&base_path), GIT_RMDIR_EMPTY_PARENTS | GIT_RMDIR_SKIP_ROOT);
50 + }
52 +cleanup:
53 + git_buf_dispose(&relative_path);
54 + git_buf_dispose(&base_path);
57 static int refdb_fs_backend__delete(
58 git_refdb_backend *_backend,
59 const char *ref_name,
60 @@ -1385,7 +1422,8 @@ static int refdb_fs_backend__delete_tail(
61 cleanup:
62 git_buf_dispose(&loose_path);
63 git_filebuf_cleanup(file);
65 + if (loose_deleted)
66 + refdb_fs_backend__try_delete_empty_ref_hierarchie(backend, ref_name, false);
67 return error;
70 @@ -2013,8 +2051,10 @@ static int refdb_reflog_fs__delete(git_refdb_backend *_backend, const char *name
72 error = retrieve_reflog_path(&path, repo, name);
74 - if (!error && git_path_exists(path.ptr))
75 + if (!error && git_path_exists(path.ptr)) {
76 error = p_unlink(path.ptr);
77 + refdb_fs_backend__try_delete_empty_ref_hierarchie(backend, name, true);
78 + }
80 git_buf_dispose(&path);
82 diff --git a/tests/refs/branches/delete.c b/tests/refs/branches/delete.c
83 index 8807db2319..928adf73ae 100644
84 --- a/tests/refs/branches/delete.c
85 +++ b/tests/refs/branches/delete.c
86 @@ -2,6 +2,8 @@
87 #include "refs.h"
88 #include "repo/repo_helpers.h"
89 #include "config/config_helpers.h"
90 +#include "fileops.h"
91 +#include "reflog.h"
93 static git_repository *repo;
94 static git_reference *fake_remote;
95 @@ -140,3 +142,47 @@ void test_refs_branches_delete__removes_reflog(void)
96 git_reflog_free(log);
99 +void test_refs_branches_delete__removes_empty_folders(void)
101 + const char *commondir = git_repository_commondir(repo);
102 + git_oid commit_id;
103 + git_commit *commit;
104 + git_reference *branch;
106 + git_reflog *log;
107 + git_oid oidzero = {{0}};
108 + git_signature *sig;
110 + git_buf ref_folder = GIT_BUF_INIT;
111 + git_buf reflog_folder = GIT_BUF_INIT;
113 + /* Create a new branch with a nested name */
114 + cl_git_pass(git_oid_fromstr(&commit_id, "a65fedf39aefe402d3bb6e24df4d4f5fe4547750"));
115 + cl_git_pass(git_commit_lookup(&commit, repo, &commit_id));
116 + cl_git_pass(git_branch_create(&branch, repo, "some/deep/ref", commit, 0));
117 + git_commit_free(commit);
119 + /* Ensure the reflog has at least one entry */
120 + cl_git_pass(git_signature_now(&sig, "Me", "user@example.com"));
121 + cl_git_pass(git_reflog_read(&log, repo, "refs/heads/some/deep/ref"));
122 + cl_git_pass(git_reflog_append(log, &oidzero, sig, "message"));
123 + cl_assert(git_reflog_entrycount(log) > 0);
124 + git_signature_free(sig);
125 + git_reflog_free(log);
127 + cl_git_pass(git_buf_joinpath(&ref_folder, commondir, "refs/heads/some/deep"));
128 + cl_git_pass(git_buf_join3(&reflog_folder, '/', commondir, GIT_REFLOG_DIR, "refs/heads/some/deep"));
130 + cl_assert(git_path_exists(git_buf_cstr(&ref_folder)) == true);
131 + cl_assert(git_path_exists(git_buf_cstr(&reflog_folder)) == true);
133 + cl_git_pass(git_branch_delete(branch));
135 + cl_assert(git_path_exists(git_buf_cstr(&ref_folder)) == false);
136 + cl_assert(git_path_exists(git_buf_cstr(&reflog_folder)) == false);
138 + git_reference_free(branch);
139 + git_buf_dispose(&ref_folder);
140 + git_buf_dispose(&reflog_folder);