Skip to content

Commit 299c3ca

Browse files
SBhojaniSome One
authored andcommitted
stash: add --include-untracked support to git stash create
The `git stash create` command now supports the `--include-untracked` flag, allowing users to include untracked files in the stash entry. This brings parity with `git stash push`, which already supports this option. Previously, `git stash create` would only stash tracked changes. With this change, users can optionally include untracked files by specifying `--include-untracked`. The implementation involves parsing the new option in `create_stash` and passing it to `do_create_stash`, which handles the creation of the stash entry. The check for tracked changes was replaced with check_changes(), which also considers untracked files when the flag is set. Test cases were added to `t3903-stash.sh` to ensure the correct behavior, and the documentation was updated accordingly. Signed-off-by: SBhojani <shabbir.r.bhojani+git@gmail.com>
1 parent 5361983 commit 299c3ca

File tree

3 files changed

+59
-8
lines changed

3 files changed

+59
-8
lines changed

Documentation/git-stash.adoc

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ git stash [push [-p | --patch] [-S | --staged] [-k | --[no-]keep-index] [-q | --
2121
git stash save [-p | --patch] [-S | --staged] [-k | --[no-]keep-index] [-q | --quiet]
2222
[-u | --include-untracked] [-a | --all] [<message>]
2323
git stash clear
24-
git stash create [<message>]
24+
git stash create [-u | --include-untracked] [<message>]
2525
git stash store [(-m | --message) <message>] [-q | --quiet] <commit>
2626
git stash export (--print | --to-ref <ref>) [<stash>...]
2727
git stash import <commit>
@@ -140,10 +140,12 @@ with no conflicts.
140140
`drop [-q | --quiet] [<stash>]`::
141141
Remove a single stash entry from the list of stash entries.
142142

143-
`create`::
143+
`create [-u | --include-untracked]`::
144144
Create a stash entry (which is a regular commit object) and
145145
return its object name, without storing it anywhere in the ref
146146
namespace.
147+
If the `--include-untracked` option is used, all untracked files are
148+
also included in the stash entry.
147149
This is intended to be useful for scripts. It is probably not
148150
the command you want to use; see "push" above.
149151

@@ -181,6 +183,9 @@ up with `git clean`.
181183
all untracked files are also stashed and then cleaned up with
182184
`git clean`.
183185
+
186+
When used with the `create` command, all untracked files are also included
187+
in the stash entry.
188+
+
184189
When used with the `show` command, show the untracked files in the stash
185190
entry as part of the diff.
186191

builtin/stash.c

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@
5858
N_("git stash save [-p | --patch] [-S | --staged] [-k | --[no-]keep-index] [-q | --quiet]\n" \
5959
" [-u | --include-untracked] [-a | --all] [<message>]")
6060
#define BUILTIN_STASH_CREATE_USAGE \
61-
N_("git stash create [<message>]")
61+
N_("git stash create [-u | --include-untracked] [<message>]")
6262
#define BUILTIN_STASH_EXPORT_USAGE \
6363
N_("git stash export (--print | --to-ref <ref>) [<stash>...]")
6464
#define BUILTIN_STASH_IMPORT_USAGE \
@@ -118,6 +118,11 @@ static const char * const git_stash_clear_usage[] = {
118118
NULL
119119
};
120120

121+
static const char * const git_stash_create_usage[] = {
122+
BUILTIN_STASH_CREATE_USAGE,
123+
NULL
124+
};
125+
121126
static const char * const git_stash_store_usage[] = {
122127
BUILTIN_STASH_STORE_USAGE,
123128
NULL
@@ -1570,22 +1575,30 @@ static int do_create_stash(const struct pathspec *ps, struct strbuf *stash_msg_b
15701575
return ret;
15711576
}
15721577

1573-
static int create_stash(int argc, const char **argv, const char *prefix UNUSED,
1578+
static int create_stash(int argc, const char **argv, const char *prefix,
15741579
struct repository *repo UNUSED)
15751580
{
15761581
int ret;
1582+
int include_untracked = 0;
1583+
struct option options[] = {
1584+
OPT_BOOL('u', "include-untracked", &include_untracked,
1585+
N_("include untracked files")),
1586+
OPT_END()
1587+
};
1588+
15771589
struct strbuf stash_msg_buf = STRBUF_INIT;
15781590
struct stash_info info = STASH_INFO_INIT;
15791591
struct pathspec ps;
15801592

1581-
/* Starting with argv[1], since argv[0] is "create" */
1582-
strbuf_join_argv(&stash_msg_buf, argc - 1, ++argv, ' ');
1593+
argc = parse_options(argc, argv, prefix, options, git_stash_create_usage, 0);
1594+
1595+
strbuf_join_argv(&stash_msg_buf, argc, argv, ' ');
15831596

15841597
memset(&ps, 0, sizeof(ps));
1585-
if (!check_changes_tracked_files(&ps))
1598+
if (!check_changes(&ps, include_untracked, NULL))
15861599
return 0;
15871600

1588-
ret = do_create_stash(&ps, &stash_msg_buf, 0, 0, NULL, 0, &info,
1601+
ret = do_create_stash(&ps, &stash_msg_buf, include_untracked, 0, NULL, 0, &info,
15891602
NULL, 0);
15901603
if (!ret)
15911604
printf_ln("%s", oid_to_hex(&info.w_commit));

t/t3903-stash.sh

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -639,6 +639,39 @@ test_expect_success 'stash create - no changes' '
639639
test_must_be_empty actual
640640
'
641641

642+
test_expect_success 'stash create with --include-untracked' '
643+
test_when_finished "git reset --hard && git clean -fd" &&
644+
test_commit stash-create-untracked-1 file1 committed &&
645+
echo staged >file2 &&
646+
git add file2 &&
647+
echo unstaged >file3 &&
648+
echo untracked >untracked_file &&
649+
STASH_ID=$(git stash create --include-untracked "test message") &&
650+
git cat-file -p $STASH_ID >stash_commit &&
651+
grep "test message" stash_commit &&
652+
grep parent stash_commit >parents &&
653+
test_line_count = 3 parents &&
654+
UNTRACKED_TREE=$(git rev-parse $STASH_ID^3^{tree}) &&
655+
git ls-tree $UNTRACKED_TREE >files &&
656+
grep untracked_file files &&
657+
test_path_is_file untracked_file
658+
'
659+
660+
test_expect_success 'stash create without --include-untracked does not include untracked files' '
661+
test_when_finished "git reset --hard && git clean -fd" &&
662+
test_commit stash-create-no-untracked-1 file4 committed &&
663+
echo staged >file5 &&
664+
git add file5 &&
665+
echo unstaged >file6 &&
666+
echo untracked >untracked_file2 &&
667+
STASH_ID=$(git stash create "test message") &&
668+
git cat-file -p $STASH_ID >stash_commit &&
669+
grep "test message" stash_commit &&
670+
grep parent stash_commit >parents &&
671+
test_line_count = 2 parents &&
672+
test_path_is_file untracked_file2
673+
'
674+
642675
test_expect_success 'stash branch - no stashes on stack, stash-like argument' '
643676
git stash clear &&
644677
test_when_finished "git reset --hard HEAD" &&

0 commit comments

Comments
 (0)