Commit Diff


commit - 1451e70d409660e581616fe32e56a7ad79b8b5a2
commit + 99724ed4012d446155eafdc18fc1337449bd8bcc
blob - b1ad87e60e9a8962edb1a6865d0ee3b134135872
blob + 62920bb290d79adcb26c0a80eff7f7db0a4d8a1c
--- lib/worktree.c
+++ lib/worktree.c
@@ -31,6 +31,51 @@
 #include "got_worktree_priv.h"
 #include "got_path_priv.h"
 
+static const struct got_error *
+create_meta_file(const char *gotpath, const char *name, const char *content)
+{
+	const struct got_error *err = NULL;
+	char *path;
+	int fd = -1;
+	char buf[4];
+	ssize_t n;
+
+	if (asprintf(&path, "%s/%s", gotpath, name) == -1) {
+		err = got_error(GOT_ERR_NO_MEM);
+		path = NULL;
+		goto done;
+	}
+
+	fd = open(path, O_RDWR | O_CREAT | O_EXCL | O_EXLOCK | O_NOFOLLOW,
+	    GOT_DEFAULT_FILE_MODE);
+	if (fd == -1) {
+		err = got_error_from_errno();
+		goto done;
+	}
+
+	/* The file should be empty. */
+	n = read(fd, buf, sizeof(buf));
+	if (n != 0) {
+		err = (n == -1 ? got_error_from_errno() :
+		    got_error(GOT_ERR_WORKTREE_EXISTS));
+		goto done;
+	}
+
+	if (content) {
+		int len = dprintf(fd, "%s\n", content);
+		if (len != strlen(content) + 1) {
+			err = got_error_from_errno();
+			goto done;
+		}
+	}
+
+done:
+	if (fd != -1 && close(fd) == -1 && err == NULL)
+		err = got_error_from_errno();
+	free(path);
+	return err;
+}
+
 const struct got_error *
 got_worktree_init(const char *path, struct got_reference *head_ref,
     struct got_repository *repo)
@@ -39,16 +84,9 @@ got_worktree_init(const char *path, struct got_referen
 	char *abspath = NULL;
 	char *normpath = NULL;
 	char *gotpath = NULL;
-	char *indexpath = NULL;
-	char *headpath = NULL;
-	char *repopath = NULL;
-	char *formatpath = NULL;
 	char *refstr = NULL;
 	char *path_repos = NULL;
 	char *formatstr = NULL;
-	char buf[4];
-	ssize_t n;
-	int fd;
 
 	if (got_path_is_absolute(path)) {
 		abspath = strdup(path);
@@ -82,28 +120,9 @@ got_worktree_init(const char *path, struct got_referen
 	}
 
 	/* Create an empty file index. */
-	if (asprintf(&indexpath, "%s/%s", gotpath, GOT_WORKTREE_FILE_INDEX)
-	    == -1) {
-		err = got_error(GOT_ERR_NO_MEM);
+	err = create_meta_file(gotpath, GOT_WORKTREE_FILE_INDEX, NULL);
+	if (err)
 		goto done;
-	}
-	fd = open(indexpath, O_RDWR | O_CREAT | O_EXCL | O_EXLOCK | O_NOFOLLOW,
-	    GOT_DEFAULT_FILE_MODE);
-	if (fd == -1) {
-		err = got_error_from_errno();
-		goto done;
-	}
-	n = read(fd, buf, sizeof(buf));
-	if (n != 0) {
-		err = (n == -1 ? got_error_from_errno() :
-		    got_error(GOT_ERR_WORKTREE_EXISTS));
-		close(fd);
-		goto done;
-	}
-	if (close(fd) == -1) {
-		err = got_error_from_errno();
-		goto done;
-	}
 
 	/* Write the HEAD reference. */
 	refstr = got_ref_to_str(head_ref);
@@ -111,123 +130,33 @@ got_worktree_init(const char *path, struct got_referen
 		err = got_error(GOT_ERR_NO_MEM);
 		goto done;
 	}
-	if (asprintf(&headpath, "%s/%s", gotpath, GOT_REF_HEAD) == -1) {
-		err = got_error(GOT_ERR_NO_MEM);
+	err = create_meta_file(gotpath, GOT_REF_HEAD, refstr);
+	if (err)
 		goto done;
-	}
-	fd = open(headpath, O_RDWR | O_CREAT | O_EXCL | O_EXLOCK | O_NOFOLLOW,
-	    GOT_DEFAULT_FILE_MODE);
-	if (fd == -1) {
-		err = got_error_from_errno();
-		goto done;
-	}
-	n = read(fd, buf, sizeof(buf));
-	if (n != 0) {
-		err = (n == -1 ? got_error_from_errno() :
-		    got_error(GOT_ERR_WORKTREE_EXISTS));
-		close(fd);
-		goto done;
-	}
-	n = write(fd, refstr, strlen(refstr));
-	if (n != strlen(refstr)) {
-		err = got_error_from_errno();
-		close(fd);
-		goto done;
-	}
-	n = write(fd, "\n", 1);
-	if (n != 1) {
-		err = got_error_from_errno();
-		close(fd);
-		goto done;
-	}
-	if (close(fd) == -1) {
-		err = got_error_from_errno();
-		goto done;
-	}
 
 	/* Store path to repository. */
-	if (asprintf(&repopath, "%s/%s", gotpath, GOT_WORKTREE_REPOSITORY)
-	    == -1) {
-		err = got_error(GOT_ERR_NO_MEM);
-		goto done;
-	}
-	fd = open(repopath, O_RDWR | O_CREAT | O_EXCL | O_EXLOCK | O_NOFOLLOW,
-	    GOT_DEFAULT_FILE_MODE);
-	if (fd == -1) {
-		err = got_error_from_errno();
-		goto done;
-	}
-	n = read(fd, buf, sizeof(buf));
-	if (n != 0) {
-		err = (n == -1 ? got_error_from_errno() :
-		    got_error(GOT_ERR_WORKTREE_EXISTS));
-		close(fd);
-		goto done;
-	}
 	path_repos = got_repo_get_path(repo);
 	if (path_repos == NULL) {
 		err = got_error(GOT_ERR_NO_MEM);
 		goto done;
 	}
-	n = write(fd, path_repos, strlen(path_repos));
-	if (n != strlen(path_repos)) {
-		err = got_error_from_errno();
-		close(fd);
+	err = create_meta_file(gotpath, GOT_WORKTREE_REPOSITORY, path_repos);
+	if (err)
 		goto done;
-	}
-	n = write(fd, "\n", 1);
-	if (n != 1) {
-		err = got_error_from_errno();
-		close(fd);
-		goto done;
-	}
-	if (close(fd) == -1) {
-		err = got_error_from_errno();
-		goto done;
-	}
 
 	/* Stamp repository with format file. */
-	if (asprintf(&formatpath, "%s/%s", gotpath, GOT_WORKTREE_FORMAT)
-	    == -1) {
-		err = got_error(GOT_ERR_NO_MEM);
-		goto done;
-	}
 	if (asprintf(&formatstr, "%d", GOT_WORKTREE_FORMAT_VERSION) == -1) {
 		err = got_error(GOT_ERR_NO_MEM);
 		goto done;
 	}
-	fd = open(formatpath, O_RDWR | O_CREAT | O_EXCL | O_EXLOCK | O_NOFOLLOW,
-	    GOT_DEFAULT_FILE_MODE);
-	if (fd == -1) {
-		err = got_error_from_errno();
+	err = create_meta_file(gotpath, GOT_WORKTREE_FORMAT, formatstr);
+	if (err)
 		goto done;
-	}
-	n = read(fd, buf, sizeof(buf));
-	if (n != 0) {
-		err = (n == -1 ? got_error_from_errno() :
-		    got_error(GOT_ERR_WORKTREE_EXISTS));
-		close(fd);
-		goto done;
-	}
-	n = dprintf(fd, "%s\n", formatstr);
-	if (n != strlen(formatstr) + 1) {
-		err = got_error_from_errno();
-		close(fd);
-		goto done;
-	}
-	if (close(fd) == -1) {
-		err = got_error_from_errno();
-		goto done;
-	}
 
 done:
 	free(abspath);
 	free(normpath);
 	free(gotpath);
-	free(indexpath);
-	free(headpath);
-	free(repopath);
-	free(formatpath);
 	free(formatstr);
 	free(refstr);
 	free(path_repos);