git/list[1] front-page[2] threads[3] people[4] search[5] about
 

Re: Better cooperation between checkouts and stashing

From
Michael Witten <mfwitten@gmail.com>
Date
Mar 1, 2010, 18:14 UTC
Message-ID
<4b8c0420.5544f10a.2eb2.ffffb4c4@mx.google.com>
In-Reply-To
<7v1vg4ufas.fsf@alter.siamese.dyndns.org>
On Mon, Mar 1, 2010 at 11:23, Junio C Hamano <gitster@pobox.com> wrote:
> Your "checkout" needs a bit better error checking.  For example, you
> don't want to "reset --hard" when stash failed for whatever reason.
Yes, you are correct.

However, in my defense, the goal was just to illustrate the gist of the desired functionality.

Show 16 quoted lines
> For performance and cleanliness reasons, it should first try a branch
> switch, and only after seeing it fail due to local changes, perform your
> stash-unstash magic.  You would probably want to use the usual "stash
> save", as you will be consuming the stashed change yourself as its first
> user, and "pop" will clear it if things resolve cleanly, or the stash will
> be left as the first element to make it easy to re-attempt the conflict
> resolution.  No need for stash-id nor special casing of detached HEAD
> situation.
>
> And it should do all that only under "-m" option, i.e. when the user
> indicated that s/he is willilng to face conflict resolution while
> switching.  That would be a genuine improvement compared to the current
> system (and I suspect it would be easier to implement).  "checkout -m" so
> far has been as bad as "CVS/SVN update" in that it can get you into an
> unresolvable mess without a chance to go back and retry.  autostash will
> remedy that.

You've still got the wrong problem in your head (though you're solving a more useful issue).

Markus Elfring's goal (I think) is to associate local modifications with a particular branch, *not* carry them across branches; that is, the goal is to stash local modifications away when we leave a branch and only pop them off the stash when we RETURN to that same branch.

Here's an example using the previously defined custom `checkout' function (don't bother trying to follow the file modifications exactly; what's important is how the stash is used during `checkout'):

  $ git init repo
  Initialized empty Git repository in /home/michael/repo/.git/
  $ cd repo
  $ echo 0 > file_0
  $ git add file_0
  $ git commit -m 0
  [master (root-commit) 26ea762] 0
   1 files changed, 1 insertions(+), 0 deletions(-)
   create mode 100644 file_0
  $ echo 1 > file_1
  $ git add file_1
  $ git commit -m 1
  [master 2faaa55] 1
   1 files changed, 1 insertions(+), 0 deletions(-)
   create mode 100644 file_1
  $ echo 2 > file_0
  $ echo 3 > file_1
  $ git add file_1
  $ git branch branch
  $ checkout branch               # Note: That's the custom 'checkout'
  Switched to branch 'branch'
  $ git stash list | cat
  stash@{0}: On master: e2f0bfbd9de98acd4941a1842e4bc55f
  $ echo 4 > file_0
  $ checkout HEAD^
  Note: checking out 'HEAD^'.
  
  You are in 'detached HEAD' state. You can look around, make experimental
  changes and commit them, and you can discard any commits you make in this
  state without impacting any branches by performing another checkout.
  
  If you want to create a new branch to retain commits you create, you may
  do so (now or later) by using -b with the checkout command again. Example:
  
    git checkout -b new_branch_name
  
  HEAD is now at 26ea762... 0
  $ git stash list | cat
  stash@{0}: On branch: 3e4d8fe5cbdcf73b9272ad21b4510424
  stash@{1}: On master: e2f0bfbd9de98acd4941a1842e4bc55f
  $ echo 5 > file_0 
  $ checkout master
  HEAD is now at 26ea762 0
  Previous HEAD position was 26ea762... 0
  Switched to branch 'master'
  # On branch master
  # Changes to be committed:
  #   (use "git reset HEAD <file>..." to unstage)
  #
  #	modified:   file_1
  #
  # Changed but not updated:
  #   (use "git add <file>..." to update what will be committed)
  #   (use "git checkout -- <file>..." to discard changes in working directory)
  #
  #	modified:   file_0
  #
  Dropped stash@{1} (6871afd660a5814a1caffe5275a9c145dba3c85a)
  $ git stash list | cat
  stash@{0}: On branch: 3e4d8fe5cbdcf73b9272ad21b4510424
  $ checkout branch
  Switched to branch 'branch'
  # On branch branch
  # Changed but not updated:
  #   (use "git add <file>..." to update what will be committed)
  #   (use "git checkout -- <file>..." to discard changes in working directory)
  #
  #	modified:   file_0
  #
  no changes added to commit (use "git add" and/or "git commit -a")
  Dropped stash@{1} (f6ecf1ceed97c760cb2b3279bbb39fc1cd16f052)
  $ git stash list | cat
  stash@{0}: On master: e2f0bfbd9de98acd4941a1842e4bc55f
  $ checkout master
  Switched to branch 'master'
  # On branch master
  # Changes to be committed:
  #   (use "git reset HEAD <file>..." to unstage)
  #
  #	modified:   file_1
  #
  # Changed but not updated:
  #   (use "git add <file>..." to update what will be committed)
  #   (use "git checkout -- <file>..." to discard changes in working directory)
  #
  #	modified:   file_0
  #
  Dropped stash@{1} (46a64d63441a924d9684c8a733a9fae4c7aa4b92)
  $ git stash list | cat
  stash@{0}: On branch: 3e4d8fe5cbdcf73b9272ad21b4510424
  $ git diff | cat
  diff --git a/file_0 b/file_0
  index 573541a..0cfbf08 100644
  --- a/file_0
  +++ b/file_0
  @@ -1 +1 @@
  -0
  +2
  $ git diff --staged | cat
  diff --git a/file_1 b/file_1
  index d00491f..00750ed 100644
  --- a/file_1
  +++ b/file_1
  @@ -1 +1 @@
  -1
  +3
etc.
Previous: Junio C HamanoNext: Markus Elfring
Message 20 of 56 in “Better cooperation between checkouts and stashing”
  1. Markus ElfringFeb 1, 2010
  2. Junio C HamanoFeb 1, 2010
  3. Markus ElfringFeb 1, 2010
  4. Eugene SajineFeb 1, 2010
  5. Petr BaudisFeb 2, 2010
  6. Markus ElfringFeb 2, 2010
  7. Petr BaudisFeb 2, 2010
  8. Markus ElfringFeb 9, 2010
  9. Junio C HamanoFeb 9, 2010
  10. Markus ElfringFeb 9, 2010
  11. Markus ElfringFeb 18, 2010
  12. Junio C HamanoFeb 18, 2010
  13. Markus ElfringFeb 27, 2010
  14. Junio C HamanoFeb 27, 2010
  15. Markus ElfringFeb 28, 2010
  16. Michael WittenFeb 28, 2010
  17. Markus ElfringMar 1, 2010
  18. Michael WittenMar 1, 2010
  19. Junio C HamanoMar 1, 2010
  20. Michael WittenMar 1, 2010
  21. Markus ElfringMar 1, 2010
  22. Junio C HamanoMar 1, 2010
  23. Markus ElfringMar 1, 2010
  24. Michael WittenMar 2, 2010
  25. Markus ElfringMar 2, 2010
  26. Junio C HamanoMar 2, 2010
  27. Markus ElfringMar 3, 2010
  28. Michael WittenMar 4, 2010
  29. Markus ElfringMar 4, 2010
  30. Markus ElfringMar 2, 2010
  31. Junio C HamanoMar 2, 2010
  32. Markus ElfringMar 3, 2010
  33. Markus ElfringMar 17, 2010
  34. Avery PennarunMar 17, 2010
  35. Markus ElfringMar 17, 2010
  36. Junio C HamanoMar 17, 2010
  37. Markus ElfringMar 17, 2010
  38. Junio C HamanoMar 17, 2010
  39. Michael WittenMar 17, 2010
  40. Junio C HamanoMar 17, 2010
  41. Markus ElfringMar 18, 2010
  42. Avery PennarunMar 18, 2010
  43. Michael WittenMar 18, 2010
  44. Avery PennarunMar 18, 2010
  45. Markus ElfringMar 19, 2010
  46. Avery PennarunMar 19, 2010
  47. Markus ElfringMar 20, 2010
  48. Markus ElfringMar 19, 2010
  49. Markus ElfringMar 30, 2010
  50. Junio C HamanoMar 30, 2010
  51. Ramkumar RamachandraMar 31, 2010
  52. Junio C HamanoApr 1, 2010
  53. Ramkumar RamachandraApr 1, 2010
  54. Markus ElfringApr 1, 2010
  55. Markus ElfringApr 10, 2010
  56. Junio C HamanoApr 10, 2010

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.