diff --git a/Documentation/git-stash.adoc b/Documentation/git-stash.adoc index 1a5177f4986ca4..b4966b567edcf1 100644 --- a/Documentation/git-stash.adoc +++ b/Documentation/git-stash.adoc @@ -21,7 +21,7 @@ SYNOPSIS 'git stash' save [-p | --patch] [-S | --staged] [-k | --[no-]keep-index] [-q | --quiet] [-u | --include-untracked] [-a | --all] [] 'git stash' clear -'git stash' create [] +'git stash' create [-u | --include-untracked] [] 'git stash' store [(-m | --message) ] [-q | --quiet] DESCRIPTION @@ -139,11 +139,13 @@ drop [-q|--quiet] []:: Remove a single stash entry from the list of stash entries. -create:: +create [-u | --include-untracked] []:: Create a stash entry (which is a regular commit object) and return its object name, without storing it anywhere in the ref namespace. + If the `--include-untracked` option is used, all untracked files are + also included in the stash entry. This is intended to be useful for scripts. It is probably not the command you want to use; see "push" above. @@ -170,6 +172,9 @@ up with `git clean`. all untracked files are also stashed and then cleaned up with `git clean`. + +When used with the `create` command, all untracked files are also included +in the stash entry. ++ When used with the `show` command, show the untracked files in the stash entry as part of the diff. diff --git a/builtin/stash.c b/builtin/stash.c index dbaa999cf171a7..34828d1e2209a5 100644 --- a/builtin/stash.c +++ b/builtin/stash.c @@ -56,7 +56,7 @@ N_("git stash save [-p | --patch] [-S | --staged] [-k | --[no-]keep-index] [-q | --quiet]\n" \ " [-u | --include-untracked] [-a | --all] []") #define BUILTIN_STASH_CREATE_USAGE \ - N_("git stash create []") + N_("git stash create [-u | --include-untracked] []") #define BUILTIN_STASH_CLEAR_USAGE \ "git stash clear" @@ -110,6 +110,11 @@ static const char * const git_stash_clear_usage[] = { NULL }; +static const char * const git_stash_create_usage[] = { + BUILTIN_STASH_CREATE_USAGE, + NULL +}; + static const char * const git_stash_store_usage[] = { BUILTIN_STASH_STORE_USAGE, NULL @@ -1499,22 +1504,30 @@ static int do_create_stash(const struct pathspec *ps, struct strbuf *stash_msg_b return ret; } -static int create_stash(int argc, const char **argv, const char *prefix UNUSED, +static int create_stash(int argc, const char **argv, const char *prefix, struct repository *repo UNUSED) { int ret; + int include_untracked = 0; + struct option options[] = { + OPT_BOOL('u', "include-untracked", &include_untracked, + N_("include untracked files")), + OPT_END() + }; + struct strbuf stash_msg_buf = STRBUF_INIT; struct stash_info info = STASH_INFO_INIT; struct pathspec ps; - /* Starting with argv[1], since argv[0] is "create" */ - strbuf_join_argv(&stash_msg_buf, argc - 1, ++argv, ' '); + argc = parse_options(argc, argv, prefix, options, git_stash_create_usage, 0); + + strbuf_join_argv(&stash_msg_buf, argc, argv, ' '); memset(&ps, 0, sizeof(ps)); if (!check_changes_tracked_files(&ps)) return 0; - ret = do_create_stash(&ps, &stash_msg_buf, 0, 0, 0, &info, + ret = do_create_stash(&ps, &stash_msg_buf, include_untracked, 0, 0, &info, NULL, 0); if (!ret) printf_ln("%s", oid_to_hex(&info.w_commit)); diff --git a/t/t3903-stash.sh b/t/t3903-stash.sh index 74666ff3e4b2b8..4dd0a19369d3e4 100755 --- a/t/t3903-stash.sh +++ b/t/t3903-stash.sh @@ -632,6 +632,47 @@ test_expect_success 'stash create - no changes' ' test_must_be_empty actual ' +test_expect_success 'stash create with --include-untracked' ' + git init repo && + cd repo && + echo committed >file1 && + git add file1 && + git commit -m "initial commit" && + echo staged >file2 && + git add file2 && + echo unstaged >file3 && + echo untracked >untracked_file && + STASH_ID=$(git stash create --include-untracked "test message") && + git cat-file -p $STASH_ID >stash_commit && + grep "test message" stash_commit && + grep "parent" stash_commit | wc -l >parent_count && + echo 3 >expect && + test_cmp expect parent_count && + UNTRACKED_TREE=$(git rev-parse $STASH_ID^3^{tree}) && + git ls-tree $UNTRACKED_TREE >files && + grep untracked_file files && + test_path_is_file untracked_file +' + +test_expect_success 'stash create without --include-untracked does not include untracked files' ' + git init repo2 && + cd repo2 && + echo committed >file1 && + git add file1 && + git commit -m "initial commit" && + echo staged >file2 && + git add file2 && + echo unstaged >file3 && + echo untracked >untracked_file && + STASH_ID=$(git stash create "test message") && + git cat-file -p $STASH_ID >stash_commit && + grep "test message" stash_commit && + grep "parent" stash_commit | wc -l >parent_count && + echo 2 >expect && + test_cmp expect parent_count && + test_path_is_file untracked_file +' + test_expect_success 'stash branch - no stashes on stack, stash-like argument' ' git stash clear && test_when_finished "git reset --hard HEAD" &&