+
Skip to content

cherry-pick: refuse cherry-pick sequence if index is dirty #1535

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 31 additions & 22 deletions sequencer.c
Original file line number Diff line number Diff line change
Expand Up @@ -3162,38 +3162,48 @@ static int walk_revs_populate_todo(struct todo_list *todo_list,
return 0;
}

static int create_seq_dir(struct repository *r)
static const char *cherry_pick_action_name(enum replay_action action) {
switch (action) {
case REPLAY_REVERT:
return "revert";
break;
case REPLAY_PICK:
return "cherry-pick";
break;
default:
BUG("unexpected action in cherry_pick_action_name");
}
}

static int create_seq_dir(struct repository *r, enum replay_action requested_action)
{
enum replay_action action;
enum replay_action in_progress_action;
const char *in_progress_action_name = NULL;
const char *in_progress_error = NULL;
const char *in_progress_advice = NULL;
const char *requested_action_name = NULL;
unsigned int advise_skip =
refs_ref_exists(get_main_ref_store(r), "REVERT_HEAD") ||
refs_ref_exists(get_main_ref_store(r), "CHERRY_PICK_HEAD");

if (!sequencer_get_last_command(r, &action)) {
switch (action) {
case REPLAY_REVERT:
in_progress_error = _("revert is already in progress");
in_progress_advice =
_("try \"git revert (--continue | %s--abort | --quit)\"");
break;
case REPLAY_PICK:
in_progress_error = _("cherry-pick is already in progress");
in_progress_advice =
_("try \"git cherry-pick (--continue | %s--abort | --quit)\"");
break;
default:
BUG("unexpected action in create_seq_dir");
}
if (!sequencer_get_last_command(r, &in_progress_action)) {
in_progress_action_name = cherry_pick_action_name(in_progress_action);
in_progress_error = _("%s is already in progress");
in_progress_advice =
_("try \"git %s (--continue | %s--abort | --quit)\"");
}
if (in_progress_error) {
error("%s", in_progress_error);
error(in_progress_error, in_progress_action_name);
if (advice_enabled(ADVICE_SEQUENCER_IN_USE))
advise(in_progress_advice,
in_progress_action_name,
advise_skip ? "--skip | " : "");
return -1;
}
requested_action_name = cherry_pick_action_name(requested_action);
if (require_clean_index(r, requested_action_name,
_("Please commit or stash them."), 1, 1))
return -1;
if (mkdir(git_path_seq_dir(), 0777) < 0)
return error_errno(_("could not create sequencer directory '%s'"),
git_path_seq_dir());
Expand Down Expand Up @@ -5223,12 +5233,11 @@ int sequencer_pick_revisions(struct repository *r,

/*
* Start a new cherry-pick/ revert sequence; but
* first, make sure that an existing one isn't in
* progress
* first, make sure that the index is clean and that
* an existing one isn't in progress.
*/

if (walk_revs_populate_todo(&todo_list, opts) ||
create_seq_dir(r) < 0)
create_seq_dir(r, opts->action) < 0)
return -1;
if (repo_get_oid(r, "HEAD", &oid) && (opts->action == REPLAY_REVERT))
return error(_("can't revert as initial commit"));
Expand Down
10 changes: 10 additions & 0 deletions t/t3510-cherry-pick-sequence.sh
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,16 @@ test_expect_success 'cherry-pick persists data on failure' '
test_path_is_file .git/sequencer/opts
'

test_expect_success 'cherry-pick sequence refuses to run on dirty index' '
pristine_detach initial &&
touch localindexchange &&
git add localindexchange &&
echo picking &&
test_must_fail git cherry-pick initial..picked &&
test_path_is_missing .git/sequencer &&
test_must_fail git cherry-pick --abort
'

test_expect_success 'cherry-pick mid-cherry-pick-sequence' '
pristine_detach initial &&
test_must_fail git cherry-pick base..anotherpick &&
Expand Down
61 changes: 48 additions & 13 deletions wt-status.c
Original file line number Diff line number Diff line change
Expand Up @@ -2616,15 +2616,12 @@ int has_uncommitted_changes(struct repository *r,
return result;
}

/**
* If the work tree has unstaged or uncommitted changes, dies with the
* appropriate message.
*/
int require_clean_work_tree(struct repository *r,
const char *action,
const char *hint,
int ignore_submodules,
int gently)
static int require_clean_index_or_work_tree(struct repository *r,
const char *action,
const char *hint,
int ignore_submodules,
int check_index_only,
int gently)
{
struct lock_file lock_file = LOCK_INIT;
int err = 0, fd;
Expand All @@ -2635,10 +2632,12 @@ int require_clean_work_tree(struct repository *r,
repo_update_index_if_able(r, &lock_file);
rollback_lock_file(&lock_file);

if (has_unstaged_changes(r, ignore_submodules)) {
/* TRANSLATORS: the action is e.g. "pull with rebase" */
error(_("cannot %s: You have unstaged changes."), _(action));
err = 1;
if (!check_index_only) {
if (has_unstaged_changes(r, ignore_submodules)) {
/* TRANSLATORS: the action is e.g. "pull with rebase" */
error(_("cannot %s: You have unstaged changes."), _(action));
err = 1;
}
}

if (has_uncommitted_changes(r, ignore_submodules)) {
Expand All @@ -2659,3 +2658,39 @@ int require_clean_work_tree(struct repository *r,

return err;
}

/**
* If the work tree has unstaged or uncommitted changes, dies with the
* appropriate message.
*/
int require_clean_work_tree(struct repository *r,
const char *action,
const char *hint,
int ignore_submodules,
int gently)
{
return require_clean_index_or_work_tree(r,
action,
hint,
ignore_submodules,
0,
gently);
}

/**
* If the work tree has uncommitted changes, dies with the appropriate
* message.
*/
int require_clean_index(struct repository *r,
const char *action,
const char *hint,
int ignore_submodules,
int gently)
{
return require_clean_index_or_work_tree(r,
action,
hint,
ignore_submodules,
1,
gently);
}
5 changes: 5 additions & 0 deletions wt-status.h
Original file line number Diff line number Diff line change
Expand Up @@ -181,5 +181,10 @@ int require_clean_work_tree(struct repository *repo,
const char *hint,
int ignore_submodules,
int gently);
int require_clean_index(struct repository *repo,
const char *action,
const char *hint,
int ignore_submodules,
int gently);

#endif /* STATUS_H */
点击 这是indexloc提供的php浏览器服务,不要输入任何密码和下载