From 01d0c02dbaa8856c4e2481ab1435bdf7df58690a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn=20Nieto?= Date: Sun, 12 Jul 2015 19:08:06 +0200 Subject: refdb: delete a ref's reflog upon deletion Removing a reflog upon ref deletion is something which only some backends might wish to do. Backends which are database-backed may wish to archive a reflog, log-based ones may not need to do anything. --- CHANGELOG.md | 4 ++++ include/git2/sys/refdb_backend.h | 5 +++-- src/branch.c | 13 +------------ src/refdb_fs.c | 7 +++++++ tests/refs/branches/delete.c | 2 ++ 5 files changed, 17 insertions(+), 14 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c0a819ed7..243b696d7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,10 @@ v0.23 + 1 * `git_cert` descendent types now have a proper `parent` member +* It is the responsibility fo the refdb backend to decide what to do + with the reflog on ref deletion. The file-based backend must delete + it, a database-backed one may wish to archive it. + v0.23 ------ diff --git a/include/git2/sys/refdb_backend.h b/include/git2/sys/refdb_backend.h index d943e550f..9f2a99b7e 100644 --- a/include/git2/sys/refdb_backend.h +++ b/include/git2/sys/refdb_backend.h @@ -103,8 +103,9 @@ struct git_refdb_backend { const git_signature *who, const char *message); /** - * Deletes the given reference from the refdb. A refdb implementation - * must provide this function. + * Deletes the given reference (and if necessary its reflog) + * from the refdb. A refdb implementation must provide this + * function. */ int (*del)(git_refdb_backend *backend, const char *ref_name, const git_oid *old_id, const char *old_target); diff --git a/src/branch.c b/src/branch.c index 791d55106..0dcc14c29 100644 --- a/src/branch.c +++ b/src/branch.c @@ -155,18 +155,7 @@ int git_branch_delete(git_reference *branch) git_reference_owner(branch), git_buf_cstr(&config_section), NULL) < 0) goto on_error; - if (git_reference_delete(branch) < 0) - goto on_error; - - if ((error = git_reflog_delete(git_reference_owner(branch), git_reference_name(branch))) < 0) { - if (error == GIT_ENOTFOUND) { - giterr_clear(); - error = 0; - } - goto on_error; - } - - error = 0; + error = git_reference_delete(branch); on_error: git_buf_free(&config_section); diff --git a/src/refdb_fs.c b/src/refdb_fs.c index e1a77f3ff..55d535eb4 100644 --- a/src/refdb_fs.c +++ b/src/refdb_fs.c @@ -63,6 +63,8 @@ typedef struct refdb_fs_backend { uint32_t direach_flags; } refdb_fs_backend; +static int refdb_reflog_fs__delete(git_refdb_backend *_backend, const char *name); + static int packref_cmp(const void *a_, const void *b_) { const struct packref *a = a_, *b = b_; @@ -1217,6 +1219,11 @@ static int refdb_fs_backend__delete( if ((error = loose_lock(&file, backend, ref_name)) < 0) return error; + if ((error = refdb_reflog_fs__delete(_backend, ref_name)) < 0) { + git_filebuf_cleanup(&file); + return error; + } + return refdb_fs_backend__delete_tail(_backend, &file, ref_name, old_id, old_target); } diff --git a/tests/refs/branches/delete.c b/tests/refs/branches/delete.c index 343ff0f50..8807db231 100644 --- a/tests/refs/branches/delete.c +++ b/tests/refs/branches/delete.c @@ -132,6 +132,8 @@ void test_refs_branches_delete__removes_reflog(void) cl_git_pass(git_branch_delete(branch)); git_reference_free(branch); + cl_assert_equal_i(false, git_reference_has_log(repo, "refs/heads/track-local")); + /* Reading a nonexistant reflog creates it, but it should be empty */ cl_git_pass(git_reflog_read(&log, repo, "refs/heads/track-local")); cl_assert_equal_i(0, git_reflog_entrycount(log)); -- cgit v1.2.1