vendor/libgit2/src/checkout.c in rugged-1.1.1 vs vendor/libgit2/src/checkout.c in rugged-1.2.0

- old
+ new

@@ -24,11 +24,10 @@ #include "filter.h" #include "blob.h" #include "diff.h" #include "diff_generate.h" #include "pathspec.h" -#include "buf_text.h" #include "diff_xdiff.h" #include "path.h" #include "attr.h" #include "pool.h" #include "strmap.h" @@ -327,10 +326,13 @@ git_buf_truncate(&data->target_path, data->target_len); if (path && git_buf_puts(&data->target_path, path) < 0) return -1; + if (git_path_validate_workdir_buf(data->repo, &data->target_path) < 0) + return -1; + *out = &data->target_path; return 0; } @@ -1241,11 +1243,11 @@ void *payload) { checkout_data *data = payload; const char *name; - assert(ancestor || ours || theirs); + GIT_ASSERT_ARG(ancestor || ours || theirs); if (ancestor) name = git__strdup(ancestor->path); else if (ours) name = git__strdup(ours->path); @@ -1276,18 +1278,18 @@ git_diff_delta *delta) { unsigned int flags = GIT_PATH_REJECT_WORKDIR_DEFAULTS; if (action & CHECKOUT_ACTION__REMOVE) { - if (!git_path_isvalid(repo, delta->old_file.path, delta->old_file.mode, flags)) { + if (!git_path_validate(repo, delta->old_file.path, delta->old_file.mode, flags)) { git_error_set(GIT_ERROR_CHECKOUT, "cannot remove invalid path '%s'", delta->old_file.path); return -1; } } if (action & ~CHECKOUT_ACTION__REMOVE) { - if (!git_path_isvalid(repo, delta->new_file.path, delta->new_file.mode, flags)) { + if (!git_path_validate(repo, delta->new_file.path, delta->new_file.mode, flags)) { git_error_set(GIT_ERROR_CHECKOUT, "cannot checkout to invalid path '%s'", delta->new_file.path); return -1; } } @@ -1485,12 +1487,14 @@ } static int checkout_stream_close(git_writestream *s) { struct checkout_stream *stream = (struct checkout_stream *)s; - assert(stream && stream->open); + GIT_ASSERT_ARG(stream); + GIT_ASSERT_ARG(stream->open); + stream->open = 0; return p_close(stream->fd); } static void checkout_stream_free(git_writestream *s) @@ -1507,11 +1511,11 @@ mode_t entry_filemode) { int flags = data->opts.file_open_flags; mode_t file_mode = data->opts.file_mode ? data->opts.file_mode : entry_filemode; - git_filter_options filter_opts = GIT_FILTER_OPTIONS_INIT; + git_filter_session filter_session = GIT_FILTER_SESSION_INIT; struct checkout_stream writer; mode_t mode; git_filter_list *fl = NULL; int fd; int error = 0; @@ -1530,17 +1534,17 @@ if ((fd = p_open(path, flags, mode)) < 0) { git_error_set(GIT_ERROR_OS, "could not open '%s' for writing", path); return fd; } - filter_opts.attr_session = &data->attr_session; - filter_opts.temp_buf = &data->tmp; + filter_session.attr_session = &data->attr_session; + filter_session.temp_buf = &data->tmp; if (!data->opts.disable_filters && - (error = git_filter_list__load_ext( + (error = git_filter_list__load( &fl, data->repo, blob, hint_path, - GIT_FILTER_TO_WORKTREE, &filter_opts))) { + GIT_FILTER_TO_WORKTREE, &filter_session))) { p_close(fd); return error; } /* setup the writer */ @@ -1552,11 +1556,11 @@ writer.fd = fd; writer.open = 1; error = git_filter_list_stream_blob(fl, blob, &writer.base); - assert(writer.open == 0); + GIT_ASSERT(writer.open == 0); git_filter_list_free(fl); if (error < 0) return error; @@ -1974,11 +1978,11 @@ const char *hint_path = NULL, *suffix; git_buf *fullpath; struct stat st; int error; - assert (side == conflict->ours || side == conflict->theirs); + GIT_ASSERT(side == conflict->ours || side == conflict->theirs); if (checkout_target_fullpath(&fullpath, data, side->path) < 0) return -1; if ((conflict->name_collision || conflict->directoryfile) && @@ -2028,11 +2032,12 @@ git_merge_file_result *result) { const char *our_label_raw, *their_label_raw, *suffix; int error = 0; - if ((error = git_buf_joinpath(out, git_repository_workdir(data->repo), result->path)) < 0) + if ((error = git_buf_joinpath(out, data->opts.target_directory, result->path)) < 0 || + (error = git_path_validate_workdir_buf(data->repo, out)) < 0) return error; /* Most conflicts simply use the filename in the index */ if (!conflict->name_collision) return 0; @@ -2057,11 +2062,11 @@ in_data = GIT_BUF_INIT, out_data = GIT_BUF_INIT; git_merge_file_options opts = GIT_MERGE_FILE_OPTIONS_INIT; git_merge_file_result result = {0}; git_filebuf output = GIT_FILEBUF_INIT; git_filter_list *fl = NULL; - git_filter_options filter_opts = GIT_FILTER_OPTIONS_INIT; + git_filter_session filter_session = GIT_FILTER_SESSION_INIT; int error = 0; if (data->opts.checkout_strategy & GIT_CHECKOUT_CONFLICT_STYLE_DIFF3) opts.flags |= GIT_MERGE_FILE_STYLE_DIFF3; @@ -2107,17 +2112,17 @@ if (!data->opts.disable_filters) { in_data.ptr = (char *)result.ptr; in_data.size = result.len; - filter_opts.attr_session = &data->attr_session; - filter_opts.temp_buf = &data->tmp; + filter_session.attr_session = &data->attr_session; + filter_session.temp_buf = &data->tmp; - if ((error = git_filter_list__load_ext( + if ((error = git_filter_list__load( &fl, data->repo, NULL, git_buf_cstr(&path_workdir), - GIT_FILTER_TO_WORKTREE, &filter_opts)) < 0 || - (error = git_filter_list_apply_to_data(&out_data, fl, &in_data)) < 0) + GIT_FILTER_TO_WORKTREE, &filter_session)) < 0 || + (error = git_filter_list__convert_buf(&out_data, fl, &in_data)) < 0) goto done; } else { out_data.ptr = (char *)result.ptr; out_data.size = result.len; } @@ -2327,10 +2332,26 @@ data->mkdir_map = NULL; git_attr_session__free(&data->attr_session); } +static int validate_target_directory(checkout_data *data) +{ + int error; + + if ((error = git_path_validate_workdir(data->repo, data->opts.target_directory)) < 0) + return error; + + if (git_path_isdir(data->opts.target_directory)) + return 0; + + error = checkout_mkdir(data, data->opts.target_directory, NULL, + GIT_DIR_MODE, GIT_MKDIR_VERIFY_DIR); + + return error; +} + static int checkout_data_init( checkout_data *data, git_iterator *target, const git_checkout_options *proposed) { @@ -2359,14 +2380,11 @@ else memmove(&data->opts, proposed, sizeof(git_checkout_options)); if (!data->opts.target_directory) data->opts.target_directory = git_repository_workdir(repo); - else if (!git_path_isdir(data->opts.target_directory) && - (error = checkout_mkdir(data, - data->opts.target_directory, NULL, - GIT_DIR_MODE, GIT_MKDIR_VERIFY_DIR)) < 0) + else if ((error = validate_target_directory(data)) < 0) goto cleanup; if ((error = git_repository_index(&data->index, data->repo)) < 0) goto cleanup; @@ -2586,11 +2604,11 @@ &baseline, data.opts.baseline, &baseline_opts)) < 0) goto cleanup; } /* Should not have case insensitivity mismatch */ - assert(git_iterator_ignore_case(workdir) == git_iterator_ignore_case(baseline)); + GIT_ASSERT(git_iterator_ignore_case(workdir) == git_iterator_ignore_case(baseline)); /* Generate baseline-to-target diff which will include an entry for * every possible update that might need to be made. */ if ((error = git_diff__from_iterators( @@ -2602,10 +2620,13 @@ * then loop through conflicts. */ if ((error = checkout_get_actions(&actions, &counts, &data, workdir)) != 0) goto cleanup; + if (data.strategy & GIT_CHECKOUT_DRY_RUN) + goto cleanup; + data.total_steps = counts[CHECKOUT_ACTION__REMOVE] + counts[CHECKOUT_ACTION__REMOVE_CONFLICT] + counts[CHECKOUT_ACTION__UPDATE_BLOB] + counts[CHECKOUT_ACTION__UPDATE_SUBMODULE] + counts[CHECKOUT_ACTION__UPDATE_CONFLICT]; @@ -2637,11 +2658,11 @@ if (data.index != git_iterator_index(target) && (error = checkout_extensions_update_index(&data)) < 0) goto cleanup; - assert(data.completed_steps == data.total_steps); + GIT_ASSERT(data.completed_steps == data.total_steps); if (data.opts.perfdata_cb) data.opts.perfdata_cb(&data.perfdata, data.opts.perfdata_payload); cleanup: @@ -2765,10 +2786,11 @@ int git_checkout_head( git_repository *repo, const git_checkout_options *opts) { - assert(repo); + GIT_ASSERT_ARG(repo); + return git_checkout_tree(repo, NULL, opts); } int git_checkout_options_init(git_checkout_options *opts, unsigned int version) {