Commit Diff


commit - f7abcac262b10952aa804b9a77dde3c728250227
commit + 59530ea7aaf19f809c3dbcec5e2d9e039a54349f
blob - f75af45a4472408c7b5720b7e5a577d47ea961d0
blob + 5016750ce73d6b7a793df2a669389225f19ad9c0
--- lib/worktree.c
+++ lib/worktree.c
@@ -393,6 +393,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");
@@ -1347,7 +1354,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;
@@ -1357,6 +1364,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;
 			}
 		}
@@ -2289,6 +2302,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,
@@ -2296,11 +2312,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;