Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 7 additions & 2 deletions Documentation/git-stash.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ git stash [push [-p | --patch] [-S | --staged] [-k | --[no-]keep-index] [-q | --
git stash save [-p | --patch] [-S | --staged] [-k | --[no-]keep-index] [-q | --quiet]
[-u | --include-untracked] [-a | --all] [<message>]
git stash clear
git stash create [<message>]
git stash create [-u | --include-untracked] [<message>]
git stash store [(-m | --message) <message>] [-q | --quiet] <commit>
git stash export (--print | --to-ref <ref>) [<stash>...]
git stash import <commit>
Expand Down Expand Up @@ -140,10 +140,12 @@ with no conflicts.
`drop [-q | --quiet] [<stash>]`::
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.

Expand Down Expand Up @@ -181,6 +183,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.

Expand Down
25 changes: 19 additions & 6 deletions builtin/stash.c
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@
N_("git stash save [-p | --patch] [-S | --staged] [-k | --[no-]keep-index] [-q | --quiet]\n" \
" [-u | --include-untracked] [-a | --all] [<message>]")
#define BUILTIN_STASH_CREATE_USAGE \
N_("git stash create [<message>]")
N_("git stash create [-u | --include-untracked] [<message>]")
#define BUILTIN_STASH_EXPORT_USAGE \
N_("git stash export (--print | --to-ref <ref>) [<stash>...]")
#define BUILTIN_STASH_IMPORT_USAGE \
Expand Down Expand Up @@ -118,6 +118,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
Expand Down Expand Up @@ -1570,22 +1575,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, ' ');
Comment on lines -1581 to +1595
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wouldn't we want the --include-untracked option to be included in the message? In other words:

 	/* Starting with argv[1], since argv[0] is "create" */
-	strbuf_join_argv(&stash_msg_buf, argc - 1, ++argv, ' ');
+	strbuf_join_argv(&stash_msg_buf, argc - 1, argv + 1, ' ');
 


memset(&ps, 0, sizeof(ps));
if (!check_changes_tracked_files(&ps))
if (!include_untracked && !check_changes_tracked_files(&ps))
return 0;

ret = do_create_stash(&ps, &stash_msg_buf, 0, 0, NULL, 0, &info,
ret = do_create_stash(&ps, &stash_msg_buf, include_untracked, 0, NULL, 0, &info,
NULL, 0);
if (!ret)
printf_ln("%s", oid_to_hex(&info.w_commit));
Expand Down
33 changes: 33 additions & 0 deletions t/t3903-stash.sh
Original file line number Diff line number Diff line change
Expand Up @@ -639,6 +639,39 @@ test_expect_success 'stash create - no changes' '
test_must_be_empty actual
'

test_expect_success 'stash create with --include-untracked' '
test_when_finished "git reset --hard && git clean -fd" &&
test_commit stash-create-untracked-1 file1 committed &&
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 >parents &&
test_line_count = 3 parents &&
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' '
test_when_finished "git reset --hard && git clean -fd" &&
test_commit stash-create-no-untracked-1 file4 committed &&
echo staged >file5 &&
git add file5 &&
echo unstaged >file6 &&
echo untracked >untracked_file2 &&
STASH_ID=$(git stash create "test message") &&
git cat-file -p $STASH_ID >stash_commit &&
grep "test message" stash_commit &&
grep parent stash_commit >parents &&
test_line_count = 2 parents &&
test_path_is_file untracked_file2
'

test_expect_success 'stash branch - no stashes on stack, stash-like argument' '
git stash clear &&
test_when_finished "git reset --hard HEAD" &&
Expand Down
Loading