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
31 changes: 29 additions & 2 deletions builtin/stash.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
#include "add-interactive.h"
#include "oid-array.h"
#include "commit.h"
#include "wt-status.h"

#define INCLUDE_ALL_FILES 2

Expand Down Expand Up @@ -585,6 +586,20 @@ static void unstage_changes_unless_new(struct object_id *orig_tree)
die(_("could not write index"));
}

static int previous_stash_count = -1;

static void print_stash_status(bool quiet)
{
int stash_count;
stash_count = count_stash_entries();

if (quiet || stash_count == previous_stash_count || previous_stash_count == -1)
return;

printf_ln(Q_("Your stash now has %d entry",
"Your stash now has %d entries", stash_count), stash_count);
}

static int do_apply_stash(const char *prefix, struct stash_info *info,
int index, int quiet)
{
Expand Down Expand Up @@ -705,7 +720,7 @@ static int do_apply_stash(const char *prefix, struct stash_info *info,
absolute_path(repo_get_work_tree(the_repository)));
strvec_pushf(&cp.env, GIT_DIR_ENVIRONMENT"=%s",
absolute_path(repo_get_git_dir(the_repository)));
strvec_push(&cp.args, "status");
strvec_pushl(&cp.args, "status", "--no-show-stash", NULL);
run_command(&cp);
}

Expand Down Expand Up @@ -756,6 +771,8 @@ static int reflog_is_empty(const char *refname)

static int do_drop_stash(struct stash_info *info, int quiet)
{
previous_stash_count = count_stash_entries();

if (!reflog_delete(info->revision.buf,
EXPIRE_REFLOGS_REWRITE | EXPIRE_REFLOGS_UPDATE_REF,
0)) {
Expand Down Expand Up @@ -805,6 +822,8 @@ static int drop_stash(int argc, const char **argv, const char *prefix,
goto cleanup;

ret = do_drop_stash(&info, quiet);
print_stash_status(quiet);

cleanup:
free_stash_info(&info);
return ret;
Expand Down Expand Up @@ -836,6 +855,8 @@ static int pop_stash(int argc, const char **argv, const char *prefix,
else
ret = do_drop_stash(&info, quiet);

print_stash_status(quiet);

cleanup:
free_stash_info(&info);
return ret;
Expand Down Expand Up @@ -875,6 +896,8 @@ static int branch_stash(int argc, const char **argv, const char *prefix,
if (!ret && info.is_stash_ref)
ret = do_drop_stash(&info, 0);

print_stash_status(0);

cleanup:
free_stash_info(&info);
return ret;
Expand Down Expand Up @@ -1062,6 +1085,7 @@ static int do_store_stash(const struct object_id *w_commit, const char *stash_ms
struct stash_info info;
char revision[GIT_MAX_HEXSZ];

previous_stash_count = count_stash_entries();
oid_to_hex_r(revision, w_commit);
assert_stash_like(&info, revision);

Expand Down Expand Up @@ -1119,6 +1143,7 @@ static int store_stash(int argc, const char **argv, const char *prefix,
}

ret = do_store_stash(&obj, stash_msg, quiet);
print_stash_status(quiet);

out:
object_context_release(&dummy);
Expand Down Expand Up @@ -1914,6 +1939,7 @@ static int push_stash(int argc, const char **argv, const char *prefix,

ret = do_push_stash(&ps, stash_msg, quiet, keep_index, patch_mode,
&add_p_opt, include_untracked, only_staged);
print_stash_status(quiet);

clear_pathspec(&ps);
free(pathspec_from_file);
Expand Down Expand Up @@ -1982,6 +2008,7 @@ static int save_stash(int argc, const char **argv, const char *prefix,
ret = do_push_stash(&ps, stash_msg, quiet, keep_index,
patch_mode, &add_p_opt, include_untracked,
only_staged);
print_stash_status(quiet);

strbuf_release(&stash_msg_buf);
return ret;
Expand Down Expand Up @@ -2291,7 +2318,7 @@ static int do_export_stash(struct repository *r,
.r = r, .items = iter,
};
if (refs_for_each_reflog_ent_reverse(get_main_ref_store(r),
"refs/stash",
ref_stash,
collect_stash_entries,
&cb_data) && cb_data.count)
goto out;
Expand Down
75 changes: 44 additions & 31 deletions t/t3903-stash.sh
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ diff_cmp () {
rm -f "$1.compare" "$2.compare"
}

setup_stash() {
setup_stash () {
echo 1 >file &&
git add file &&
echo unrelated >other-file &&
Expand All @@ -60,13 +60,15 @@ setup_stash() {
git add file &&
echo 3 >file &&
test_tick &&
git stash &&
git stash | tail -n 1 >actual &&
git diff-files --quiet &&
git diff-index --cached --quiet HEAD
}

test_expect_success 'stash some dirty working directory' '
setup_stash
test_expect_success 'stash reports stash count' '
setup_stash &&
echo "Your stash now has 1 entry" >expect &&
test_cmp expect actual
'

cat >expect <<EOF
Expand Down Expand Up @@ -145,12 +147,14 @@ test_expect_success 'stash drop complains of extra options' '

test_expect_success 'drop top stash' '
git reset --hard &&
git stash list >expected &&
git stash list >expect &&
echo 7 >file &&
git stash &&
git stash drop &&
git stash drop | tail -n 1 >msg-actual &&
echo "Your stash now has 1 entry" >msg-expect &&
test_cmp msg-expect msg-actual &&
git stash list >actual &&
test_cmp expected actual &&
test_cmp expect actual &&
git stash apply &&
test 3 = $(cat file) &&
test 1 = $(git show :file) &&
Expand Down Expand Up @@ -236,14 +240,18 @@ test_expect_success 'drop stash reflog updates refs/stash with rewrite' '

test_expect_success 'stash pop' '
git reset --hard &&
git stash pop &&
git stash pop | tail -n 1 >actual &&
echo "Your stash now has 0 entries" >expect &&
test_cmp expect actual &&
test 3 = $(cat file) &&
test 1 = $(git show :file) &&
test 1 = $(git show HEAD:file) &&
test 0 = $(git stash list | wc -l)
'

cat >expect <<EOF
echo "Your stash now has 0 entries" >expect

cat >expect1 <<EOF
diff --git a/file2 b/file2
new file mode 100644
index 0000000..1fe912c
Expand All @@ -253,7 +261,7 @@ index 0000000..1fe912c
+bar2
EOF

cat >expect1 <<EOF
cat >expect2 <<EOF
diff --git a/file b/file
index 257cc56..5716ca5 100644
--- a/file
Expand All @@ -263,7 +271,7 @@ index 257cc56..5716ca5 100644
+bar
EOF

cat >expect2 <<EOF
cat >expect3 <<EOF
diff --git a/file b/file
index 7601807..5716ca5 100644
--- a/file
Expand All @@ -289,17 +297,18 @@ test_expect_success 'stash branch' '
git stash &&
echo baz >file &&
git commit file -m second &&
git stash branch stashbranch &&
git stash branch stashbranch | tail -n 1 >actual &&
test_cmp expect actual &&
test refs/heads/stashbranch = $(git symbolic-ref HEAD) &&
test $(git rev-parse HEAD) = $(git rev-parse main^) &&
git diff --cached >output &&
diff_cmp expect output &&
git diff >output &&
diff_cmp expect1 output &&
git diff >output &&
diff_cmp expect2 output &&
git add file &&
git commit -m alternate\ second &&
git diff main..stashbranch >output &&
diff_cmp output expect2 &&
diff_cmp output expect3 &&
test 0 = $(git stash list | wc -l)
'

Expand Down Expand Up @@ -427,7 +436,9 @@ test_expect_success 'stash an added file' '
git reset --hard &&
echo new >file3 &&
git add file3 &&
git stash save "added file" &&
git stash save "added file" | tail -n 1 >actual &&
echo "Your stash now has 6 entries" >expect &&
test_cmp expect actual &&
! test -r file3 &&
git stash apply &&
test new = "$(cat file3)"
Expand Down Expand Up @@ -683,12 +694,12 @@ test_expect_success 'stash show format defaults to --stat' '
echo bar >>file &&
STASH_ID=$(git stash create) &&
git reset --hard &&
cat >expected <<-EOF &&
cat >expect <<-EOF &&
file | 1 +
1 file changed, 1 insertion(+)
EOF
git stash show ${STASH_ID} >actual &&
test_cmp expected actual
test_cmp expect actual
'

test_expect_success 'stash show - stashes on stack, stash-like argument' '
Expand All @@ -701,9 +712,9 @@ test_expect_success 'stash show - stashes on stack, stash-like argument' '
echo bar >>file &&
STASH_ID=$(git stash create) &&
git reset --hard &&
echo "1 0 file" >expected &&
echo "1 0 file" >expect &&
git stash show --numstat ${STASH_ID} >actual &&
test_cmp expected actual
test_cmp expect actual
'

test_expect_success 'stash show -p - stashes on stack, stash-like argument' '
Expand All @@ -716,7 +727,7 @@ test_expect_success 'stash show -p - stashes on stack, stash-like argument' '
echo bar >>file &&
STASH_ID=$(git stash create) &&
git reset --hard &&
cat >expected <<-EOF &&
cat >expect <<-EOF &&
diff --git a/file b/file
index 7601807..935fbd3 100644
--- a/file
Expand All @@ -726,7 +737,7 @@ test_expect_success 'stash show -p - stashes on stack, stash-like argument' '
+bar
EOF
git stash show -p ${STASH_ID} >actual &&
diff_cmp expected actual
diff_cmp expect actual
'

test_expect_success 'stash show - no stashes on stack, stash-like argument' '
Expand All @@ -736,9 +747,9 @@ test_expect_success 'stash show - no stashes on stack, stash-like argument' '
echo foo >>file &&
STASH_ID=$(git stash create) &&
git reset --hard &&
echo "1 0 file" >expected &&
echo "1 0 file" >expect &&
git stash show --numstat ${STASH_ID} >actual &&
test_cmp expected actual
test_cmp expect actual
'

test_expect_success 'stash show -p - no stashes on stack, stash-like argument' '
Expand All @@ -748,7 +759,7 @@ test_expect_success 'stash show -p - no stashes on stack, stash-like argument' '
echo foo >>file &&
STASH_ID=$(git stash create) &&
git reset --hard &&
cat >expected <<-EOF &&
cat >expect <<-EOF &&
diff --git a/file b/file
index 7601807..71b52c4 100644
--- a/file
Expand All @@ -758,15 +769,15 @@ test_expect_success 'stash show -p - no stashes on stack, stash-like argument' '
+foo
EOF
git stash show -p ${STASH_ID} >actual &&
diff_cmp expected actual
diff_cmp expect actual
'

test_expect_success 'stash show --patience shows diff' '
git reset --hard &&
echo foo >>file &&
STASH_ID=$(git stash create) &&
git reset --hard &&
cat >expected <<-EOF &&
cat >expect <<-EOF &&
diff --git a/file b/file
index 7601807..71b52c4 100644
--- a/file
Expand All @@ -776,7 +787,7 @@ test_expect_success 'stash show --patience shows diff' '
+foo
EOF
git stash show --patience ${STASH_ID} >actual &&
diff_cmp expected actual
diff_cmp expect actual
'

test_expect_success 'drop: fail early if specified stash is not a stash ref' '
Expand Down Expand Up @@ -915,7 +926,7 @@ test_expect_success 'apply: show same status as git status (relative to ./)' '
sane_unset GIT_MERGE_VERBOSITY &&
git stash apply
) |
sed -e 1d >actual && # drop "Saved..."
sed -e 1,2d >actual && # drop "Your stash now has 1 entry" and "Saved..."
test_cmp expect actual
'

Expand Down Expand Up @@ -959,9 +970,11 @@ test_expect_success 'store updates stash ref and reflog' '
STASH_ID=$(git stash create) &&
git reset --hard &&
test_path_is_missing bazzy &&
git stash store -m quuxery $STASH_ID &&
git stash store -m quuxery $STASH_ID | tail -n 1 >actual &&
echo "Your stash now has 1 entry" >expect &&
test_cmp expect actual &&
test $(git rev-parse stash) = $STASH_ID &&
git reflog --format=%H stash| grep $STASH_ID &&
git reflog --format=%H stash | grep $STASH_ID &&
git stash pop &&
grep quux bazzy
'
Expand Down
2 changes: 1 addition & 1 deletion wt-status.c
Original file line number Diff line number Diff line change
Expand Up @@ -983,7 +983,7 @@ static int stash_count_refs(struct object_id *ooid UNUSED,
return 0;
}

static int count_stash_entries(void)
int count_stash_entries(void)
{
int n = 0;
refs_for_each_reflog_ent(get_main_ref_store(the_repository),
Expand Down
1 change: 1 addition & 0 deletions wt-status.h
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,7 @@ size_t wt_status_locate_end(const char *s, size_t len);
void wt_status_append_cut_line(struct strbuf *buf);
void wt_status_add_cut_line(struct wt_status *s);
void wt_status_prepare(struct repository *r, struct wt_status *s);
int count_stash_entries(void);
void wt_status_print(struct wt_status *s);
void wt_status_collect(struct wt_status *s);
/*
Expand Down
Loading