Skip to content

Commit 2546030

Browse files
committed
Fixes libgit2#6344: git_branch_move now renames the reflog instead of deleting.
1 parent 1a94d97 commit 2546030

2 files changed

Lines changed: 38 additions & 5 deletions

File tree

src/libgit2/refdb_fs.c

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1769,6 +1769,15 @@ static int refdb_fs_backend__rename(
17691769
(error = refdb_fs_backend__lookup(&old, _backend, old_name)) < 0)
17701770
return error;
17711771

1772+
/* Try to rename the refog; it's ok if the old doesn't exist */
1773+
/* Must be done before calling refdb_fs_backend__delete, otherwise */
1774+
/* the reflog is deleted before being renamed. */
1775+
error = refdb_reflog_fs__rename(_backend, old_name, new_name);
1776+
if ((error != 0) && (error != GIT_ENOTFOUND)) {
1777+
git_reference_free(old);
1778+
return error;
1779+
}
1780+
17721781
if ((error = refdb_fs_backend__delete(_backend, old_name, NULL, NULL)) < 0) {
17731782
git_reference_free(old);
17741783
return error;
@@ -1785,10 +1794,7 @@ static int refdb_fs_backend__rename(
17851794
return error;
17861795
}
17871796

1788-
/* Try to rename the refog; it's ok if the old doesn't exist */
1789-
error = refdb_reflog_fs__rename(_backend, old_name, new_name);
1790-
if (((error == 0) || (error == GIT_ENOTFOUND)) &&
1791-
((error = reflog_append(backend, new, git_reference_target(new), NULL, who, message)) < 0)) {
1797+
if ((error = reflog_append(backend, new, git_reference_target(new), NULL, who, message)) < 0) {
17921798
git_reference_free(new);
17931799
git_filebuf_cleanup(&file);
17941800
return error;
@@ -2368,7 +2374,12 @@ static int refdb_reflog_fs__delete(git_refdb_backend *_backend, const char *name
23682374
if ((error = reflog_path(&path, backend->repo, name)) < 0)
23692375
goto out;
23702376

2371-
if (!git_fs_path_exists(path.ptr))
2377+
/*
2378+
* If a reference was moved downwards, eg refs/heads/br2 -> refs/heads/br2/new-name,
2379+
* refs/heads/br2 does exist but it's a directory. That's a valid situation.
2380+
* Proceed only if it's a file.
2381+
*/
2382+
if (!git_fs_path_isfile(path.ptr))
23722383
goto out;
23732384

23742385
if ((error = p_unlink(path.ptr)) < 0)

tests/libgit2/refs/branches/move.c

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,3 +210,25 @@ void test_refs_branches_move__can_move_with_unicode(void)
210210
git_reference_free(original_ref);
211211
git_reference_free(new_ref);
212212
}
213+
214+
void test_refs_branches_move__moves_reflog_correctly(void)
215+
{
216+
git_reference *original_ref, *new_ref;
217+
git_reflog *original_reflog, *new_reflog;
218+
219+
cl_git_pass(git_reference_lookup(&original_ref, repo, "refs/heads/br2"));
220+
221+
cl_git_pass(git_reflog_read(&original_reflog, repo, "refs/heads/br2"));
222+
cl_assert_equal_i(2, git_reflog_entrycount(original_reflog));
223+
224+
cl_git_pass(git_branch_move(&new_ref, original_ref, NEW_BRANCH_NAME, 0));
225+
cl_assert_equal_s(GIT_REFS_HEADS_DIR NEW_BRANCH_NAME, git_reference_name(new_ref));
226+
227+
cl_git_pass(git_reflog_read(&new_reflog, repo, GIT_REFS_HEADS_DIR NEW_BRANCH_NAME));
228+
cl_assert_equal_i(3, git_reflog_entrycount(new_reflog));
229+
230+
git_reference_free(original_ref);
231+
git_reference_free(new_ref);
232+
git_reflog_free(original_reflog);
233+
git_reflog_free(new_reflog);
234+
}

0 commit comments

Comments
 (0)