path: root/
diff options
authorPetr Baudis <>2013-06-28 15:05:32 (GMT)
committerJunio C Hamano <>2013-07-01 21:23:24 (GMT)
commita73653130edd6a8977106d45a8092c09040f9132 (patch)
treec76de88cc20570b9555b6a41e3429deee29fd247 /
parent26c986e118523fda4624cec8d14bb8a4a09fdd08 (diff)
git stash: avoid data loss when "git stash save" kills a directory
"stash save" is about saving the local change to the working tree, but also about restoring the state of the last commit to the working tree. When a local change is to turn a non-directory to a directory, in order to restore the non-directory, everything in the directory needs to be removed. Which is fine when running "git stash save --include-untracked", but without that option, untracked, newly created files in the directory will have to be discarded, if the state you are restoring to has a non-directory at the same path as the directory. Introduce a safety valve to fail the operation in such case, using the "ls-files --killed" which was designed for this exact purpose. The "stash save" is stopped when untracked files need to be discarded because their leading path ceased to be a directory, and the user is required to pass --force to really have the data removed. Signed-off-by: Petr Baudis <> Signed-off-by: Junio C Hamano <>
Diffstat (limited to '')
1 files changed, 12 insertions, 0 deletions
diff --git a/ b/
index 1e541a2..85c9e2c 100755
--- a/
+++ b/
@@ -195,6 +195,7 @@ save_stash () {
+ force=
while test $# != 0
case "$1" in
@@ -215,6 +216,9 @@ save_stash () {
+ -f|--force)
+ force=t
+ ;;
@@ -258,6 +262,14 @@ save_stash () {
say "$(gettext "No local changes to save")"
exit 0
+ if test -z "$untracked$force" &&
+ test -n "$(git ls-files --killed | head -n 1)"
+ then
+ say "$(gettext "The following untracked files would NOT be saved but need to be removed by stash save:")"
+ test -n "$GIT_QUIET" || git ls-files --killed | sed 's/^/\t/'
+ say "$(gettext "Aborting. Consider using either the --force or --include-untracked option.")" >&2
+ exit 1
+ fi
test -f "$GIT_DIR/logs/$ref_stash" ||
clear_stash || die "$(gettext "Cannot initialize stash")"