Commit Diff


commit - 135819daf958ffae66a5c54ff1215b6130196cf3
commit + b249b824fbd8134a3152b48798682db67aa45c68
blob - c5fb394b57b4336f094177e1a3d4f59a67e0794f
blob + c3c1b5abc876c276781220cad85eb5f5081d47b4
--- include/got_error.h
+++ include/got_error.h
@@ -83,6 +83,7 @@
 #define GOT_ERR_FILE_MODIFIED	67
 #define GOT_ERR_FILE_STATUS	68
 #define GOT_ERR_COMMIT_CONFLICT	69
+#define GOT_ERR_BAD_REF_TYPE	70
 
 static const struct got_error {
 	int code;
@@ -157,6 +158,7 @@ static const struct got_error {
 	{ GOT_ERR_FILE_MODIFIED,"file contains modifications" },
 	{ GOT_ERR_FILE_STATUS,	"file has unexpected status" },
 	{ GOT_ERR_COMMIT_CONFLICT,"cannot commit file in conflicted status" },
+	{ GOT_ERR_BAD_REF_TYPE,	"bad reference type" },
 };
 
 /*
blob - cf87b34c6f7c83a5f08e9ad6eeb9048e658e0942
blob + 5c3eed9a3a8b0f5dbc490b7a2cfeccd2fd6f744e
--- include/got_reference.h
+++ include/got_reference.h
@@ -77,6 +77,18 @@ const struct got_error *got_ref_list(struct got_reflis
 /* Free all references on a ref list. */
 void got_ref_list_free(struct got_reflist_head *);
 
+/* Indicate whether the provided reference is symbolic (points at another
+ * refernce) or not (points at an object ID). */
+int got_ref_is_symbolic(struct got_reference *);
+
+/* Change the object ID a reference points to. */
+const struct got_error *
+got_ref_change_ref(struct got_reference *, struct got_object_id *);
+
+/* Change the reference name a symbolic reference points to. */
+const struct got_error *got_ref_change_symref(struct got_reference *,
+    char *);
+
 /* Write a reference to its on-disk path in the repository. */
 const struct got_error *got_ref_write(struct got_reference *,
     struct got_repository *);
blob - f01bb78825819e1a4ce68bfae120f461c9b8be00
blob + 168ef0c6453dfb820f829ead7011fc90b64c5c47
--- lib/reference.c
+++ lib/reference.c
@@ -762,10 +762,43 @@ got_ref_list_free(struct got_reflist_head *refs)
 		free(re->id);
 		free(re);
 	}
+
+}
+
+int
+got_ref_is_symbolic(struct got_reference *ref)
+{
+	return (ref->flags & GOT_REF_IS_SYMBOLIC);
+}
+
+const struct got_error *
+got_ref_change_ref(struct got_reference *ref, struct got_object_id *id)
+{
+	if (ref->flags & GOT_REF_IS_SYMBOLIC)
+		return got_error(GOT_ERR_BAD_REF_TYPE);
 
+	memcpy(ref->ref.ref.sha1, id->sha1, sizeof(ref->ref.ref.sha1));
+	return NULL;
 }
 
 const struct got_error *
+got_ref_change_symref(struct got_reference *ref, char *refname)
+{
+	char *new_name;
+
+	if ((ref->flags & GOT_REF_IS_SYMBOLIC) == 0)
+		return got_error(GOT_ERR_BAD_REF_TYPE);
+
+	new_name = strdup(refname);
+	if (new_name == NULL)
+		return got_error_from_errno();
+
+	free(ref->ref.symref.name);
+	ref->ref.symref.name = new_name;
+	return NULL;
+}
+
+const struct got_error *
 got_ref_write(struct got_reference *ref, struct got_repository *repo)
 {
 	const struct got_error *err = NULL, *unlock_err = NULL;