Skip to content

Commit 7a77754

Browse files
committed
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
2 parents 0184435 + 02a481f commit 7a77754

File tree

6 files changed

+75
-31
lines changed

6 files changed

+75
-31
lines changed

Documentation/config.txt

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1310,9 +1310,10 @@ interactive.singlekey::
13101310
In interactive commands, allow the user to provide one-letter
13111311
input with a single key (i.e., without hitting enter).
13121312
Currently this is used by the `\--patch` mode of
1313-
linkgit:git-add[1], linkgit:git-reset[1], linkgit:git-stash[1] and
1314-
linkgit:git-checkout[1]. Note that this setting is silently
1315-
ignored if portable keystroke input is not available.
1313+
linkgit:git-add[1], linkgit:git-checkout[1], linkgit:git-commit[1],
1314+
linkgit:git-reset[1], and linkgit:git-stash[1]. Note that this
1315+
setting is silently ignored if portable keystroke input
1316+
is not available.
13161317

13171318
log.date::
13181319
Set the default date-time mode for the 'log' command.

Documentation/git-commit.txt

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,12 @@ git-commit - Record changes to the repository
88
SYNOPSIS
99
--------
1010
[verse]
11-
'git commit' [-a | --interactive] [-s] [-v] [-u<mode>] [--amend] [--dry-run]
12-
[(-c | -C | --fixup | --squash) <commit>] [-F <file> | -m <msg>]
13-
[--reset-author] [--allow-empty] [--allow-empty-message] [--no-verify]
14-
[-e] [--author=<author>] [--date=<date>] [--cleanup=<mode>]
15-
[--status | --no-status] [-i | -o] [--] [<file>...]
11+
'git commit' [-a | --interactive | --patch] [-s] [-v] [-u<mode>] [--amend]
12+
[--dry-run] [(-c | -C | --fixup | --squash) <commit>]
13+
[-F <file> | -m <msg>] [--reset-author] [--allow-empty]
14+
[--allow-empty-message] [--no-verify] [-e] [--author=<author>]
15+
[--date=<date>] [--cleanup=<mode>] [--status | --no-status]
16+
[-i | -o] [--] [<file>...]
1617

1718
DESCRIPTION
1819
-----------
@@ -39,9 +40,10 @@ The content to be added can be specified in several ways:
3940
that have been removed from the working tree, and then perform the
4041
actual commit;
4142

42-
5. by using the --interactive switch with the 'commit' command to decide one
43-
by one which files should be part of the commit, before finalizing the
44-
operation. Currently, this is done by invoking 'git add --interactive'.
43+
5. by using the --interactive or --patch switches with the 'commit' command
44+
to decide one by one which files or hunks should be part of the commit,
45+
before finalizing the operation. See the ``Interactive Mode`` section of
46+
linkgit:git-add[1] to learn how to operate these modes.
4547

4648
The `--dry-run` option can be used to obtain a
4749
summary of what is included by any of the above for the next
@@ -59,6 +61,12 @@ OPTIONS
5961
been modified and deleted, but new files you have not
6062
told git about are not affected.
6163

64+
-p::
65+
--patch::
66+
Use the interactive patch selection interface to chose
67+
which changes to commit. See linkgit:git-add[1] for
68+
details.
69+
6270
-C <commit>::
6371
--reuse-message=<commit>::
6472
Take an existing commit object, and reuse the log message

builtin/add.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -242,7 +242,7 @@ int run_add_interactive(const char *revision, const char *patch_mode,
242242
return status;
243243
}
244244

245-
int interactive_add(int argc, const char **argv, const char *prefix)
245+
int interactive_add(int argc, const char **argv, const char *prefix, int patch)
246246
{
247247
const char **pathspec = NULL;
248248

@@ -253,7 +253,7 @@ int interactive_add(int argc, const char **argv, const char *prefix)
253253
}
254254

255255
return run_add_interactive(NULL,
256-
patch_interactive ? "--patch" : NULL,
256+
patch ? "--patch" : NULL,
257257
pathspec);
258258
}
259259

@@ -378,7 +378,7 @@ int cmd_add(int argc, const char **argv, const char *prefix)
378378
if (patch_interactive)
379379
add_interactive = 1;
380380
if (add_interactive)
381-
exit(interactive_add(argc - 1, argv + 1, prefix));
381+
exit(interactive_add(argc - 1, argv + 1, prefix, patch_interactive));
382382

383383
if (edit_interactive)
384384
return(edit_patch(argc, argv, prefix));

builtin/commit.c

Lines changed: 34 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ static const char *template_file;
8383
static const char *author_message, *author_message_buffer;
8484
static char *edit_message, *use_message;
8585
static char *fixup_message, *squash_message;
86-
static int all, edit_flag, also, interactive, only, amend, signoff;
86+
static int all, edit_flag, also, interactive, patch_interactive, only, amend, signoff;
8787
static int quiet, verbose, no_verify, allow_empty, dry_run, renew_authorship;
8888
static int no_post_rewrite, allow_empty_message;
8989
static char *untracked_files_arg, *force_date, *ignore_submodule_arg;
@@ -152,6 +152,7 @@ static struct option builtin_commit_options[] = {
152152
OPT_BOOLEAN('a', "all", &all, "commit all changed files"),
153153
OPT_BOOLEAN('i', "include", &also, "add specified files to index for commit"),
154154
OPT_BOOLEAN(0, "interactive", &interactive, "interactively add files"),
155+
OPT_BOOLEAN('p', "patch", &patch_interactive, "interactively add changes"),
155156
OPT_BOOLEAN('o', "only", &only, "commit only specified files"),
156157
OPT_BOOLEAN('n', "no-verify", &no_verify, "bypass pre-commit hook"),
157158
OPT_BOOLEAN(0, "dry-run", &dry_run, "show what would be committed"),
@@ -336,25 +337,45 @@ static char *prepare_index(int argc, const char **argv, const char *prefix, int
336337
int fd;
337338
struct string_list partial;
338339
const char **pathspec = NULL;
340+
char *old_index_env = NULL;
339341
int refresh_flags = REFRESH_QUIET;
340342

341343
if (is_status)
342344
refresh_flags |= REFRESH_UNMERGED;
343-
if (interactive) {
344-
if (interactive_add(argc, argv, prefix) != 0)
345-
die(_("interactive add failed"));
346-
if (read_cache_preload(NULL) < 0)
347-
die(_("index file corrupt"));
348-
commit_style = COMMIT_AS_IS;
349-
return get_index_file();
350-
}
351345

352346
if (*argv)
353347
pathspec = get_pathspec(prefix, argv);
354348

355349
if (read_cache_preload(pathspec) < 0)
356350
die(_("index file corrupt"));
357351

352+
if (interactive) {
353+
fd = hold_locked_index(&index_lock, 1);
354+
355+
refresh_cache_or_die(refresh_flags);
356+
357+
if (write_cache(fd, active_cache, active_nr) ||
358+
close_lock_file(&index_lock))
359+
die(_("unable to create temporary index"));
360+
361+
old_index_env = getenv(INDEX_ENVIRONMENT);
362+
setenv(INDEX_ENVIRONMENT, index_lock.filename, 1);
363+
364+
if (interactive_add(argc, argv, prefix, patch_interactive) != 0)
365+
die(_("interactive add failed"));
366+
367+
if (old_index_env && *old_index_env)
368+
setenv(INDEX_ENVIRONMENT, old_index_env, 1);
369+
else
370+
unsetenv(INDEX_ENVIRONMENT);
371+
372+
discard_cache();
373+
read_cache_from(index_lock.filename);
374+
375+
commit_style = COMMIT_NORMAL;
376+
return index_lock.filename;
377+
}
378+
358379
/*
359380
* Non partial, non as-is commit.
360381
*
@@ -1043,8 +1064,11 @@ static int parse_and_validate_options(int argc, const char *argv[],
10431064
author_message_buffer = read_commit_message(author_message);
10441065
}
10451066

1067+
if (patch_interactive)
1068+
interactive = 1;
1069+
10461070
if (!!also + !!only + !!all + !!interactive > 1)
1047-
die(_("Only one of --include/--only/--all/--interactive can be used."));
1071+
die(_("Only one of --include/--only/--all/--interactive/--patch can be used."));
10481072
if (argc == 0 && (also || (only && !amend)))
10491073
die(_("No paths with --include/--only does not make sense."));
10501074
if (argc == 0 && only && amend)
@@ -1066,8 +1090,6 @@ static int parse_and_validate_options(int argc, const char *argv[],
10661090

10671091
if (all && argc > 0)
10681092
die(_("Paths with -a does not make sense."));
1069-
else if (interactive && argc > 0)
1070-
die(_("Paths with --interactive does not make sense."));
10711093

10721094
if (null_termination && status_format == STATUS_FORMAT_LONG)
10731095
status_format = STATUS_FORMAT_PORCELAIN;

commit.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,7 @@ extern struct commit_list *get_shallow_commits(struct object_array *heads,
161161
int is_descendant_of(struct commit *, struct commit_list *);
162162
int in_merge_bases(struct commit *, struct commit **, int);
163163

164-
extern int interactive_add(int argc, const char **argv, const char *prefix);
164+
extern int interactive_add(int argc, const char **argv, const char *prefix, int patch);
165165
extern int run_add_interactive(const char *revision, const char *patch_mode,
166166
const char **pathspec);
167167

t/t7501-commit.sh

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -42,10 +42,13 @@ test_expect_success \
4242
"echo King of the bongo >file &&
4343
test_must_fail git commit -m foo -a file"
4444

45-
test_expect_success PERL \
46-
"using paths with --interactive" \
47-
"echo bong-o-bong >file &&
48-
! (echo 7 | git commit -m foo --interactive file)"
45+
test_expect_success PERL 'can use paths with --interactive' '
46+
echo bong-o-bong >file &&
47+
# 2: update, 1:st path, that is all, 7: quit
48+
( echo 2; echo 1; echo; echo 7 ) |
49+
git commit -m foo --interactive file &&
50+
git reset --hard HEAD^
51+
'
4952

5053
test_expect_success \
5154
"using invalid commit with -C" \
@@ -131,6 +134,16 @@ test_expect_success PERL \
131134
"interactive add" \
132135
"echo 7 | git commit --interactive | grep 'What now'"
133136

137+
test_expect_success PERL \
138+
"commit --interactive doesn't change index if editor aborts" \
139+
"echo zoo >file &&
140+
test_must_fail git diff --exit-code >diff1 &&
141+
(echo u ; echo '*' ; echo q) |
142+
(EDITOR=: && export EDITOR &&
143+
test_must_fail git commit --interactive) &&
144+
git diff >diff2 &&
145+
test_cmp diff1 diff2"
146+
134147
test_expect_success \
135148
"showing committed revisions" \
136149
"git rev-list HEAD >current"

0 commit comments

Comments
 (0)