Commit Diff


commit - f02eaa22e5963774a1ad9810e415ab201552ec8c
commit + 9e672c7443bebadbd8806c9a4366543f852eb372
blob - ee6fe6460a2a0de9ae5395eb0de8571d8aa8a135
blob + a0d4587d54e186ee756ec2c4e91ce23ca709d5c4
--- got/Makefile
+++ got/Makefile
@@ -5,7 +5,7 @@ SRCS=		got.c blame.c commit_graph.c delta.c diff.c dif
 		diffreg.c error.c fileindex.c object.c object_cache.c \
 		object_idset.c object_parse.c opentemp.c path.c pack.c \
 		privsep.c reference.c repository.c sha1.c worktree.c \
-		inflate.c buf.c worklist.c rcsutil.c diff3.c
+		inflate.c buf.c worklist.c rcsutil.c diff3.c lockfile.c
 
 CPPFLAGS = -I${.CURDIR}/../include -I${.CURDIR}/../lib \
 	-DGOT_LIBEXECDIR=${GOT_LIBEXECDIR}
blob - dfb265d33164e060c796c1de3b3ad9f85bb27bb7
blob + 6f15ea20735cffc58ec67eb8b358eecaab8360d5
--- include/got_reference.h
+++ include/got_reference.h
@@ -73,3 +73,7 @@ SIMPLEQ_HEAD(got_reflist_head, got_reflist_entry);
 /* Append all known references to a caller-provided ref list head. */
 const struct got_error *got_ref_list(struct got_reflist_head *,
     struct got_repository *);
+
+/* 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 - 9e9655183bf6af53d89c2fcea53352d7d2a47b3e
blob + 18fca1ae9be06a6b5840128d6f6bc4454d04ab49
--- lib/reference.c
+++ lib/reference.c
@@ -16,6 +16,7 @@
 
 #include <sys/types.h>
 #include <sys/queue.h>
+#include <sys/stat.h>
 
 #include <ctype.h>
 #include <dirent.h>
@@ -31,6 +32,7 @@
 #include "got_object.h"
 #include "got_repository.h"
 #include "got_reference.h"
+#include "got_opentemp.h"
 
 #include "got_lib_sha1.h"
 #include "got_lib_path.h"
@@ -696,3 +698,90 @@ done:
 		err = got_error_from_errno();
 	return err;
 }
+
+const struct got_error *
+got_ref_write(struct got_reference *ref, struct got_repository *repo)
+{
+	const struct got_error *err = NULL, *unlock_err = NULL;
+	const char *name = got_ref_get_name(ref);
+	char *path_refs = NULL, *path = NULL, *tmppath = NULL;
+	struct got_lockfile *lf = NULL;
+	FILE *f = NULL;
+	size_t n;
+	struct stat sb;
+
+	path_refs = get_refs_dir_path(repo, name);
+	if (path_refs == NULL) {
+		err = got_error_from_errno();
+		goto done;
+	}
+
+	if (asprintf(&path, "%s/%s", path_refs, name) == -1) {
+		err = got_error_from_errno();
+		goto done;
+	}
+
+	err = got_opentemp_named(&tmppath, &f, path);
+	if (f == NULL) {
+		err = got_error_from_errno();
+		goto done;
+	}
+
+	if (ref->flags & GOT_REF_IS_SYMBOLIC) {
+		n = fprintf(f, "ref: %s\n", ref->ref.symref.ref);
+		if (n != strlen(ref->ref.symref.ref) + 6) {
+			err = got_ferror(f, GOT_ERR_IO);
+			goto done;
+		}
+	} else {
+		char hex[SHA1_DIGEST_STRING_LENGTH];
+		if (got_sha1_digest_to_str(ref->ref.ref.sha1, hex,
+		    sizeof(hex)) == NULL) {
+			err = got_error(GOT_ERR_BAD_REF_DATA);
+			goto done;
+		}
+		n = fprintf(f, "%s\n", hex);
+		if (n != sizeof(hex) + 1) {
+			err = got_ferror(f, GOT_ERR_IO);
+			goto done;
+		}
+	}
+
+	err = got_lockfile_lock(&lf, path);
+	if (err)
+		goto done;
+
+	/* XXX: check if old content matches our expectations? */
+
+	if (stat(path, &sb) != 0) {
+		err = got_error_from_errno();
+		goto done;
+	}
+
+	if (rename(tmppath, path) != 0) {
+		err = got_error_from_errno();
+		goto done;
+	}
+	free(tmppath);
+	tmppath = NULL;
+
+	if (chmod(path, sb.st_mode) != 0) {
+		err = got_error_from_errno();
+		goto done;
+	}
+done:
+	if (lf)
+		unlock_err = got_lockfile_unlock(lf);
+	if (f) {
+		if (fclose(f) != 0 && err == NULL)
+			err = got_error_from_errno();
+	}
+	free(path_refs);
+	free(path);
+	if (tmppath) {
+		if (unlink(tmppath) != 0 && err == NULL)
+			err = got_error_from_errno();
+		free(tmppath);
+	}
+	return err ? err : unlock_err;
+}
blob - 8fb53dfe4ebce9973fd7098c98914117b3baf3bf
blob + f9ca31289f75c7ae7b0173ad9c02ced0b74ee558
--- regress/idset/Makefile
+++ regress/idset/Makefile
@@ -4,7 +4,7 @@ PROG = idset_test
 SRCS = error.c object.c privsep.c sha1.c pack.c inflate.c path.c opentemp.c \
 	delta.c repository.c reference.c worktree.c fileindex.c object_cache.c \
 	object_idset.c object_parse.c idset_test.c \
-	buf.c worklist.c rcsutil.c diff.c diffreg.c diff3.c
+	buf.c worklist.c rcsutil.c diff.c diffreg.c diff3.c lockfile.c
 
 CPPFLAGS = -I${.CURDIR}/../../include -I${.CURDIR}/../../lib
 LDADD = -lutil -lz
blob - d75f821ba3e7ed1050713ad1cc994f972eda1ee1
blob + 77226c0a9e382144bb29cf3d1b4c85432d485d37
--- regress/repository/Makefile
+++ regress/repository/Makefile
@@ -4,7 +4,7 @@ PROG = repository_test
 SRCS = path.c repository.c error.c reference.c object.c object_cache.c \
 	object_idset.c object_parse.c opentemp.c sha1.c diff.c diffreg.c \
 	pack.c privsep.c delta.c fileindex.c worktree.c inflate.c \
-	buf.c worklist.c rcsutil.c diff3.c \
+	buf.c worklist.c rcsutil.c diff3.c lockfile.c \
 	repository_test.c
 
 CPPFLAGS = -I${.CURDIR}/../../include -I${.CURDIR}/../../lib \
blob - 21476afed2b0930f65f44d151ae98a2ba3c55081
blob + 1f297d962fc7317a131f0a9fe1c790fc0512c7b7
--- regress/worktree/Makefile
+++ regress/worktree/Makefile
@@ -4,7 +4,7 @@ PROG = worktree_test
 SRCS = worktree.c repository.c object.c object_cache.c object_idset.c \
 	object_parse.c opentemp.c path.c error.c reference.c sha1.c pack.c \
 	privsep.c delta.c inflate.c fileindex.c \
-	buf.c worklist.c rcsutil.c diff.c diffreg.c diff3.c \
+	buf.c worklist.c rcsutil.c diff.c diffreg.c diff3.c lockfile.c \
 	worktree_test.c
 
 CPPFLAGS = -I${.CURDIR}/../../include -I${.CURDIR}/../../lib \
blob - 87516af1da37593f11b27b5440b5d09a61937e7e
blob + 144d8da5ec3fc100ce967fcaf1c1aca1d07660e7
--- tog/Makefile
+++ tog/Makefile
@@ -5,7 +5,8 @@ SRCS=		tog.c blame.c commit_graph.c delta.c diff.c dif
 		diffreg.c error.c fileindex.c object.c object_cache.c \
 		object_idset.c object_parse.c opentemp.c path.c pack.c \
 		privsep.c reference.c repository.c sha1.c worktree.c \
-		utf8.c inflate.c buf.c worklist.c rcsutil.c diff3.c
+		utf8.c inflate.c buf.c worklist.c rcsutil.c diff3.c \
+		lockfile.c
 
 CPPFLAGS = -I${.CURDIR}/../include -I${.CURDIR}/../lib \
 	-DGOT_LIBEXECDIR=${GOT_LIBEXECDIR}