@@ -27,11 +27,11 @@ static const char * const git_stash_usage[] = {
2727 N_ ("git stash ( pop | apply ) [--index] [-q|--quiet] [<stash>]" ),
2828 N_ ("git stash branch <branchname> [<stash>]" ),
2929 "git stash clear" ,
30- N_ ("git stash [push [-p|--patch] [-k|--[no-]keep-index] [-q|--quiet]\n"
30+ N_ ("git stash [push [-p|--patch] [-S|--staged] [- k|--[no-]keep-index] [-q|--quiet]\n"
3131 " [-u|--include-untracked] [-a|--all] [-m|--message <message>]\n"
3232 " [--pathspec-from-file=<file> [--pathspec-file-nul]]\n"
3333 " [--] [<pathspec>...]]" ),
34- N_ ("git stash save [-p|--patch] [-k|--[no-]keep-index] [-q|--quiet]\n"
34+ N_ ("git stash save [-p|--patch] [-S|--staged] [- k|--[no-]keep-index] [-q|--quiet]\n"
3535 " [-u|--include-untracked] [-a|--all] [<message>]" ),
3636 NULL
3737};
@@ -1132,6 +1132,38 @@ static int save_untracked_files(struct stash_info *info, struct strbuf *msg,
11321132 return ret ;
11331133}
11341134
1135+ static int stash_staged (struct stash_info * info , struct strbuf * out_patch ,
1136+ int quiet )
1137+ {
1138+ int ret = 0 ;
1139+ struct child_process cp_diff_tree = CHILD_PROCESS_INIT ;
1140+ struct index_state istate = { NULL };
1141+
1142+ if (write_index_as_tree (& info -> w_tree , & istate , the_repository -> index_file ,
1143+ 0 , NULL )) {
1144+ ret = -1 ;
1145+ goto done ;
1146+ }
1147+
1148+ cp_diff_tree .git_cmd = 1 ;
1149+ strvec_pushl (& cp_diff_tree .args , "diff-tree" , "-p" , "-U1" , "HEAD" ,
1150+ oid_to_hex (& info -> w_tree ), "--" , NULL );
1151+ if (pipe_command (& cp_diff_tree , NULL , 0 , out_patch , 0 , NULL , 0 )) {
1152+ ret = -1 ;
1153+ goto done ;
1154+ }
1155+
1156+ if (!out_patch -> len ) {
1157+ if (!quiet )
1158+ fprintf_ln (stderr , _ ("No staged changes" ));
1159+ ret = 1 ;
1160+ }
1161+
1162+ done :
1163+ discard_index (& istate );
1164+ return ret ;
1165+ }
1166+
11351167static int stash_patch (struct stash_info * info , const struct pathspec * ps ,
11361168 struct strbuf * out_patch , int quiet )
11371169{
@@ -1258,7 +1290,7 @@ static int stash_working_tree(struct stash_info *info, const struct pathspec *ps
12581290}
12591291
12601292static int do_create_stash (const struct pathspec * ps , struct strbuf * stash_msg_buf ,
1261- int include_untracked , int patch_mode ,
1293+ int include_untracked , int patch_mode , int only_staged ,
12621294 struct stash_info * info , struct strbuf * patch ,
12631295 int quiet )
12641296{
@@ -1337,6 +1369,16 @@ static int do_create_stash(const struct pathspec *ps, struct strbuf *stash_msg_b
13371369 } else if (ret > 0 ) {
13381370 goto done ;
13391371 }
1372+ } else if (only_staged ) {
1373+ ret = stash_staged (info , patch , quiet );
1374+ if (ret < 0 ) {
1375+ if (!quiet )
1376+ fprintf_ln (stderr , _ ("Cannot save the current "
1377+ "staged state" ));
1378+ goto done ;
1379+ } else if (ret > 0 ) {
1380+ goto done ;
1381+ }
13401382 } else {
13411383 if (stash_working_tree (info , ps )) {
13421384 if (!quiet )
@@ -1395,7 +1437,7 @@ static int create_stash(int argc, const char **argv, const char *prefix)
13951437 if (!check_changes_tracked_files (& ps ))
13961438 return 0 ;
13971439
1398- ret = do_create_stash (& ps , & stash_msg_buf , 0 , 0 , & info ,
1440+ ret = do_create_stash (& ps , & stash_msg_buf , 0 , 0 , 0 , & info ,
13991441 NULL , 0 );
14001442 if (!ret )
14011443 printf_ln ("%s" , oid_to_hex (& info .w_commit ));
@@ -1405,7 +1447,7 @@ static int create_stash(int argc, const char **argv, const char *prefix)
14051447}
14061448
14071449static int do_push_stash (const struct pathspec * ps , const char * stash_msg , int quiet ,
1408- int keep_index , int patch_mode , int include_untracked )
1450+ int keep_index , int patch_mode , int include_untracked , int only_staged )
14091451{
14101452 int ret = 0 ;
14111453 struct stash_info info ;
@@ -1423,6 +1465,17 @@ static int do_push_stash(const struct pathspec *ps, const char *stash_msg, int q
14231465 goto done ;
14241466 }
14251467
1468+ /* --patch overrides --staged */
1469+ if (patch_mode )
1470+ only_staged = 0 ;
1471+
1472+ if (only_staged && include_untracked ) {
1473+ fprintf_ln (stderr , _ ("Can't use --staged and --include-untracked"
1474+ " or --all at the same time" ));
1475+ ret = -1 ;
1476+ goto done ;
1477+ }
1478+
14261479 read_cache_preload (NULL );
14271480 if (!include_untracked && ps -> nr ) {
14281481 int i ;
@@ -1463,7 +1516,7 @@ static int do_push_stash(const struct pathspec *ps, const char *stash_msg, int q
14631516
14641517 if (stash_msg )
14651518 strbuf_addstr (& stash_msg_buf , stash_msg );
1466- if (do_create_stash (ps , & stash_msg_buf , include_untracked , patch_mode ,
1519+ if (do_create_stash (ps , & stash_msg_buf , include_untracked , patch_mode , only_staged ,
14671520 & info , & patch , quiet )) {
14681521 ret = -1 ;
14691522 goto done ;
@@ -1480,7 +1533,7 @@ static int do_push_stash(const struct pathspec *ps, const char *stash_msg, int q
14801533 printf_ln (_ ("Saved working directory and index state %s" ),
14811534 stash_msg_buf .buf );
14821535
1483- if (!patch_mode ) {
1536+ if (!( patch_mode || only_staged ) ) {
14841537 if (include_untracked && !ps -> nr ) {
14851538 struct child_process cp = CHILD_PROCESS_INIT ;
14861539
@@ -1598,6 +1651,7 @@ static int push_stash(int argc, const char **argv, const char *prefix,
15981651{
15991652 int force_assume = 0 ;
16001653 int keep_index = -1 ;
1654+ int only_staged = 0 ;
16011655 int patch_mode = 0 ;
16021656 int include_untracked = 0 ;
16031657 int quiet = 0 ;
@@ -1608,6 +1662,8 @@ static int push_stash(int argc, const char **argv, const char *prefix,
16081662 struct option options [] = {
16091663 OPT_BOOL ('k' , "keep-index" , & keep_index ,
16101664 N_ ("keep index" )),
1665+ OPT_BOOL ('S' , "staged" , & only_staged ,
1666+ N_ ("stash staged changes only" )),
16111667 OPT_BOOL ('p' , "patch" , & patch_mode ,
16121668 N_ ("stash in patch mode" )),
16131669 OPT__QUIET (& quiet , N_ ("quiet mode" )),
@@ -1646,6 +1702,9 @@ static int push_stash(int argc, const char **argv, const char *prefix,
16461702 if (patch_mode )
16471703 die (_ ("--pathspec-from-file is incompatible with --patch" ));
16481704
1705+ if (only_staged )
1706+ die (_ ("--pathspec-from-file is incompatible with --staged" ));
1707+
16491708 if (ps .nr )
16501709 die (_ ("--pathspec-from-file is incompatible with pathspec arguments" ));
16511710
@@ -1657,12 +1716,13 @@ static int push_stash(int argc, const char **argv, const char *prefix,
16571716 }
16581717
16591718 return do_push_stash (& ps , stash_msg , quiet , keep_index , patch_mode ,
1660- include_untracked );
1719+ include_untracked , only_staged );
16611720}
16621721
16631722static int save_stash (int argc , const char * * argv , const char * prefix )
16641723{
16651724 int keep_index = -1 ;
1725+ int only_staged = 0 ;
16661726 int patch_mode = 0 ;
16671727 int include_untracked = 0 ;
16681728 int quiet = 0 ;
@@ -1673,6 +1733,8 @@ static int save_stash(int argc, const char **argv, const char *prefix)
16731733 struct option options [] = {
16741734 OPT_BOOL ('k' , "keep-index" , & keep_index ,
16751735 N_ ("keep index" )),
1736+ OPT_BOOL ('S' , "staged" , & only_staged ,
1737+ N_ ("stash staged changes only" )),
16761738 OPT_BOOL ('p' , "patch" , & patch_mode ,
16771739 N_ ("stash in patch mode" )),
16781740 OPT__QUIET (& quiet , N_ ("quiet mode" )),
@@ -1694,7 +1756,7 @@ static int save_stash(int argc, const char **argv, const char *prefix)
16941756
16951757 memset (& ps , 0 , sizeof (ps ));
16961758 ret = do_push_stash (& ps , stash_msg , quiet , keep_index ,
1697- patch_mode , include_untracked );
1759+ patch_mode , include_untracked , only_staged );
16981760
16991761 strbuf_release (& stash_msg_buf );
17001762 return ret ;
0 commit comments