Merge branch 'ms/subtree-install-fix'

* ms/subtree-install-fix:
  contrib/subtree: Fix make install target
diff --git a/.mailmap b/.mailmap
index 57070b5..57551b0 100644
--- a/.mailmap
+++ b/.mailmap
@@ -26,6 +26,8 @@
 Cheng Renquan <crquan@gmail.com>
 Chris Shoemaker <c.shoemaker@cox.net>
 Chris Wright <chrisw@sous-sol.org> <chrisw@osdl.org>
+Cord Seele <cowose@gmail.com> <cowose@googlemail.com>
+Christian Stimming <stimming@tuhh.de> <chs@ckiste.goetheallee>
 Csaba Henk <csaba@gluster.com> <csaba@lowlife.hu>
 Dan Johnson <computerdruid@gmail.com>
 Dana L. How <danahow@gmail.com> <how@deathvalley.cswitch.com>
@@ -74,6 +76,7 @@
 Johannes Sixt <j6t@kdbg.org> <J.Sixt@eudaptics.com>
 Johannes Sixt <j6t@kdbg.org> <j.sixt@viscovery.net>
 Johannes Sixt <j6t@kdbg.org> <johannes.sixt@telecom.at>
+John 'Warthog9' Hawley <warthog9@kernel.org> <warthog9@eaglescrag.net>
 Jon Loeliger <jdl@jdl.com> <jdl@freescale.com>
 Jon Loeliger <jdl@jdl.com> <jdl@freescale.org>
 Jon Seymour <jon.seymour@gmail.com> <jon@blackcubes.dyndns.org>
@@ -181,6 +184,7 @@
 Stefan Naewe <stefan.naewe@gmail.com> <stefan.naewe@atlas-elektronik.com>
 Stefan Naewe <stefan.naewe@gmail.com> <stefan.naewe@googlemail.com>
 Stefan Sperling <stsp@elego.de> <stsp@stsp.name>
+Štěpán Němec <stepnem@gmail.com> <stepan.nemec@gmail.com>
 Stephen Boyd <bebarino@gmail.com> <sboyd@codeaurora.org>
 Steven Drake <sdrake@xnet.co.nz> <sdrake@ihug.co.nz>
 Steven Grimm <koreth@midwinter.com> <sgrimm@sgrimm-mbp.local>
diff --git a/Documentation/git-clean.txt b/Documentation/git-clean.txt
index 75fb543..8997922 100644
--- a/Documentation/git-clean.txt
+++ b/Documentation/git-clean.txt
@@ -111,7 +111,7 @@
    '>>' like this, you can make more than one selection, concatenated
    with whitespace or comma.  Also you can say ranges.  E.g. "2-5 7,9"
    to choose 2,3,4,5,7,9 from the list.  If the second number in a
-   range is omitted, all remaining patches are taken.  E.g. "7-" to
+   range is omitted, all remaining items are selected.  E.g. "7-" to
    choose 7,8,9 from the list.  You can say '*' to choose everything.
    Also when you are satisfied with the filtered result, press ENTER
    (empty) back to the main menu.
diff --git a/Documentation/git-config.txt b/Documentation/git-config.txt
index 34b0894..2dbe486 100644
--- a/Documentation/git-config.txt
+++ b/Documentation/git-config.txt
@@ -96,29 +96,31 @@
 	names are not.
 
 --global::
-	For writing options: write to global ~/.gitconfig file rather than
-	the repository .git/config, write to $XDG_CONFIG_HOME/git/config file
-	if this file exists and the ~/.gitconfig file doesn't.
+	For writing options: write to global `~/.gitconfig` file
+	rather than the repository `.git/config`, write to
+	`$XDG_CONFIG_HOME/git/config` file if this file exists and the
+	`~/.gitconfig` file doesn't.
 +
-For reading options: read only from global ~/.gitconfig and from
-$XDG_CONFIG_HOME/git/config rather than from all available files.
+For reading options: read only from global `~/.gitconfig` and from
+`$XDG_CONFIG_HOME/git/config` rather than from all available files.
 +
 See also <<FILES>>.
 
 --system::
-	For writing options: write to system-wide $(prefix)/etc/gitconfig
-	rather than the repository .git/config.
+	For writing options: write to system-wide
+	`$(prefix)/etc/gitconfig` rather than the repository
+	`.git/config`.
 +
-For reading options: read only from system-wide $(prefix)/etc/gitconfig
+For reading options: read only from system-wide `$(prefix)/etc/gitconfig`
 rather than from all available files.
 +
 See also <<FILES>>.
 
 --local::
-	For writing options: write to the repository .git/config file.
+	For writing options: write to the repository `.git/config` file.
 	This is	the default behavior.
 +
-For reading options: read only from the repository .git/config rather than
+For reading options: read only from the repository `.git/config` rather than
 from all available files.
 +
 See also <<FILES>>.
@@ -218,9 +220,9 @@
 
 $XDG_CONFIG_HOME/git/config::
 	Second user-specific configuration file. If $XDG_CONFIG_HOME is not set
-	or empty, $HOME/.config/git/config will be used. Any single-valued
+	or empty, `$HOME/.config/git/config` will be used. Any single-valued
 	variable set in this file will be overwritten by whatever is in
-	~/.gitconfig.  It is a good idea not to create this file if
+	`~/.gitconfig`.  It is a good idea not to create this file if
 	you sometimes use older versions of Git, as support for this
 	file was added fairly recently.
 
diff --git a/Documentation/git-tag.txt b/Documentation/git-tag.txt
index 22894cb..c418c44 100644
--- a/Documentation/git-tag.txt
+++ b/Documentation/git-tag.txt
@@ -42,6 +42,17 @@
 GnuPG key for signing. 	The configuration variable `gpg.program`
 is used to specify custom GnuPG binary.
 
+Tag objects (created with `-a`, `s`, or `-u`) are called "annotated"
+tags; they contain a creation date, the tagger name and e-mail, a
+tagging message, and an optional GnuPG signature. Whereas a
+"lightweight" tag is simply a name for an object (usually a commit
+object).
+
+Annotated tags are meant for release while lightweight tags are meant
+for private or temporary object labels. For this reason, some git
+commands for naming objects (like `git describe`) will ignore
+lightweight tags by default.
+
 
 OPTIONS
 -------
diff --git a/Documentation/technical/protocol-capabilities.txt b/Documentation/technical/protocol-capabilities.txt
index b15517f..fd8ffa5 100644
--- a/Documentation/technical/protocol-capabilities.txt
+++ b/Documentation/technical/protocol-capabilities.txt
@@ -18,11 +18,12 @@
 and server advertised.  As a consequence of these rules, server MUST
 NOT advertise capabilities it does not understand.
 
-The 'report-status' and 'delete-refs' capabilities are sent and
+The 'report-status', 'delete-refs', and 'quiet' capabilities are sent and
 recognized by the receive-pack (push to server) process.
 
-The 'ofs-delta' capability is sent and recognized by both upload-pack
-and receive-pack protocols.
+The 'ofs-delta' and 'side-band-64k' capabilities are sent and recognized
+by both upload-pack and receive-pack protocols.  The 'agent' capability
+may optionally be sent in both protocols.
 
 All other capabilities are only recognized by the upload-pack (fetch
 from server) process.
@@ -123,6 +124,20 @@
 its base by position in pack rather than by an obj-id.  That is, they can
 send/read OBJ_OFS_DELTA (aka type 6) in a packfile.
 
+agent
+-----
+
+The server may optionally send a capability of the form `agent=X` to
+notify the client that the server is running version `X`. The client may
+optionally return its own agent string by responding with an `agent=Y`
+capability (but it MUST NOT do so if the server did not mention the
+agent capability). The `X` and `Y` strings may contain any printable
+ASCII characters except space (i.e., the byte range 32 < x < 127), and
+are typically of the form "package/version" (e.g., "git/1.8.3.1"). The
+agent strings are purely informative for statistics and debugging
+purposes, and MUST NOT be used to programatically assume the presence
+or absence of particular features.
+
 shallow
 -------
 
@@ -168,7 +183,7 @@
 report-status
 -------------
 
-The upload-pack process can receive a 'report-status' capability,
+The receive-pack process can receive a 'report-status' capability,
 which tells it that the client wants a report of what happened after
 a packfile upload and reference update.  If the pushing client requests
 this capability, after unpacking and updating references the server
@@ -185,3 +200,20 @@
 value of a reference update.  It is not sent back by the client, it
 simply informs the client that it can be sent zero-id values
 to delete references.
+
+quiet
+-----
+
+If the receive-pack server advertises the 'quiet' capability, it is
+capable of silencing human-readable progress output which otherwise may
+be shown when processing the received pack. A send-pack client should
+respond with the 'quiet' capability to suppress server-side progress
+reporting if the local progress reporting is also being suppressed
+(e.g., via `push -q`, or if stderr does not go to a tty).
+
+allow-tip-sha1-in-want
+----------------------
+
+If the upload-pack server advertises this capability, fetch-pack may
+send "want" lines with SHA-1s that exist at the server but are not
+advertised by upload-pack.
diff --git a/advice.c b/advice.c
index 2a52098..3eca9f5 100644
--- a/advice.c
+++ b/advice.c
@@ -35,7 +35,7 @@
 	{ "implicitidentity", &advice_implicit_identity },
 	{ "detachedhead", &advice_detached_head },
 	{ "setupstreamfailure", &advice_set_upstream_failure },
-	{ "object_name_warning", &advice_object_name_warning },
+	{ "objectnamewarning", &advice_object_name_warning },
 	{ "rmhints", &advice_rm_hints },
 
 	/* make this an alias for backward compatibility */
diff --git a/builtin/clean.c b/builtin/clean.c
index dba8387..3c85e15 100644
--- a/builtin/clean.c
+++ b/builtin/clean.c
@@ -365,6 +365,56 @@
 	string_list_clear(&menu_list, 0);
 }
 
+static int find_unique(const char *choice, struct menu_stuff *menu_stuff)
+{
+	struct menu_item *menu_item;
+	struct string_list_item *string_list_item;
+	int i, len, found = 0;
+
+	len = strlen(choice);
+	switch (menu_stuff->type) {
+	default:
+		die("Bad type of menu_stuff when parse choice");
+	case MENU_STUFF_TYPE_MENU_ITEM:
+
+		menu_item = (struct menu_item *)menu_stuff->stuff;
+		for (i = 0; i < menu_stuff->nr; i++, menu_item++) {
+			if (len == 1 && *choice == menu_item->hotkey) {
+				found = i + 1;
+				break;
+			}
+			if (!strncasecmp(choice, menu_item->title, len)) {
+				if (found) {
+					if (len == 1) {
+						/* continue for hotkey matching */
+						found = -1;
+					} else {
+						found = 0;
+						break;
+					}
+				} else {
+					found = i + 1;
+				}
+			}
+		}
+		break;
+	case MENU_STUFF_TYPE_STRING_LIST:
+		string_list_item = ((struct string_list *)menu_stuff->stuff)->items;
+		for (i = 0; i < menu_stuff->nr; i++, string_list_item++) {
+			if (!strncasecmp(choice, string_list_item->string, len)) {
+				if (found) {
+					found = 0;
+					break;
+				}
+				found = i + 1;
+			}
+		}
+		break;
+	}
+	return found;
+}
+
+
 /*
  * Parse user input, and return choice(s) for menu (menu_stuff).
  *
@@ -392,8 +442,6 @@
 			int **chosen)
 {
 	struct strbuf **choice_list, **ptr;
-	struct menu_item *menu_item;
-	struct string_list_item *string_list_item;
 	int nr = 0;
 	int i;
 
@@ -457,32 +505,8 @@
 			bottom = 1;
 			top = menu_stuff->nr;
 		} else {
-			switch (menu_stuff->type) {
-			default:
-				die("Bad type of menu_stuff when parse choice");
-			case MENU_STUFF_TYPE_MENU_ITEM:
-				menu_item = (struct menu_item *)menu_stuff->stuff;
-				for (i = 0; i < menu_stuff->nr; i++, menu_item++) {
-					if (((*ptr)->len == 1 &&
-					     *(*ptr)->buf == menu_item->hotkey) ||
-					    !strcasecmp((*ptr)->buf, menu_item->title)) {
-						bottom = i + 1;
-						top = bottom;
-						break;
-					}
-				}
-				break;
-			case MENU_STUFF_TYPE_STRING_LIST:
-				string_list_item = ((struct string_list *)menu_stuff->stuff)->items;
-				for (i = 0; i < menu_stuff->nr; i++, string_list_item++) {
-					if (!strcasecmp((*ptr)->buf, string_list_item->string)) {
-						bottom = i + 1;
-						top = bottom;
-						break;
-					}
-				}
-				break;
-			}
+			bottom = find_unique((*ptr)->buf, menu_stuff);
+			top = bottom;
 		}
 
 		if (top <= 0 || bottom <= 0 || top > menu_stuff->nr || bottom > top ||
diff --git a/builtin/commit.c b/builtin/commit.c
index 003bd7d..10acc53 100644
--- a/builtin/commit.c
+++ b/builtin/commit.c
@@ -63,8 +63,18 @@
 "If you wish to commit it anyway, use:\n"
 "\n"
 "    git commit --allow-empty\n"
+"\n");
+
+static const char empty_cherry_pick_advice_single[] =
+N_("Otherwise, please use 'git reset'\n");
+
+static const char empty_cherry_pick_advice_multi[] =
+N_("If you wish to skip this commit, use:\n"
 "\n"
-"Otherwise, please use 'git reset'\n");
+"    git reset\n"
+"\n"
+"Then \"git cherry-pick --continue\" will resume cherry-picking\n"
+"the remaining commits.\n");
 
 static const char *use_message_buffer;
 static const char commit_editmsg[] = "COMMIT_EDITMSG";
@@ -107,6 +117,7 @@
 static const char *cleanup_arg;
 
 static enum commit_whence whence;
+static int sequencer_in_use;
 static int use_editor = 1, include_status = 1;
 static int show_ignored_in_status, have_option_m;
 static const char *only_include_assumed;
@@ -141,8 +152,11 @@
 {
 	if (file_exists(git_path("MERGE_HEAD")))
 		whence = FROM_MERGE;
-	else if (file_exists(git_path("CHERRY_PICK_HEAD")))
+	else if (file_exists(git_path("CHERRY_PICK_HEAD"))) {
 		whence = FROM_CHERRY_PICK;
+		if (file_exists(git_path("sequencer")))
+			sequencer_in_use = 1;
+	}
 	else
 		whence = FROM_COMMIT;
 	if (s)
@@ -810,8 +824,13 @@
 		run_status(stdout, index_file, prefix, 0, s);
 		if (amend)
 			fputs(_(empty_amend_advice), stderr);
-		else if (whence == FROM_CHERRY_PICK)
+		else if (whence == FROM_CHERRY_PICK) {
 			fputs(_(empty_cherry_pick_advice), stderr);
+			if (!sequencer_in_use)
+				fputs(_(empty_cherry_pick_advice_single), stderr);
+			else
+				fputs(_(empty_cherry_pick_advice_multi), stderr);
+		}
 		return 0;
 	}
 
diff --git a/builtin/rm.c b/builtin/rm.c
index 18916e0..0df0b4d 100644
--- a/builtin/rm.c
+++ b/builtin/rm.c
@@ -58,6 +58,21 @@
 	}
 }
 
+static void error_removing_concrete_submodules(struct string_list *files, int *errs)
+{
+	print_error_files(files,
+			  Q_("the following submodule (or one of its nested "
+			     "submodules)\n"
+			     "uses a .git directory:",
+			     "the following submodules (or one of its nested "
+			     "submodules)\n"
+			     "use a .git directory:", files->nr),
+			  _("\n(use 'rm -rf' if you really want to remove "
+			    "it including all of its history)"),
+			  errs);
+	string_list_clear(files, 0);
+}
+
 static int check_submodules_use_gitfiles(void)
 {
 	int i;
@@ -86,16 +101,8 @@
 		if (!submodule_uses_gitfile(name))
 			string_list_append(&files, name);
 	}
-	print_error_files(&files,
-			  Q_("the following submodule (or one of its nested "
-			     "submodules)\n uses a .git directory:",
-			     "the following submodules (or one of its nested "
-			     "submodules)\n use a .git directory:",
-			     files.nr),
-			  _("\n(use 'rm -rf' if you really want to remove "
-			    "it including all of its history)"),
-			  &errs);
-	string_list_clear(&files, 0);
+
+	error_removing_concrete_submodules(&files, &errs);
 
 	return errs;
 }
@@ -237,17 +244,9 @@
 			    " or -f to force removal)"),
 			  &errs);
 	string_list_clear(&files_cached, 0);
-	print_error_files(&files_submodule,
-			  Q_("the following submodule (or one of its nested "
-			     "submodule)\nuses a .git directory:",
-			     "the following submodules (or one of its nested "
-			     "submodule)\nuse a .git directory:",
-			     files_submodule.nr),
-			  _("\n(use 'rm -rf' if you really "
-			    "want to remove it including all "
-			    "of its history)"),
-			  &errs);
-	string_list_clear(&files_submodule, 0);
+
+	error_removing_concrete_submodules(&files_submodule, &errs);
+
 	print_error_files(&files_local,
 			  Q_("the following file has local modifications:",
 			     "the following files have local modifications:",
diff --git a/commit-slab.h b/commit-slab.h
index 7d48163..d4c8286 100644
--- a/commit-slab.h
+++ b/commit-slab.h
@@ -48,7 +48,7 @@
 	if (!stride)							\
 		stride = 1;						\
 	s->stride = stride;						\
-	elem_size = sizeof(struct slabname) * stride;			\
+	elem_size = sizeof(elemtype) * stride;				\
 	s->slab_size = COMMIT_SLAB_SIZE / elem_size;			\
 	s->slab_count = 0;						\
 	s->slab = NULL;							\
@@ -72,11 +72,10 @@
 static elemtype *slabname## _at(struct slabname *s,			\
 				const struct commit *c)			\
 {									\
-	int nth_slab, nth_slot, ix;					\
+	int nth_slab, nth_slot;						\
 									\
-	ix = c->index * s->stride;					\
-	nth_slab = ix / s->slab_size;					\
-	nth_slot = ix % s->slab_size;					\
+	nth_slab = c->index / s->slab_size;				\
+	nth_slot = c->index % s->slab_size;				\
 									\
 	if (s->slab_count <= nth_slab) {				\
 		int i;							\
@@ -89,8 +88,8 @@
 	}								\
 	if (!s->slab[nth_slab])						\
 		s->slab[nth_slab] = xcalloc(s->slab_size,		\
-					    sizeof(**s->slab));		\
-	return &s->slab[nth_slab][nth_slot];				\
+					    sizeof(**s->slab) * s->stride);		\
+	return &s->slab[nth_slab][nth_slot * s->stride];				\
 }									\
 									\
 static int stat_ ##slabname## realloc
diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash
index cd509a5..32d1b45 100644
--- a/contrib/completion/git-completion.bash
+++ b/contrib/completion/git-completion.bash
@@ -2581,7 +2581,7 @@
 				--*=*|*.) ;;
 				*) c="$c " ;;
 				esac
-				array+=("$c")
+				array[$#array+1]="$c"
 			done
 			compset -P '*[=:]'
 			compadd -Q -S '' -p "${2-}" -a -- array && _ret=0
diff --git a/contrib/hg-to-git/hg-to-git.py b/contrib/hg-to-git/hg-to-git.py
index 232625a..60dec86 100755
--- a/contrib/hg-to-git/hg-to-git.py
+++ b/contrib/hg-to-git/hg-to-git.py
@@ -225,7 +225,7 @@
     os.system('git ls-files -x .hg --deleted | git update-index --remove --stdin')
 
     # commit
-    os.system(getgitenv(user, date) + 'git commit --allow-empty -a -F %s' % filecomment)
+    os.system(getgitenv(user, date) + 'git commit --allow-empty --allow-empty-message -a -F %s' % filecomment)
     os.unlink(filecomment)
 
     # tag
diff --git a/contrib/subtree/git-subtree.sh b/contrib/subtree/git-subtree.sh
index 51ae932..7d7af03 100755
--- a/contrib/subtree/git-subtree.sh
+++ b/contrib/subtree/git-subtree.sh
Binary files differ
diff --git a/contrib/subtree/t/t7900-subtree.sh b/contrib/subtree/t/t7900-subtree.sh
index b0f8536..66ce4b0 100755
--- a/contrib/subtree/t/t7900-subtree.sh
+++ b/contrib/subtree/t/t7900-subtree.sh
@@ -182,9 +182,9 @@
 test_expect_success 'Check that prefix argument is required for split' '
         echo "You must provide the --prefix option." > expected &&
         test_must_fail git subtree split > actual 2>&1 &&
-        test_debug "echo -n expected: " &&
+	test_debug "printf '"'"'expected: '"'"'" &&
         test_debug "cat expected" &&
-        test_debug "echo -n actual: " &&
+	test_debug "printf '"'"'actual: '"'"'" &&
         test_debug "cat actual" &&
         test_cmp expected actual &&
         rm -f expected actual
@@ -193,9 +193,9 @@
 test_expect_success 'Check that the <prefix> exists for a split' '
         echo "'"'"'non-existent-directory'"'"'" does not exist\; use "'"'"'git subtree add'"'"'" > expected &&
         test_must_fail git subtree split --prefix=non-existent-directory > actual 2>&1 &&
-        test_debug "echo -n expected: " &&
+	test_debug "printf '"'"'expected: '"'"'" &&
         test_debug "cat expected" &&
-        test_debug "echo -n actual: " &&
+	test_debug "printf '"'"'actual: '"'"'" &&
         test_debug "cat actual" &&
         test_cmp expected actual
 #        rm -f expected actual
diff --git a/git-rebase.sh b/git-rebase.sh
index 0039ecf..8d7659a 100755
--- a/git-rebase.sh
+++ b/git-rebase.sh
@@ -159,7 +159,7 @@
 			die "$(eval_gettext "Cannot store \$stash_sha1")"
 			gettext 'Applying autostash resulted in conflicts.
 Your changes are safe in the stash.
-You can run "git stash pop" or "git stash drop" it at any time.
+You can run "git stash pop" or "git stash drop" at any time.
 '
 		fi
 	fi
diff --git a/refs.c b/refs.c
index a3f2302..7b08a37 100644
--- a/refs.c
+++ b/refs.c
@@ -634,7 +634,9 @@
 static int do_one_ref(struct ref_entry *entry, void *cb_data)
 {
 	struct ref_entry_cb *data = cb_data;
+	struct ref_entry *old_current_ref;
 	int retval;
+
 	if (prefixcmp(entry->name, data->base))
 		return 0;
 
@@ -642,10 +644,12 @@
 	      !ref_resolves_to_object(entry))
 		return 0;
 
+	/* Store the old value, in case this is a recursive call: */
+	old_current_ref = current_ref;
 	current_ref = entry;
 	retval = data->fn(entry->name + data->trim, entry->u.value.sha1,
 			  entry->flag, data->cb_data);
-	current_ref = NULL;
+	current_ref = old_current_ref;
 	return retval;
 }
 
diff --git a/sha1_name.c b/sha1_name.c
index 1d210e3..852dd95 100644
--- a/sha1_name.c
+++ b/sha1_name.c
@@ -445,7 +445,7 @@
 	"\n"
 	"where \"$br\" is somehow empty and a 40-hex ref is created. Please\n"
 	"examine these refs and maybe delete them. Turn this message off by\n"
-	"running \"git config advice.object_name_warning false\"");
+	"running \"git config advice.objectNameWarning false\"");
 	unsigned char tmp_sha1[20];
 	char *real_ref = NULL;
 	int refs_found = 0;
diff --git a/t/perf/perf-lib.sh b/t/perf/perf-lib.sh
index c61d535..f4eecaa 100644
--- a/t/perf/perf-lib.sh
+++ b/t/perf/perf-lib.sh
@@ -161,7 +161,7 @@
 		echo "$test_count" >>"$perf_results_dir"/$base.subtests
 		echo "$1" >"$perf_results_dir"/$base.$test_count.descr
 		if test -z "$verbose"; then
-			echo -n "perf $test_count - $1:"
+			printf "%s" "perf $test_count - $1:"
 		else
 			echo "perf $test_count - $1:"
 		fi
@@ -170,7 +170,7 @@
 			if test_run_perf_ "$2"
 			then
 				if test -z "$verbose"; then
-					echo -n " $i"
+					printf " %s" "$i"
 				else
 					echo "* timing run $i/$GIT_PERF_REPEAT_COUNT:"
 				fi
diff --git a/t/t7301-clean-interactive.sh b/t/t7301-clean-interactive.sh
index 4e6055d..3ae394e 100755
--- a/t/t7301-clean-interactive.sh
+++ b/t/t7301-clean-interactive.sh
@@ -17,7 +17,7 @@
 
 '
 
-test_expect_success 'git clean -i (clean)' '
+test_expect_success 'git clean -i (c: clean hotkey)' '
 
 	mkdir -p build docs &&
 	touch a.out src/part3.c src/part3.h src/part4.c src/part4.h \
@@ -38,12 +38,33 @@
 
 '
 
+test_expect_success 'git clean -i (cl: clean prefix)' '
+
+	mkdir -p build docs &&
+	touch a.out src/part3.c src/part3.h src/part4.c src/part4.h \
+	docs/manual.txt obj.o build/lib.so &&
+	echo cl | git clean -i &&
+	test -f Makefile &&
+	test -f README &&
+	test -f src/part1.c &&
+	test -f src/part2.c &&
+	test ! -f a.out &&
+	test -f docs/manual.txt &&
+	test ! -f src/part3.c &&
+	test ! -f src/part3.h &&
+	test ! -f src/part4.c &&
+	test ! -f src/part4.h &&
+	test -f obj.o &&
+	test -f build/lib.so
+
+'
+
 test_expect_success 'git clean -i (quit)' '
 
 	mkdir -p build docs &&
 	touch a.out src/part3.c src/part3.h src/part4.c src/part4.h \
 	docs/manual.txt obj.o build/lib.so &&
-	echo q | git clean -i &&
+	echo quit | git clean -i &&
 	test -f Makefile &&
 	test -f README &&
 	test -f src/part1.c &&
@@ -256,6 +277,21 @@
 
 '
 
+test_expect_success 'git clean -id (select - filenames)' '
+
+	mkdir -p build docs &&
+	touch a.out foo.txt bar.txt baz.txt &&
+	(echo s; echo a.out fo ba bar; echo; echo c) | \
+	git clean -id &&
+	test -f Makefile &&
+	test ! -f a.out &&
+	test ! -f foo.txt &&
+	test ! -f bar.txt &&
+	test -f baz.txt &&
+	rm baz.txt
+
+'
+
 test_expect_success 'git clean -id (select - range)' '
 
 	mkdir -p build docs &&