reflog: Deploy EINVALIDSPEC usage
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83
diff --git a/include/git2/reflog.h b/include/git2/reflog.h
index 45dff21..418826d 100644
--- a/include/git2/reflog.h
+++ b/include/git2/reflog.h
@@ -63,9 +63,12 @@ GIT_EXTERN(int) git_reflog_append(git_reflog *reflog, const git_oid *id, const g
*
* The reflog to be renamed is expected to already exist
*
+ * The new name will be checked for validity.
+ * See `git_reference_create_symbolic()` for rules about valid names.
+ *
* @param ref the reference
* @param name the new name of the reference
- * @return 0 or an error code
+ * @return 0 on success, GIT_EINVALIDSPEC or an error code
*/
GIT_EXTERN(int) git_reflog_rename(git_reference *ref, const char *name);
diff --git a/src/reflog.c b/src/reflog.c
index ac481fb..df799b1 100644
--- a/src/reflog.c
+++ b/src/reflog.c
@@ -340,21 +340,29 @@ cleanup:
int git_reflog_rename(git_reference *ref, const char *new_name)
{
- int error = -1, fd;
+ int error, fd;
git_buf old_path = GIT_BUF_INIT;
git_buf new_path = GIT_BUF_INIT;
git_buf temp_path = GIT_BUF_INIT;
+ git_buf normalized = GIT_BUF_INIT;
assert(ref && new_name);
+ if ((error = git_reference__normalize_name(
+ &normalized, new_name, GIT_REF_FORMAT_ALLOW_ONELEVEL)) < 0)
+ goto cleanup;
+
+ error = -1;
+
if (git_buf_joinpath(&temp_path, git_reference_owner(ref)->path_repository, GIT_REFLOG_DIR) < 0)
return -1;
if (git_buf_joinpath(&old_path, git_buf_cstr(&temp_path), ref->name) < 0)
goto cleanup;
- if (git_buf_joinpath(&new_path, git_buf_cstr(&temp_path), new_name) < 0)
- goto cleanup;
+ if (git_buf_joinpath(&new_path,
+ git_buf_cstr(&temp_path), git_buf_cstr(&normalized)) < 0)
+ goto cleanup;
/*
* Move the reflog to a temporary place. This two-phase renaming is required
@@ -386,6 +394,7 @@ cleanup:
git_buf_free(&temp_path);
git_buf_free(&old_path);
git_buf_free(&new_path);
+ git_buf_free(&normalized);
return error;
}
diff --git a/tests-clar/refs/reflog/reflog.c b/tests-clar/refs/reflog/reflog.c
index 8743c8a..19ee535 100644
--- a/tests-clar/refs/reflog/reflog.c
+++ b/tests-clar/refs/reflog/reflog.c
@@ -170,3 +170,15 @@ void test_refs_reflog_reflog__cannot_write_a_moved_reflog(void)
git_buf_free(&moved_log_path);
git_buf_free(&master_log_path);
}
+
+void test_refs_reflog_reflog__renaming_with_an_invalid_name_returns_EINVALIDSPEC(void)
+{
+ git_reference *master;
+
+ cl_git_pass(git_reference_lookup(&master, g_repo, "refs/heads/master"));
+
+ cl_assert_equal_i(GIT_EINVALIDSPEC,
+ git_reflog_rename(master, "refs/heads/Inv@{id"));
+
+ git_reference_free(master);
+}