commit 59530ea7aaf19f809c3dbcec5e2d9e039a54349f from: Stefan Sperling via: Thomas Adam date: Mon Jul 17 16:31:44 2023 UTC prevent useless EEXIST errors filling up the global custom error array While checking out files, do not attempt to create every directory that exists in the repository tree without paying consideration to their existence on disk. Instead, let functions which add files worry about creating any missing parent directories. This shakes out two other bugs in broken symlink installation code which ended up passing an absolute path to add_dir_on_disk() and forgot to report progress in an unreachable code path that is now getting used. Problem reported by + ok naddy@ 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;