Skip to content

Commit 3c79baf

Browse files
committed
Add reverting reflog move if an error happens.
1 parent 2546030 commit 3c79baf

2 files changed

Lines changed: 19 additions & 0 deletions

File tree

src/libgit2/refdb_fs.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1779,17 +1779,20 @@ static int refdb_fs_backend__rename(
17791779
}
17801780

17811781
if ((error = refdb_fs_backend__delete(_backend, old_name, NULL, NULL)) < 0) {
1782+
refdb_reflog_fs__rename(_backend, new_name, old_name);
17821783
git_reference_free(old);
17831784
return error;
17841785
}
17851786

17861787
new = git_reference__realloc(&old, new_name);
17871788
if (!new) {
1789+
refdb_reflog_fs__rename(_backend, new_name, old_name);
17881790
git_reference_free(old);
17891791
return -1;
17901792
}
17911793

17921794
if ((error = loose_lock(&file, backend, new->name)) < 0) {
1795+
refdb_reflog_fs__rename(_backend, new_name, old_name);
17931796
git_reference_free(new);
17941797
return error;
17951798
}

tests/libgit2/refs/branches/move.c

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -232,3 +232,19 @@ void test_refs_branches_move__moves_reflog_correctly(void)
232232
git_reflog_free(original_reflog);
233233
git_reflog_free(new_reflog);
234234
}
235+
236+
void test_refs_branches_move__failed_move_restores_reflog(void)
237+
{
238+
git_reference *original_ref, *new_ref;
239+
git_reflog *recovered_reflog;
240+
241+
cl_git_pass(git_reference_lookup(&original_ref, repo, "refs/heads/br2"));
242+
243+
cl_assert_equal_i(GIT_EINVALIDSPEC, git_branch_move(&new_ref, original_ref, "Inv@{id", 0));
244+
245+
cl_git_pass(git_reflog_read(&recovered_reflog, repo, "refs/heads/br2"));
246+
cl_assert_equal_i(2, git_reflog_entrycount(recovered_reflog));
247+
248+
git_reference_free(original_ref);
249+
git_reflog_free(recovered_reflog);
250+
}

0 commit comments

Comments
 (0)