Merge branch 'ci/commit--interactive-atomic'

* ci/commit--interactive-atomic:
  Test atomic git-commit --interactive
  Add commit to list of config.singlekey commands
  Add support for -p/--patch to git-commit
  Allow git commit --interactive with paths
  t7501.8: feed a meaningful command
  Use a temporary index for git commit --interactive
This commit is contained in:
Junio C Hamano 2011-05-16 16:47:10 -07:00
commit 7a77754cf6
6 changed files with 75 additions and 31 deletions

View file

@ -1310,9 +1310,10 @@ interactive.singlekey::
In interactive commands, allow the user to provide one-letter
input with a single key (i.e., without hitting enter).
Currently this is used by the `\--patch` mode of
linkgit:git-add[1], linkgit:git-reset[1], linkgit:git-stash[1] and
linkgit:git-checkout[1]. Note that this setting is silently
ignored if portable keystroke input is not available.
linkgit:git-add[1], linkgit:git-checkout[1], linkgit:git-commit[1],
linkgit:git-reset[1], and linkgit:git-stash[1]. Note that this
setting is silently ignored if portable keystroke input
is not available.
log.date::
Set the default date-time mode for the 'log' command.

View file

@ -8,11 +8,12 @@ git-commit - Record changes to the repository
SYNOPSIS
--------
[verse]
'git commit' [-a | --interactive] [-s] [-v] [-u<mode>] [--amend] [--dry-run]
[(-c | -C | --fixup | --squash) <commit>] [-F <file> | -m <msg>]
[--reset-author] [--allow-empty] [--allow-empty-message] [--no-verify]
[-e] [--author=<author>] [--date=<date>] [--cleanup=<mode>]
[--status | --no-status] [-i | -o] [--] [<file>...]
'git commit' [-a | --interactive | --patch] [-s] [-v] [-u<mode>] [--amend]
[--dry-run] [(-c | -C | --fixup | --squash) <commit>]
[-F <file> | -m <msg>] [--reset-author] [--allow-empty]
[--allow-empty-message] [--no-verify] [-e] [--author=<author>]
[--date=<date>] [--cleanup=<mode>] [--status | --no-status]
[-i | -o] [--] [<file>...]
DESCRIPTION
-----------
@ -39,9 +40,10 @@ The content to be added can be specified in several ways:
that have been removed from the working tree, and then perform the
actual commit;
5. by using the --interactive switch with the 'commit' command to decide one
by one which files should be part of the commit, before finalizing the
operation. Currently, this is done by invoking 'git add --interactive'.
5. by using the --interactive or --patch switches with the 'commit' command
to decide one by one which files or hunks should be part of the commit,
before finalizing the operation. See the ``Interactive Mode`` section of
linkgit:git-add[1] to learn how to operate these modes.
The `--dry-run` option can be used to obtain a
summary of what is included by any of the above for the next
@ -59,6 +61,12 @@ OPTIONS
been modified and deleted, but new files you have not
told git about are not affected.
-p::
--patch::
Use the interactive patch selection interface to chose
which changes to commit. See linkgit:git-add[1] for
details.
-C <commit>::
--reuse-message=<commit>::
Take an existing commit object, and reuse the log message

View file

@ -242,7 +242,7 @@ int run_add_interactive(const char *revision, const char *patch_mode,
return status;
}
int interactive_add(int argc, const char **argv, const char *prefix)
int interactive_add(int argc, const char **argv, const char *prefix, int patch)
{
const char **pathspec = NULL;
@ -253,7 +253,7 @@ int interactive_add(int argc, const char **argv, const char *prefix)
}
return run_add_interactive(NULL,
patch_interactive ? "--patch" : NULL,
patch ? "--patch" : NULL,
pathspec);
}
@ -378,7 +378,7 @@ int cmd_add(int argc, const char **argv, const char *prefix)
if (patch_interactive)
add_interactive = 1;
if (add_interactive)
exit(interactive_add(argc - 1, argv + 1, prefix));
exit(interactive_add(argc - 1, argv + 1, prefix, patch_interactive));
if (edit_interactive)
return(edit_patch(argc, argv, prefix));

View file

@ -83,7 +83,7 @@ static const char *template_file;
static const char *author_message, *author_message_buffer;
static char *edit_message, *use_message;
static char *fixup_message, *squash_message;
static int all, edit_flag, also, interactive, only, amend, signoff;
static int all, edit_flag, also, interactive, patch_interactive, only, amend, signoff;
static int quiet, verbose, no_verify, allow_empty, dry_run, renew_authorship;
static int no_post_rewrite, allow_empty_message;
static char *untracked_files_arg, *force_date, *ignore_submodule_arg;
@ -152,6 +152,7 @@ static struct option builtin_commit_options[] = {
OPT_BOOLEAN('a', "all", &all, "commit all changed files"),
OPT_BOOLEAN('i', "include", &also, "add specified files to index for commit"),
OPT_BOOLEAN(0, "interactive", &interactive, "interactively add files"),
OPT_BOOLEAN('p', "patch", &patch_interactive, "interactively add changes"),
OPT_BOOLEAN('o', "only", &only, "commit only specified files"),
OPT_BOOLEAN('n', "no-verify", &no_verify, "bypass pre-commit hook"),
OPT_BOOLEAN(0, "dry-run", &dry_run, "show what would be committed"),
@ -336,18 +337,11 @@ static char *prepare_index(int argc, const char **argv, const char *prefix, int
int fd;
struct string_list partial;
const char **pathspec = NULL;
char *old_index_env = NULL;
int refresh_flags = REFRESH_QUIET;
if (is_status)
refresh_flags |= REFRESH_UNMERGED;
if (interactive) {
if (interactive_add(argc, argv, prefix) != 0)
die(_("interactive add failed"));
if (read_cache_preload(NULL) < 0)
die(_("index file corrupt"));
commit_style = COMMIT_AS_IS;
return get_index_file();
}
if (*argv)
pathspec = get_pathspec(prefix, argv);
@ -355,6 +349,33 @@ static char *prepare_index(int argc, const char **argv, const char *prefix, int
if (read_cache_preload(pathspec) < 0)
die(_("index file corrupt"));
if (interactive) {
fd = hold_locked_index(&index_lock, 1);
refresh_cache_or_die(refresh_flags);
if (write_cache(fd, active_cache, active_nr) ||
close_lock_file(&index_lock))
die(_("unable to create temporary index"));
old_index_env = getenv(INDEX_ENVIRONMENT);
setenv(INDEX_ENVIRONMENT, index_lock.filename, 1);
if (interactive_add(argc, argv, prefix, patch_interactive) != 0)
die(_("interactive add failed"));
if (old_index_env && *old_index_env)
setenv(INDEX_ENVIRONMENT, old_index_env, 1);
else
unsetenv(INDEX_ENVIRONMENT);
discard_cache();
read_cache_from(index_lock.filename);
commit_style = COMMIT_NORMAL;
return index_lock.filename;
}
/*
* Non partial, non as-is commit.
*
@ -1043,8 +1064,11 @@ static int parse_and_validate_options(int argc, const char *argv[],
author_message_buffer = read_commit_message(author_message);
}
if (patch_interactive)
interactive = 1;
if (!!also + !!only + !!all + !!interactive > 1)
die(_("Only one of --include/--only/--all/--interactive can be used."));
die(_("Only one of --include/--only/--all/--interactive/--patch can be used."));
if (argc == 0 && (also || (only && !amend)))
die(_("No paths with --include/--only does not make sense."));
if (argc == 0 && only && amend)
@ -1066,8 +1090,6 @@ static int parse_and_validate_options(int argc, const char *argv[],
if (all && argc > 0)
die(_("Paths with -a does not make sense."));
else if (interactive && argc > 0)
die(_("Paths with --interactive does not make sense."));
if (null_termination && status_format == STATUS_FORMAT_LONG)
status_format = STATUS_FORMAT_PORCELAIN;

View file

@ -161,7 +161,7 @@ extern struct commit_list *get_shallow_commits(struct object_array *heads,
int is_descendant_of(struct commit *, struct commit_list *);
int in_merge_bases(struct commit *, struct commit **, int);
extern int interactive_add(int argc, const char **argv, const char *prefix);
extern int interactive_add(int argc, const char **argv, const char *prefix, int patch);
extern int run_add_interactive(const char *revision, const char *patch_mode,
const char **pathspec);

View file

@ -42,10 +42,13 @@ test_expect_success \
"echo King of the bongo >file &&
test_must_fail git commit -m foo -a file"
test_expect_success PERL \
"using paths with --interactive" \
"echo bong-o-bong >file &&
! (echo 7 | git commit -m foo --interactive file)"
test_expect_success PERL 'can use paths with --interactive' '
echo bong-o-bong >file &&
# 2: update, 1:st path, that is all, 7: quit
( echo 2; echo 1; echo; echo 7 ) |
git commit -m foo --interactive file &&
git reset --hard HEAD^
'
test_expect_success \
"using invalid commit with -C" \
@ -131,6 +134,16 @@ test_expect_success PERL \
"interactive add" \
"echo 7 | git commit --interactive | grep 'What now'"
test_expect_success PERL \
"commit --interactive doesn't change index if editor aborts" \
"echo zoo >file &&
test_must_fail git diff --exit-code >diff1 &&
(echo u ; echo '*' ; echo q) |
(EDITOR=: && export EDITOR &&
test_must_fail git commit --interactive) &&
git diff >diff2 &&
test_cmp diff1 diff2"
test_expect_success \
"showing committed revisions" \
"git rev-list HEAD >current"