commit 75f0a0fb346fb0ad381536024728164cd32d2a7e from: Stefan Sperling date: Thu Jul 23 14:22:39 2020 UTC stop reinstalling symlinks after commit; 'got update' can handle that commit - 35213c7c838a48142d398147b54bb9938af8cab0 commit + 75f0a0fb346fb0ad381536024728164cd32d2a7e blob - bf1f2beb4941056d469b27d8a85aa3aa02dd903a blob + 4975303c833082ccb5a3aac5e50291ffc8a32641 --- lib/worktree.c +++ lib/worktree.c @@ -5135,128 +5135,6 @@ write_tree(struct got_object_id **new_tree_id, int *ne err = got_object_tree_create(new_tree_id, &paths, *nentries, repo); done: got_pathlist_free(&paths); - return err; -} - -static const struct got_error * -reinstall_symlink_after_commit(int *is_bad_symlink, struct got_commitable *ct, - struct got_object_id *new_base_commit_id, struct got_worktree *worktree, - struct got_fileindex_entry *ie, struct got_repository *repo) -{ - const struct got_error *err = NULL; - struct got_blob_object *blob = NULL; - struct got_object_id *tree_id = NULL; - char *tree_path = NULL; - struct got_tree_object *tree = NULL; - struct got_tree_entry *te; - char *entry_name; - unsigned char status; - struct stat sb; - - err = get_file_status(&status, &sb, ie, ct->ondisk_path, - -1, NULL, repo); - if (err) - return err; - if (status != GOT_STATUS_NO_CHANGE) - return NULL; - - if (ct->staged_status == GOT_STATUS_ADD || - ct->staged_status == GOT_STATUS_MODIFY) { - err = got_object_open_as_blob(&blob, repo, ct->staged_blob_id, - PATH_MAX); - if (err) - return err; - } else { - err = got_object_open_as_blob(&blob, repo, ct->blob_id, - PATH_MAX); - if (err) - return err; - } - - err = got_path_dirname(&tree_path, ct->in_repo_path); - if (err) { - if (err->code != GOT_ERR_BAD_PATH) - goto done; - err = got_object_id_by_path(&tree_id, repo, - new_base_commit_id, ""); - if (err) - goto done; - } else { - err = got_object_id_by_path(&tree_id, repo, - new_base_commit_id, tree_path); - if (err) - goto done; - } - - err = got_object_open_as_tree(&tree, repo, tree_id); - if (err) - goto done; - - entry_name = basename(ct->path); - if (entry_name == NULL) { - err = got_error_from_errno2("basename", ct->path); - goto done; - } - - te = got_object_tree_find_entry(tree, entry_name); - if (te == NULL) { - err = got_error_path(ct->path, GOT_ERR_NO_TREE_ENTRY); - goto done; - } - - err = install_symlink(is_bad_symlink, worktree, ct->ondisk_path, - ct->path, blob, 0, 0, 0, repo, NULL, NULL); -done: - if (blob) - got_object_blob_close(blob); - if (tree) - got_object_tree_close(tree); - free(tree_id); - free(tree_path); - return err; -} - -/* - * After comitting a symlink we have a chance to convert "bad" symlinks - * (those which point outside the work tree or into .got) to regular files. - * This way, the post-commit work tree state matches a fresh checkout of - * the tree which was just committed. We also mark such newly committed - * symlinks as "bad" in the work tree's fileindex. - */ -static const struct got_error * -reinstall_symlinks_after_commit(struct got_pathlist_head *commitable_paths, - struct got_object_id *new_base_commit_id, struct got_fileindex *fileindex, - struct got_worktree *worktree, struct got_repository *repo) -{ - const struct got_error *err = NULL; - struct got_pathlist_entry *pe; - - TAILQ_FOREACH(pe, commitable_paths, entry) { - struct got_commitable *ct = pe->data; - struct got_fileindex_entry *ie; - int is_bad_symlink = 0; - - if (!S_ISLNK(get_ct_file_mode(ct)) || - ct->staged_status == GOT_STATUS_DELETE || - ct->status == GOT_STATUS_DELETE) - continue; - - ie = got_fileindex_entry_get(fileindex, ct->path, - strlen(ct->path)); - if (ie == NULL) { - err = got_error_path(ct->path, GOT_ERR_BAD_PATH); - break; - } - err = reinstall_symlink_after_commit(&is_bad_symlink, - ct, new_base_commit_id, worktree, ie, repo); - if (err) - break; - if (ie && is_bad_symlink) { - got_fileindex_entry_filetype_set(ie, - GOT_FILEIDX_MODE_BAD_SYMLINK); - } - } - return err; } @@ -5639,10 +5517,6 @@ got_worktree_commit(struct got_object_id **new_commit_ err = update_fileindex_after_commit(&commitable_paths, *new_commit_id, fileindex, have_staged_files); - if (err == NULL) { - err = reinstall_symlinks_after_commit(&commitable_paths, - *new_commit_id, fileindex, worktree, repo); - } sync_err = sync_fileindex(fileindex, fileindex_path); if (sync_err && err == NULL) err = sync_err; blob - 1f478a3523850ec49f239dc826069cc14c97b220 blob + b877e38e53b5003239de90bd1bd31223db2fd177 --- regress/cmdline/commit.sh +++ regress/cmdline/commit.sh @@ -1044,7 +1044,14 @@ function test_commit_symlink { return 1 fi - # verify post-commit work tree state matches a fresh checkout + if ! [ -h $testroot/wt/passwd.link ]; then + echo 'passwd.link is not a symlink' >&2 + test_done "$testroot" 1 + return 1 + fi + + # 'got update' should reinstall passwd.link as a regular file + (cd $testroot/wt && got update > /dev/null) check_symlinks $testroot/wt ret="$?" if [ "$ret" != "0" ]; then @@ -1142,6 +1149,12 @@ function test_commit_fix_bad_symlink { (cd $testroot/wt && got commit -S -m 'commit bad symlink' \ > $testroot/stdout) + if ! [ -h $testroot/wt/passwd.link ]; then + echo 'passwd.link is not a symlink' >&2 + test_done "$testroot" 1 + return 1 + fi + (cd $testroot/wt && got update >/dev/null) if [ -h $testroot/wt/passwd.link ]; then echo "passwd.link is a symlink but should be a regular file" >&2 test_done "$testroot" "1" blob - 90792acb612758516f6519ea08af7cfa75605260 blob + 21af58910aa46d20189bd009ad4c9a6bf02d4453 --- regress/cmdline/stage.sh +++ regress/cmdline/stage.sh @@ -2579,6 +2579,12 @@ EOF return 1 fi + if [ ! -h $testroot/wt/dotgotbar.link ]; then + echo "dotgotbar.link is not a symlink" + test_done "$testroot" "1" + return 1 + fi + (cd $testroot/wt && got update > /dev/null) if [ -h $testroot/wt/dotgotbar.link ]; then echo "dotgotbar.link is a symlink" test_done "$testroot" "1"