Commit Diff


commit - 5fb50fce7978aa218c87ec7ac6c3f4e7bf20e5b3
commit + 6a390967d72bf5e54eb669a0cef5ea548662bbbf
blob - 20e319355137e3ec594f1a28760412c19ab58905
blob + 0057e61e6db15e140ea00a36f04722389b25a0ba
--- lib/worktree.c
+++ lib/worktree.c
@@ -396,6 +396,13 @@ add_dir_on_disk(struct got_worktree *worktree, const c
 {
 	const struct got_error *err = NULL;
 	char *abspath;
+
+	/* We only accept worktree-relative paths here. */
+	if (got_path_is_absolute(path)) {
+		return got_error_fmt(GOT_ERR_BAD_PATH,
+		    "%s does not accept absolute paths: %s",
+		    __func__, path);
+	}
 
 	if (asprintf(&abspath, "%s/%s", worktree->root_path, path) == -1)
 		return got_error_from_errno("asprintf");
@@ -1350,7 +1357,7 @@ install_symlink(int *is_bad_symlink, struct got_worktr
 			err = got_path_dirname(&parent, ondisk_path);
 			if (err)
 				return err;
-			err = add_dir_on_disk(worktree, parent);
+			err = got_path_mkdir(parent);
 			free(parent);
 			if (err)
 				return err;
@@ -1360,6 +1367,12 @@ install_symlink(int *is_bad_symlink, struct got_worktr
 			 */
 			if (symlink(target_path, ondisk_path) != -1) {
 				err = NULL; /* success */
+				if (progress_cb) {
+					err = (*progress_cb)(progress_arg,
+					    reverting_versioned_file ?
+					    GOT_STATUS_REVERT : GOT_STATUS_ADD,
+					    path);
+				}
 				return err;
 			}
 		}
@@ -2292,6 +2305,9 @@ diff_new(void *arg, struct got_tree_entry *te, const c
 		return got_error(GOT_ERR_CANCELLED);
 
 	if (got_object_tree_entry_is_submodule(te))
+		return NULL;
+
+	if (!S_ISREG(te->mode) && !S_ISLNK(te->mode))
 		return NULL;
 
 	if (asprintf(&path, "%s%s%s", parent_path,
@@ -2299,11 +2315,8 @@ diff_new(void *arg, struct got_tree_entry *te, const c
 	    == -1)
 		return got_error_from_errno("asprintf");
 
-	if (S_ISDIR(te->mode))
-		err = add_dir_on_disk(a->worktree, path);
-	else
-		err = update_blob(a->worktree, a->fileindex, NULL, te, path,
-		    a->repo, a->progress_cb, a->progress_arg);
+	err = update_blob(a->worktree, a->fileindex, NULL, te, path,
+	    a->repo, a->progress_cb, a->progress_arg);
 
 	free(path);
 	return err;