commit 1451e70d409660e581616fe32e56a7ad79b8b5a2 from: Stefan Sperling date: Sat Mar 10 15:51:30 2018 UTC stamp worktrees with a format number commit - 8eea5a5c6da95a1fd35a24016e33276c271d6b45 commit + 1451e70d409660e581616fe32e56a7ad79b8b5a2 blob - 97fb6c888a7d319c81a0c1bc3f9c8158bed69ada blob + f49af4462fbbafaf62103a6217682cd77b3f9449 --- lib/got_worktree_priv.h +++ lib/got_worktree_priv.h @@ -22,3 +22,6 @@ struct got_worktree { #define GOT_WORKTREE_GOT_DIR ".got" #define GOT_WORKTREE_FILE_INDEX "fileindex" #define GOT_WORKTREE_REPOSITORY "repository" +#define GOT_WORKTREE_FORMAT "format" + +#define GOT_WORKTREE_FORMAT_VERSION 1 blob - f6557150155aa8359bc005a868d34a0d67dd60c6 blob + b1ad87e60e9a8962edb1a6865d0ee3b134135872 --- lib/worktree.c +++ lib/worktree.c @@ -42,8 +42,10 @@ got_worktree_init(const char *path, struct got_referen 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; @@ -143,7 +145,7 @@ got_worktree_init(const char *path, struct got_referen goto done; } - /* Store path to repository. */ + /* Store path to repository. */ if (asprintf(&repopath, "%s/%s", gotpath, GOT_WORKTREE_REPOSITORY) == -1) { err = got_error(GOT_ERR_NO_MEM); @@ -184,6 +186,40 @@ got_worktree_init(const char *path, struct got_referen 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(); + 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); @@ -191,6 +227,8 @@ done: free(indexpath); free(headpath); free(repopath); + free(formatpath); + free(formatstr); free(refstr); free(path_repos); return err; blob - e9f6cee931bf97d124b46fc90b1c0035ad396d38 blob + cad1391f834a5c431a11516c16e8d13cb8a1be97 --- regress/worktree/worktree_test.c +++ regress/worktree/worktree_test.c @@ -83,6 +83,7 @@ remove_workdir(const char *worktree_path) remove_meta_file(worktree_path, GOT_REF_HEAD); remove_meta_file(worktree_path, GOT_WORKTREE_FILE_INDEX); remove_meta_file(worktree_path, GOT_WORKTREE_REPOSITORY); + remove_meta_file(worktree_path, GOT_WORKTREE_FORMAT); remove_got_dir(worktree_path); rmdir(worktree_path); } @@ -135,6 +136,8 @@ worktree_init(const char *repo_path) goto done; if (!check_meta_file_exists(worktree_path, GOT_WORKTREE_REPOSITORY)) goto done; + if (!check_meta_file_exists(worktree_path, GOT_WORKTREE_FORMAT)) + goto done; ok = 1; remove_workdir(worktree_path); done: @@ -224,15 +227,23 @@ worktree_init_exists(const char *repo_path) unlink(path); free(path); + if (!obstruct_meta_file(&path, worktree_path, GOT_WORKTREE_FORMAT)) + goto done; + err = got_worktree_init(worktree_path, head_ref, repo); + if (err != NULL && err->code == GOT_ERR_ERRNO && errno == EEXIST) + ok++; + unlink(path); + free(path); + done: if (head_ref) got_ref_close(head_ref); if (repo) got_repo_close(repo); free(gotpath); - if (ok == 3) + if (ok == 4) remove_workdir(worktree_path); - return (ok == 3); + return (ok == 4); } #define RUN_TEST(expr, name) \