1. 08 Jan, 2018 1 commit
    • Thomas Gummerer's avatar
      stash: don't delete untracked files that match pathspec · bba067d2
      Thomas Gummerer authored
      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 (df6bba09 ("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: default avatarReid Price <reid.price@gmail.com>
      Helped-by: default avatarJunio C Hamano <gitster@pobox.com>
      Signed-off-by: default avatarThomas Gummerer <t.gummerer@gmail.com>
      Signed-off-by: default avatarJunio C Hamano <gitster@pobox.com>
      bba067d2
  2. 24 Nov, 2017 1 commit
    • Phil Hord's avatar
      stash: learn to parse -m/--message like commit does · 5675473f
      Phil Hord authored
      `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's avatarPhil Hord <phil.hord@gmail.com>
      Signed-off-by: default avatarJunio C Hamano <gitster@pobox.com>
      5675473f
  3. 27 Oct, 2017 2 commits
    • Thomas Gummerer's avatar
      stash: remove now superfluos help for "stash push" · c0c0c825
      Thomas Gummerer authored
      With the 'git stash save' interface, it was easily possible for users to
      try to add a message which would start with "-", which 'git stash save'
      would interpret as a command line argument, and fail.  For this case we
      added some extra help on how to create a stash with a message starting
      with "-".
      
      For 'stash push', messages are passed with the -m flag, avoiding this
      potential pitfall.  Now only pathspecs starting with "-" would have to
      be distinguished from command line parameters by using
      "-- --<pathspec>".  This is fairly common in the git command line
      interface, and we don't try to guess what the users wanted in the other
      cases.
      
      Because this way of passing pathspecs is quite common in other git
      commands, and we don't provide any extra help there, do the same in the
      error message for 'git stash push'.
      Signed-off-by: default avatarThomas Gummerer <t.gummerer@gmail.com>
      Signed-off-by: default avatarJunio C Hamano <gitster@pobox.com>
      c0c0c825
    • Thomas Gummerer's avatar
      stash: replace "git stash save" with "git stash push" in the documentation · db37745e
      Thomas Gummerer authored
      "git stash push" is the newer interface for creating a stash.  While we
      are still keeping "git stash save" around for the time being, it's better
      to point new users of "git stash" to the more modern (and more feature
      rich) interface, instead of teaching them the older version that we
      might want to phase out in the future.
      Signed-off-by: default avatarThomas Gummerer <t.gummerer@gmail.com>
      Signed-off-by: default avatarJunio C Hamano <gitster@pobox.com>
      db37745e
  4. 14 Aug, 2017 1 commit
    • Kevin Daudt's avatar
      stash: prevent warning about null bytes in input · 5fc92f88
      Kevin Daudt authored
      The `no_changes` function calls the `untracked_files` function through
      command substitution. `untracked_files` will return null bytes because it
      runs ls-files with the '-z' option.
      
      Bash since version 4.4 warns about these null bytes. As they are not
      required for the test that is being done, make sure `untracked_files`
      does not output null bytes when not required.
      
      This is achieved by adding a parameter to the `untracked_files` function to
      specify wither `-z` should be passed to ls-files or not.
      
      This warning is triggered when running git stash save -u resulting in
      two warnings:
      
          git-stash: line 43: warning: command substitution: ignored null byte
          in input
      Signed-off-by: default avatarKevin Daudt <me@ikke.info>
      Signed-off-by: default avatarJunio C Hamano <gitster@pobox.com>
      5fc92f88
  5. 11 Aug, 2017 1 commit
  6. 07 Aug, 2017 1 commit
  7. 19 Jun, 2017 1 commit
  8. 13 Jun, 2017 1 commit
    • Patrick Steinhardt's avatar
      git-stash: fix pushing stash with pathspec from subdir · 22fc703e
      Patrick Steinhardt authored
      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: default avatarPatrick Steinhardt <ps@pks.im>
      Signed-off-by: default avatarJunio C Hamano <gitster@pobox.com>
      22fc703e
  9. 22 Mar, 2017 3 commits
  10. 28 Feb, 2017 3 commits
  11. 20 Feb, 2017 2 commits
  12. 06 Dec, 2016 1 commit
    • Jeff King's avatar
      stash: prefer plumbing over git-diff · 9d4e28ea
      Jeff King authored
      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: default avatarMatthew Patey <matthew.patey2167@gmail.com>
      Signed-off-by: default avatarJeff King <peff@peff.net>
      Signed-off-by: default avatarJunio C Hamano <gitster@pobox.com>
      9d4e28ea
  13. 26 Oct, 2016 1 commit
    • Aaron M Watson's avatar
      stash: allow stashes to be referenced by index only · a56c8f5a
      Aaron M Watson authored
      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: default avatarAaron M Watson <watsona4@gmail.com>
      Reviewed-by: default avatarJeff King <peff@peff.net>
      a56c8f5a
  14. 21 Sep, 2016 1 commit
  15. 10 Aug, 2016 1 commit
  16. 17 Jun, 2016 1 commit
  17. 14 May, 2016 1 commit
    • Jeff King's avatar
      always quote shell arguments to test -z/-n · 268ef4d3
      Jeff King authored
      In shell code like:
      
        test -z $foo
        test -n $foo
      
      that does not quote its arguments, it's easy to think that
      it is actually looking at the contents of $foo in each case.
      But if $foo is empty, then "test" does not see any argument
      at all! The results are quite subtle.
      
      POSIX specifies that test's behavior depends on the number
      of arguments it sees, and if $foo is empty, it sees only
      one. The behavior in this case is:
      
        1 argument: Exit true (0) if $1 is not null; otherwise,
                    exit false.
      
      So in the "-z $foo" case, if $foo is empty, then we check
      that "-z" is non-null, and it returns success. Which happens
      to match what we expected.  But for "-n $foo", if $foo is
      empty, we'll see that "-n" is non-null and still return
      success. That's the opposite of what we intended!
      
      Furthermore, if $foo contains whitespace, we'll end up with
      more than 2 arguments. The results in this case are
      generally unspecified (unless the first part of $foo happens
      to be a valid binary operator, in which case the results are
      specified but certainly not what we intended).
      
      And on top of this, even though "test -z $foo" _should_ work
      for the empty case, some older shells (reportedly ksh88)
      complain about the missing argument.
      
      So let's make sure we consistently quote our variable
      arguments to "test". After this patch, the results of:
      
        git grep 'test -[zn] [^"]'
      
      are empty.
      Reported-by: default avatarArmin Kunaschik <megabreit@googlemail.com>
      Helped-by: default avatarJunio C Hamano <gitster@pobox.com>
      Signed-off-by: default avatarJeff King <peff@peff.net>
      Signed-off-by: default avatarJunio C Hamano <gitster@pobox.com>
      268ef4d3
  18. 31 Aug, 2015 1 commit
  19. 21 Jul, 2015 1 commit
  20. 15 Jun, 2015 1 commit
    • Jeff King's avatar
      Revert "stash: require a clean index to apply" · 19376104
      Jeff King authored
      This reverts commit ed178ef1.
      
      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 ed178ef1, 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
      ed178ef1 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: default avatarJeff King <peff@peff.net>
      Signed-off-by: default avatarJunio C Hamano <gitster@pobox.com>
      19376104
  21. 20 May, 2015 2 commits
    • Jeff King's avatar
      stash: recognize "--help" for subcommands · 5ba28313
      Jeff King authored
      If you run "git stash --help", you get the help for stash
      (this magic is done by the git wrapper itself). But if you
      run "git stash drop --help", you get an error. We
      cannot show help specific to "stash drop", of course, but we
      can at least give the user the normal stash manpage.
      Signed-off-by: default avatarJeff King <peff@peff.net>
      Signed-off-by: default avatarJunio C Hamano <gitster@pobox.com>
      5ba28313
    • Jeff King's avatar
      stash: complain about unknown flags · d6cc2df5
      Jeff King authored
      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: default avatarVincent Legoll <vincent.legoll@gmail.com>
      Signed-off-by: default avatarJeff King <peff@peff.net>
      Signed-off-by: default avatarJunio C Hamano <gitster@pobox.com>
      d6cc2df5
  22. 22 Apr, 2015 1 commit
    • Jeff King's avatar
      stash: require a clean index to apply · ed178ef1
      Jeff King authored
      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: default avatarJeff King <peff@peff.net>
      Signed-off-by: default avatarJunio C Hamano <gitster@pobox.com>
      ed178ef1
  23. 01 Dec, 2014 2 commits
  24. 19 Sep, 2014 1 commit
  25. 02 Sep, 2014 1 commit
  26. 07 Aug, 2014 1 commit
    • Jeff King's avatar
      stash: default listing to working-tree diff · 288c67ca
      Jeff King authored
      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: default avatarJeff King <peff@peff.net>
      Signed-off-by: default avatarJunio C Hamano <gitster@pobox.com>
      288c67ca
  27. 23 May, 2014 1 commit
  28. 23 Apr, 2014 1 commit
  29. 26 Feb, 2014 1 commit
  30. 07 Jan, 2014 1 commit
  31. 14 Aug, 2013 1 commit
  32. 01 Jul, 2013 1 commit
    • Petr Baudis's avatar
      git stash: avoid data loss when "git stash save" kills a directory · a7365313
      Petr Baudis authored
      "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's avatarPetr Baudis <pasky@ucw.cz>
      Signed-off-by: default avatarJunio C Hamano <gitster@pobox.com>
      a7365313