diff options
| author | Junio C Hamano <gitster@pobox.com> | 2011-05-16 16:47:10 -0700 | 
|---|---|---|
| committer | Junio C Hamano <gitster@pobox.com> | 2011-05-16 16:47:10 -0700 | 
| commit | 7a77754cf6fde7b513da1283fe76179ffa930ecc (patch) | |
| tree | 3923485c3d4f775b41c1907dca4cd9bbc4ab3c52 | |
| parent | 018443526875456d335fef2dfbc78bc4de2d340d (diff) | |
| parent | 02a481fc6aef5d8a52f900448657d1cbe7c963ef (diff) | |
| download | git-7a77754cf6fde7b513da1283fe76179ffa930ecc.tar.gz | |
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
| -rw-r--r-- | Documentation/config.txt | 7 | ||||
| -rw-r--r-- | Documentation/git-commit.txt | 24 | ||||
| -rw-r--r-- | builtin/add.c | 6 | ||||
| -rw-r--r-- | builtin/commit.c | 46 | ||||
| -rw-r--r-- | commit.h | 2 | ||||
| -rwxr-xr-x | t/t7501-commit.sh | 21 | 
6 files changed, 75 insertions, 31 deletions
diff --git a/Documentation/config.txt b/Documentation/config.txt index 285c7f73ca..1a060ecbc8 100644 --- a/Documentation/config.txt +++ b/Documentation/config.txt @@ -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. diff --git a/Documentation/git-commit.txt b/Documentation/git-commit.txt index d0534b8c05..7951cb7b00 100644 --- a/Documentation/git-commit.txt +++ b/Documentation/git-commit.txt @@ -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 diff --git a/builtin/add.c b/builtin/add.c index e57abddf52..c59b0c98fe 100644 --- a/builtin/add.c +++ b/builtin/add.c @@ -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)); diff --git a/builtin/commit.c b/builtin/commit.c index 411d5e4153..5286432f39 100644 --- a/builtin/commit.c +++ b/builtin/commit.c @@ -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; @@ -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); diff --git a/t/t7501-commit.sh b/t/t7501-commit.sh index 7f7f7c7b95..3ad04363b5 100755 --- a/t/t7501-commit.sh +++ b/t/t7501-commit.sh @@ -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"  | 
