Commit 80212ecb1c2ce3e27d1a4ffe053e36260ee06c01

nulltoken 2012-11-12T16:49:29

reflog: Deploy EINVALIDSPEC usage

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);
+}