Commit graph

95 commits

Author SHA1 Message Date
Junio C Hamano ba2d451122 Merge branch 'tg/stash-refresh-index'
"git stash" learned to write refreshed index back to disk.

* tg/stash-refresh-index:
  stash: make sure to write refreshed cache
  merge: use refresh_and_write_cache
  factor out refresh_and_write_cache function
2019-10-07 11:32:53 +09:00
Thomas Gummerer 34933d0eff stash: make sure to write refreshed cache
When converting stash into C, calls to 'git update-index --refresh'
were replaced with the 'refresh_cache()' function.  That is fine as
long as the index is only needed in-core, and not re-read from disk.

However in many cases we do actually need the refreshed index to be
written to disk, for example 'merge_recursive_generic()' discards the
in-core index before re-reading it from disk, and in the case of 'apply
--quiet', the 'refresh_cache()' we currently have is pointless without
writing the index to disk.

Always write the index after refreshing it to ensure there are no
regressions in this compared to the scripted stash.  In the future we
can consider avoiding the write where possible after making sure none
of the subsequent calls actually need the refreshed cache, and it is
not expected to be refreshed after stash exits or it is written
somewhere else already.

Reported-by: Jeff King <peff@peff.net>
Signed-off-by: Thomas Gummerer <t.gummerer@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2019-09-20 09:58:22 -07:00
brian m. carlson c784815073 t3903: abstract away SHA-1-specific constants
Abstract away the SHA-1-specific constants by sanitizing diff output to
remove the index lines, since it's clear from the assertions in question
that we are not interested in the specific object IDs.

Signed-off-by: brian m. carlson <sandals@crustytoothpaste.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2019-08-26 08:55:45 -07:00
Junio C Hamano f8aee8576a Merge branch 'tg/stash-keep-index-with-removed-paths'
"git stash --keep-index" did not work correctly on paths that have
been removed, which has been fixed.

* tg/stash-keep-index-with-removed-paths:
  stash: fix handling removed files with --keep-index
2019-07-25 13:59:23 -07:00
Thomas Gummerer b932f6a5e8 stash: fix handling removed files with --keep-index
git stash push --keep-index is supposed to keep all changes that have
been added to the index, both in the index and on disk.

Currently this doesn't behave correctly when a file is removed from
the index.  Instead of keeping it deleted on disk, --keep-index
currently restores the file.

Fix that behaviour by using 'git checkout' in no-overlay mode which
can faithfully restore the index and working tree.  This also
simplifies the code.

Note that this will overwrite untracked files if the untracked file
has the same name as a file that has been deleted in the index.

Signed-off-by: Thomas Gummerer <t.gummerer@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2019-07-16 12:58:20 -07:00
Thomas Gummerer 63b50c8ffe stash: fix show referencing stash index
In the conversion of 'stash show' to C in dc7bd382b1 ("stash: convert
show to builtin", 2019-02-25), 'git stash show <n>', where n is the
index of a stash got broken, if n is not a file or a valid revision by
itself.

'stash show' accepts any flag 'git diff' accepts for changing the
output format.  Internally we use 'setup_revisions()' to parse these
command line flags.  Currently we pass the whole argv through to
'setup_revisions()', which includes the stash index.

As the stash index is not a valid revision or a file in the working
tree in most cases however, this 'setup_revisions()' call (and thus
the whole command) ends up failing if we use this form of 'git stash
show'.

Instead of passing the whole argv to 'setup_revisions()', only pass
the flags (and the command name) through, while excluding the stash
reference.  The stash reference is parsed (and validated) in
'get_stash_info()' already.

This separate parsing also means that we currently do produce the
correct output if the command succeeds.

Reported-by: Mike Hommey <mh@glandium.org>
Signed-off-by: Thomas Gummerer <t.gummerer@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2019-06-19 14:47:49 -07:00
Thomas Gummerer 8e407bc817 stash: setup default diff output format if necessary
In the scripted 'git stash show' when no arguments are passed, we just
pass '--stat' to 'git diff'.  When any argument is passed to 'stash
show', we no longer pass '--stat' to 'git diff', and pass whatever
flags are passed directly through to 'git diff'.

By default 'git diff' shows the patch output.  So when a user uses
'git stash show --patience', they would be shown the diff as expected,
using the patience algorithm.  '--patience' in this case only changes
the diff algorithm, but does not cause 'git diff' to show the diff by
itself.  The diff is shown because that's the default behaviour of
'git diff'.

In the C version of 'git stash show', we try to emulate that behaviour
using the internal diff API.  However we forgot to set up the default
output format, in case it wasn't set by any of the flags that were
passed through.  So 'git stash show --patience' in the builtin version
of stash would be completely silent, while it would show the diff in
the scripted version.

The same thing would happen for other flags that only affect the way a
patch is displayed, rather than switching to a different output format
than the default one.

Fix this by setting up the default output format for 'git diff'.

Reported-by: Denton Liu <liu.denton@gmail.com>
Signed-off-by: Thomas Gummerer <t.gummerer@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2019-03-21 10:41:56 +09:00
Paul-Sebastian Ungureanu 1ac528c0b0 stash: make push -q quiet
There is a change in behaviour with this commit. When there was
no initial commit, the shell version of stash would still display
a message. This commit makes `push` to not display any message if
`--quiet` or `-q` is specified. Add tests for `--quiet`.

Signed-off-by: Paul-Sebastian Ungureanu <ungureanupaulsebastian@gmail.com>
Signed-off-by: Thomas Gummerer <t.gummerer@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2019-03-07 09:41:40 +09:00
Paul-Sebastian Ungureanu ab8ad46ec7 stash: rename test cases to be more descriptive
Rename some test cases' labels to be more descriptive and under 80
characters per line.

Signed-off-by: Paul-Sebastian Ungureanu <ungureanupaulsebastian@gmail.com>
Signed-off-by: Thomas Gummerer <t.gummerer@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2019-03-07 09:41:40 +09:00
Matthew Kraai b6e531e6c6 t3903: add test for --intent-to-add file
Add a test showing the 'git stash' behaviour with a file that has been
added with 'git add --intent-to-add'.  Stash fails to stash the file,
so the purpose of this test is mainly to make sure git doesn't crash,
but exits normally in this situation.

This is in preparation for converting stash into a builtin.

[tg: pulled the test out into a separate commit]

Signed-off-by: Matthew Kraai <mkraai@its.jnj.com>
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Thomas Gummerer <t.gummerer@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2019-03-07 09:41:40 +09:00
Paul-Sebastian Ungureanu 6a0b88b24d t3903: modernize style
Remove whitespaces after redirection operators and wrap
long lines.

Signed-off-by: Paul-Sebastian Ungureanu <ungureanupaulsebastian@gmail.com>
Signed-off-by: Thomas Gummerer <t.gummerer@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2019-03-07 09:41:40 +09:00
Joel Teichroeb 93415f58e0 stash: improve option parsing test coverage
In preparation for converting the stash command incrementally to
a builtin command, this patch improves test coverage of the option
parsing. Both for having too many parameters, or too few.

Signed-off-by: Joel Teichroeb <joel@teichroeb.net>
Signed-off-by: Paul-Sebastian Ungureanu <ungureanupaulsebastian@gmail.com>
Signed-off-by: Thomas Gummerer <t.gummerer@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2019-03-07 09:41:40 +09:00
Thomas Gummerer 0640897dc5 ident: don't require calling prepare_fallback_ident first
In fd5a58477c ("ident: add the ability to provide a "fallback
identity"", 2019-02-25) I made it a requirement to call
prepare_fallback_ident as the first function in the ident API.
However in stash we didn't actually end up following that.

This leads to a BUG if user.email and user.name are set.  It was not
caught in the test suite because we only rely on environment variables
for setting the user name and email instead of the config.

Instead of making it a bug to call other functions in the ident API
first, just return silently if the identity of a user was already set
up.

Reported-by: Denton Liu <liu.denton@gmail.com>
Helped-by: Jeff King <peff@peff.net>
Signed-off-by: Thomas Gummerer <t.gummerer@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2019-03-07 09:41:40 +09:00
Slavica Djukic 3bc2111fc2 stash: tolerate missing user identity
The "git stash" command insists on having a usable user identity to
the same degree as the "git commit-tree" and "git commit" commands
do, because it uses the same codepath that creates commit objects
as these commands.

It is not strictly necesary to do so. Check if we will barf before
creating commit objects and then supply fake identity to please the
machinery that creates commits.
Add test to document that stash executes correctly both with and
without valid ident.

This is not that much of usability improvement, as the users who run
"git stash" would eventually want to record their changes that are
temporarily stored in the stashes in a more permanent history by
committing, and they must do "git config user.{name,email}" at that
point anyway, so arguably this change is only delaying a step that
is necessary to work in the repository.

Helped-by: Junio C Hamano <gitster@pobox.com>
Signed-off-by: Slavica Djukic <slawica92@hotmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2018-11-19 08:24:34 +09:00
Matthew DeVore dcbaa0b361 t/*: fix ordering of expected/observed arguments
Fix various places where the ordering was obviously wrong, meaning it
was easy to find with grep.

Signed-off-by: Matthew DeVore <matvore@google.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2018-10-07 08:51:18 +09:00
SZEDER Gábor 79b04f9b60 t3903-stash: don't try to grep non-existing file
The test 'store updates stash ref and reflog' in 't3903-stash.sh'
creates a stash from a new file, runs 'git reset --hard' to throw away
any modifications to the work tree, and then runs '! grep' to ensure
that the staged contents are gone.  Since the file didn't exist
before, it shouldn't exist after 'git reset' either.  Consequently,
this 'grep' doesn't fail as expected, because it can't find the staged
content, but it fails because it can't open the file.

Tighten this check by using 'test_path_is_missing' instead, thereby
avoiding an unexpected error from 'grep' as well.

Signed-off-by: SZEDER Gábor <szeder.dev@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2018-08-22 11:52:35 -07:00
David Turner cbc5cf7ce5 t: make many tests depend less on the refs being files
Many tests are very focused on the file system representation of the
loose and packed refs code. As there are plans to implement other
ref storage systems, let's migrate these tests to a form that test
the intent of the refs storage system instead of it internals.

This will make clear to readers that these tests do not depend on
which ref backend is used.

The internals of the loose refs backend are still tested in
t1400-update-ref.sh, whereas the tests changed in this patch focus
on testing other aspects.

This patch just takes care of many low hanging fruits. It does not
try to completely solves the issue.

Helped-by: Stefan Beller <sbeller@google.com>
Helped-by: Johannes Schindelin <Johannes.Schindelin@gmx.de>
Signed-off-by: David Turner <dturner@twopensource.com>
Signed-off-by: Christian Couder <chriscool@tuxfamily.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2018-05-23 14:59:38 +09:00
Junio C Hamano 087d1a8e9c Merge branch 'tg/stash-with-pathspec-fix'
"git stash -- <pathspec>" incorrectly blew away untracked files in
the directory that matched the pathspec, which has been corrected.

* tg/stash-with-pathspec-fix:
  stash: don't delete untracked files that match pathspec
2018-01-23 13:16:39 -08:00
Thomas Gummerer bba067d2fa stash: don't delete untracked files that match pathspec
Currently when 'git stash push -- <pathspec>' is used, untracked files
that match the pathspec will be deleted, even though they do not end up
in a stash anywhere.

This is because the original commit introducing the pathspec feature in
git stash push (df6bba0937 ("stash: teach 'push' (and 'create_stash') to
honor pathspec", 2017-02-28)) used the sequence of 'git reset <pathspec>
&& git ls-files --modified <pathspec> | git checkout-index && git clean
<pathspec>'.

The intention was to emulate what 'git reset --hard -- <pathspec>' would
do.  The call to 'git clean' was supposed to clean up the files that
were unstaged by 'git reset'.  This would work fine if the pathspec
doesn't match any files that were untracked before 'git stash push --
<pathspec>'.  However if <pathspec> matches a file that was untracked
before invoking the 'stash' command, all untracked files matching the
pathspec would inadvertently be deleted as well, even though they
wouldn't end up in the stash, and are therefore lost.

This behaviour was never what was intended, only blobs that also end up
in the stash should be reset to their state in HEAD, previously
untracked files should be left alone.

To achieve this, first match what's in the index and what's in the
working tree by adding all changes to the index, ask diff-index what
changed between HEAD and the current index, and then apply that patch in
reverse to get rid of the changes, which includes removal of added
files and resurrection of removed files.

Reported-by: Reid Price <reid.price@gmail.com>
Helped-by: Junio C Hamano <gitster@pobox.com>
Signed-off-by: Thomas Gummerer <t.gummerer@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2018-01-08 13:02:25 -08:00
Junio C Hamano 714485c7de Merge branch 'ph/stash-save-m-option-fix'
In addition to "git stash -m message", the command learned to
accept "git stash -mmessage" form.

* ph/stash-save-m-option-fix:
  stash: learn to parse -m/--message like commit does
2017-12-06 09:23:43 -08:00
Phil Hord 5675473fcb stash: learn to parse -m/--message like commit does
`git stash push -m foo` uses "foo" as the message for the stash. But
`git stash push -m"foo"` does not parse successfully.  Similarly
`git stash push --message="My stash message"` also fails.  The stash
documentation doesn't suggest this syntax should work, but gitcli
does and my fingers have learned this pattern long ago for `commit`.

Teach `git stash` to parse -mFoo and --message=Foo the same as `git
commit` would do.  Even though it's an internal function, add
similar support to create_stash() for consistency.

Signed-off-by: Phil Hord <phil.hord@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-11-24 14:47:44 +09:00
Joel Teichroeb 4e9bf3dd6d stash: add a test for stashing in a detached state
All that we are really testing here is that the message is
correct when we are not on any branch. All other functionality is
already tested elsewhere.

Signed-off-by: Joel Teichroeb <joel@teichroeb.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-08-19 14:04:04 -07:00
Joel Teichroeb b04e6915fa stash: add a test for when apply fails during stash branch
If the return value of merge recursive is not checked, the stash could end
up being dropped even though it was not applied properly

Signed-off-by: Joel Teichroeb <joel@teichroeb.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-08-19 14:03:56 -07:00
Joel Teichroeb c95bc226d4 stash: add a test for stash create with no files
Ensure the command suceeds and outputs nothing

Signed-off-by: Joel Teichroeb <joel@teichroeb.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-08-19 14:03:53 -07:00
Junio C Hamano 49a8bf2eda Merge branch 'ps/stash-push-pathspec-fix'
"git stash push <pathspec>" did not work from a subdirectory at all.
Bugfix for a topic in v2.13

* ps/stash-push-pathspec-fix:
  git-stash: fix pushing stash with pathspec from subdir
2017-06-22 14:15:25 -07:00
Patrick Steinhardt 22fc703ec9 git-stash: fix pushing stash with pathspec from subdir
The `git stash push` command recently gained the ability to get a
pathspec as its argument to only stash matching files. Calling this
command from a subdirectory does not work, though, as one of the first
things we do is changing to the top level directory without keeping
track of the prefix from which the command is being run.

Fix the shortcoming by storing the prefix previous to the call to
`cd_to_toplevel` and then subsequently using `git rev-parse --prefix` to
correctly resolve the pathspec. Add a test to catch future breakage of
this usecase.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-06-13 08:27:13 -07:00
Ævar Arnfjörð Bjarmason 0d75bfe67b tests: fix tests broken under GETTEXT_POISON=YesPlease
The GETTEXT_POISON=YesPlease compile-time testing option added in my
bb946bba76 ("i18n: add GETTEXT_POISON to simulate unfriendly
translator", 2011-02-22) has been slowly bitrotting as strings have
been marked for translation, and new tests have been added without
running it.

I brought this up on the list ("[BUG] test suite broken with
GETTEXT_POISON=YesPlease", [1]) asking whether this mode was useful at
all anymore. At least one person occasionally uses it, and Lars
Schneider offered to change one of the the Travis builds to run in
this mode, so fix up the failing ones.

My test setup runs most of the tests, with the notable exception of
skipping all the p4 tests, so it's possible that there's still some
lurking regressions I haven't fixed.

1. <CACBZZX62+acvi1dpkknadTL827mtCm_QesGSZ=6+UnyeMpg8+Q@mail.gmail.com>

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-05-11 18:44:38 +09:00
Thomas Gummerer e0e7f99ea4 stash: keep untracked files intact in stash -k
Currently when there are untracked changes in a file "one" and in a file
"two" in the repository and the user uses:

    git stash push -k one

all changes in "two" are wiped out completely.  That is clearly not the
intended result.  Make sure that only the files given in the pathspec
are changed when git stash push -k <pathspec> is used.

Reported-by: Jeff King <peff@peff.net>
Signed-off-by: Thomas Gummerer <t.gummerer@gmail.com>
Reviewed-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-03-22 14:55:56 -07:00
Thomas Gummerer 1790f4fea0 stash: don't show internal implementation details
git stash push uses other git commands internally.  Currently it only
passes the -q flag to those if the -q flag is passed to git stash.  when
using 'git stash push -p -q --no-keep-index', it doesn't even pass the
flag on to the internal reset at all.

It really is enough for the user to know that the stash is created,
without bothering them with the internal details of what's happening.
Always pass the -q flag to the internal git clean and git reset
commands, to avoid unnecessary and potentially confusing output.

Reported-by: Jeff King <peff@peff.net>
Signed-off-by: Thomas Gummerer <t.gummerer@gmail.com>
Reviewed-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-03-22 14:55:11 -07:00
Thomas Gummerer 9e140909f6 stash: allow pathspecs in the no verb form
Now that stash_push is used in the no verb form of stash, allow
specifying the command line for this form as well.  Always use -- to
disambiguate pathspecs from other non-option arguments.

Also make git stash -p an alias for git stash push -p.  This allows
users to use git stash -p <pathspec>.

Signed-off-by: Thomas Gummerer <t.gummerer@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-02-28 14:21:10 -08:00
Thomas Gummerer 1ada5020b3 stash: use stash_push for no verb form
Now that we have stash_push, which accepts pathspec arguments, use
it instead of stash_save in git stash without any additional verbs.

Previously we allowed git stash -- -message, which is no longer allowed
after this patch.  Messages starting with a hyphen was allowed since
3c2eb80f, ("stash: simplify defaulting to "save" and reject unknown
options").  However it was never the intent to allow that, but rather it
was allowed accidentally.

Signed-off-by: Thomas Gummerer <t.gummerer@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-02-28 14:21:10 -08:00
Thomas Gummerer df6bba0937 stash: teach 'push' (and 'create_stash') to honor pathspec
While working on a repository, it's often helpful to stash the changes
of a single or multiple files, and leave others alone.  Unfortunately
git currently offers no such option.  git stash -p can be used to work
around this, but it's often impractical when there are a lot of changes
over multiple files.

Allow 'git stash push' to take pathspec to specify which paths to stash.

Helped-by: Junio C Hamano <gitster@pobox.com>
Signed-off-by: Thomas Gummerer <t.gummerer@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-02-28 14:21:05 -08:00
Thomas Gummerer 6f5ccd4df5 stash: add test for the create command line arguments
Currently there is no test showing the expected behaviour of git stash
create's command line arguments.  Add a test for that to show the
current expected behaviour and to make sure future refactorings don't
break those expectations.

Signed-off-by: Thomas Gummerer <t.gummerer@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-02-19 23:47:41 -08:00
Thomas Gummerer f5727e26e4 stash: introduce push verb
Introduce a new git stash push verb in addition to git stash save.  The
push verb is used to transition from the current command line arguments
to a more conventional way, in which the message is given as an argument
to the -m option.

This allows us to have pathspecs at the end of the command line
arguments like other Git commands do, so that the user can say which
subset of paths to stash (and leave others behind).

Helped-by: Junio C Hamano <gitster@pobox.com>
Signed-off-by: Thomas Gummerer <t.gummerer@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-02-19 23:47:41 -08:00
Junio C Hamano 12361d025f Merge branch 'jk/stash-disable-renames-internally' into maint
When diff.renames configuration is on (and with Git 2.9 and later,
it is enabled by default, which made it worse), "git stash"
misbehaved if a file is removed and another file with a very
similar content is added.

* jk/stash-disable-renames-internally:
  stash: prefer plumbing over git-diff
2017-01-17 14:49:30 -08:00
Jeff King 9d4e28ead5 stash: prefer plumbing over git-diff
When creating a stash, we need to look at the diff between
the working tree and HEAD, and do so using the git-diff
porcelain.  Because git-diff enables porcelain config like
renames by default, this causes at least one problem. The
--name-only format will not mention the source side of a
rename, meaning we will fail to stash a deletion that is
part of a rename.

We could fix that case by passing --no-renames, but this is
a symptom of a larger problem. We should be using the
diff-index plumbing here, which does not have renames
enabled by default, and also does not respect any
potentially confusing config options.

Reported-by: Matthew Patey <matthew.patey2167@gmail.com>
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2016-12-06 14:16:53 -08:00
Aaron M Watson a56c8f5aab stash: allow stashes to be referenced by index only
Instead of referencing "stash@{n}" explicitly, make it possible to
simply reference as "n".  Most users only reference stashes by their
position in the stash stack (what I refer to as the "index" here).

The syntax for the typical stash (stash@{n}) is slightly annoying and
easy to forget, and sometimes difficult to escape properly in a
script. Because of this the capability to do things with the stash by
simply referencing the index is desirable.

This patch includes the superior implementation provided by Øsse Walle
(thanks for that), with a slight change to fix a broken test in the test
suite. I also merged the test scripts as suggested by Jeff King, and
un-wrapped the documentation as suggested by Junio Hamano.

Signed-off-by: Aaron M Watson <watsona4@gmail.com>
Reviewed-by: Jeff King <peff@peff.net>
2016-10-26 09:58:10 -07:00
David Turner d0ab058498 tests: remove some direct access to .git/logs
Alternate refs backends might store reflogs somewhere other than
.git/logs.  Change most test code that directly accesses .git/logs to
instead use git reflog commands.

There are still a few tests which need direct access to reflogs: to
check reflog permissions, to manually create reflogs from scratch, to
save/restore reflogs, to check the format of raw reflog data, and to
remove not just reflog contents, but the reflogs themselves. All cases
which don't need direct access have been modified.

Signed-off-by: David Turner <dturner@twopensource.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2015-07-28 11:46:46 -07:00
Junio C Hamano 351d06df51 Merge branch 'jk/stash-require-clean-index' into maint
A hotfix for the topic already in 'master'.

* jk/stash-require-clean-index:
  Revert "stash: require a clean index to apply"
2015-06-25 23:03:27 -07:00
Junio C Hamano 659d4c8fb2 Merge branch 'jk/stash-options' into maint
Make "git stash something --help" error out, so that users can
safely say "git stash drop --help".

* jk/stash-options:
  stash: recognize "--help" for subcommands
  stash: complain about unknown flags
2015-06-16 14:33:43 -07:00
Jeff King 19376104a8 Revert "stash: require a clean index to apply"
This reverts commit ed178ef13a.

That commit was an attempt to improve the safety of applying
a stash, because the application process may create
conflicted index entries, after which it is hard to restore
the original index state.

Unfortunately, this hurts some common workflows around "git
stash -k", like:

    git add -p       ;# (1) stage set of proposed changes
    git stash -k     ;# (2) get rid of everything else
    make test        ;# (3) make sure proposal is reasonable
    git stash apply  ;# (4) restore original working tree

If you "git commit" between steps (3) and (4), then this
just works. However, if these steps are part of a pre-commit
hook, you don't have that opportunity (you have to restore
the original state regardless of whether the tests passed or
failed).

It's possible that we could provide better tools for this
sort of workflow. In particular, even before ed178ef, it
could fail with a conflict if there were conflicting hunks
in the working tree and index (since the "stash -k" puts the
index version into the working tree, and we then attempt to
apply the differences between HEAD and the old working tree
on top of that). But the fact remains that people have been
using it happily for a while, and the safety provided by
ed178ef is simply not that great. Let's revert it for now.
In the long run, people can work on improving stash for this
sort of workflow, but the safety tradeoff is not worth it in
the meantime.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2015-06-15 13:11:17 -07:00
Jeff King d6cc2df5c8 stash: complain about unknown flags
The option parser for git-stash stuffs unknown flags into
the $FLAGS variable, where they can be accessed by the
individual commands. However, most commands do not even look
at these extra flags, leading to unexpected results like
this:

  $ git stash drop --help
  Dropped refs/stash@{0} (e6cf6d80faf92bb7828f7b60c47fc61c03bd30a1)

We should notice the extra flags and bail. Rather than
annotate each command to reject a non-empty $FLAGS variable,
we can notice that "stash show" is the only command that
actually _wants_ arbitrary flags. So we switch the default
mode to reject unknown flags, and let stash_show() opt into
the feature.

Reported-by: Vincent Legoll <vincent.legoll@gmail.com>
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2015-05-20 13:47:30 -07:00
Jeff King ed178ef13a stash: require a clean index to apply
If you have staged contents in your index and run "stash
apply", we may hit a conflict and put new entries into the
index. Recovering to your original state is difficult at
that point, because tools like "git reset --keep" will blow
away anything staged.  We can make this safer by refusing to
apply when there are staged changes.

It's possible we could provide better tooling here, as "git
stash apply" should be writing only conflicts to the index
(so we know that any stage-0 entries are potentially
precious). But it is the odd duck; most "mergy" commands
will update the index for cleanly merged entries, and it is
not worth updating our tooling to support this use case
which is unlikely to be of interest (besides which, we would
still need to block a dirty index for "stash apply --index",
since that case _would_ be ambiguous).

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2015-04-22 13:38:58 -07:00
Jeff King 88bab59c5b t3903: avoid applying onto dirty index
One of the tests in t3903 wants to make sure that applying a
stash that touches only "file" can still happen even if there
are working tree changes to "other-file". To do so, it adds
"other-file" to the index (since otherwise it is an
untracked file, voiding the purpose of the test).

But as we are about to refactor the dirty-index handling,
and as this test does not actually care about having a dirty
index (only a dirty working tree), let's bump the tracking
of "other-file" into the setup phase, so we can have _just_
a dirty working tree here.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2015-04-22 13:38:58 -07:00
Jeff King f2f3fc9547 t3903: stop hard-coding commit sha1s
When testing the diff output of "git stash list", we look
for the stash's subject of "WIP on master: $sha1", even
though it's not relevant to the diff output. This makes the
test brittle to refactoring, as any changes to earlier tests
may impact the commit sha1.

Since we don't care about the commit subject here, we can
simply ask stash not to print it.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2015-04-22 13:38:58 -07:00
Jeff King 288c67caf6 stash: default listing to working-tree diff
When you list stashes, you can provide arbitrary git-log
options to change the display. However, adding just "-p"
does nothing, because each stash is actually a merge commit.

This implementation detail is easy to forget, leading to
confused users who think "-p" is not working. We can make
this easier by defaulting to "--first-parent -m", which will
show the diff against the working tree. This omits the
index portion of the stash entirely, but it's simple and it
matches what "git stash show" provides.

People who are more clueful about stash's true form can use
"--cc" to override the "-m", and the "--first-parent" will
then do nothing. For diffs, it only affects non-combined
diffs, so "--cc" overrides it. And for the traversal, we are
walking the linear reflog anyway, so we do not even care
about the parents.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-08-07 14:37:28 -07:00
Øystein Walle 2a07e4374c stash: handle specifying stashes with $IFS
When trying to pop/apply a stash specified with an argument
containing IFS whitespace, git-stash will throw an error:

    $ git stash pop 'stash@{two hours ago}'
    Too many revisions specified: stash@{two hours ago}

This happens because word splitting is used to count non-option
arguments. Make use of rev-parse's --sq option to quote the arguments
for us to ensure a correct count. Add quotes where necessary.

Also add a test that verifies correct behaviour.

Helped-by: Thomas Rast <tr@thomasrast.ch>
Signed-off-by: Øystein Walle <oystwa@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-01-07 10:51:04 -08:00
Junio C Hamano c1ebd90c83 Revert "git stash: avoid data loss when "git stash save" kills a directory"
This reverts commit a73653130e, as it
has been reported that "ls-files --killed" is too time-consuming in
a deep directory with too many untracked crufts (e.g. $HOME/.git
tracking only a few files).

We'd need to revisit it later but "ls-files --killed" needs to be
optimized before it happens.
2013-08-14 09:53:43 -07:00
Petr Baudis a73653130e 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 <pasky@ucw.cz>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2013-07-01 14:23:24 -07:00
Junio C Hamano fa4bf9edb9 Merge branch 'rr/rebase-stash-store'
Finishing touches for the "git rebase --autostash" feature
introduced earlier.

* rr/rebase-stash-store:
  rebase: use 'git stash store' to simplify logic
  stash: introduce 'git stash store'
  stash: simplify option parser for create
  stash doc: document short form -p in synopsis
  stash doc: add a warning about using create
2013-06-27 14:29:41 -07:00