我想使用这个工作流:

进行一些改变。 将未分阶段的更改保存到存储中。 用阶段中的东西做一些事情(构建、测试等)。 提交。 恢复未分阶段的更改。

有办法完成第二步吗?

例子:

git init
echo one >file
git add file
git commit
echo two >>file
git add file
echo three >>file
git stash push
test
git commit
git stash pop

当前回答

没有阶段性变化的隐藏

——keep-index / -k的问题

在Git中只存储工作树(非阶段性更改)比它应该做的要困难得多。接受的答案,以及其他一些答案,将存储非阶段的更改,并按照请求通过——keep-index离开阶段。

然而,不明显的是——keep-index还存储了分阶段的更改。阶段性的更改最终同时存在于阶段和存储中。这很少是人们想要的,因为对隐藏的任何临时更改都可能在稍后弹出隐藏时导致冲突。

别名解决方案

这个别名可以很好地执行工作副本更改:

stash-working = "!f() { \
  git commit --quiet --no-verify -m \"temp for stash-working\" && \
  git stash push \"$@\" && \
  git reset --quiet --soft HEAD~1; }; f"

它临时提交分阶段的更改,从剩余的更改中创建一个隐藏(并允许额外的参数,如——include-untracked和——message作为别名参数传递),然后重置临时提交以获得分阶段的更改。

它类似于@Simon Knapp的答案,但有一些小的区别——它在所采取的临时操作上使用——quiet,它接受任意数量的参数用于stash推送,而不是硬编码-m,它确实在最终重置中添加——soft,以便索引保持它开始时的状态。它还在提交时使用——no-verify来避免来自预提交钩子(HT: @Granfalloner)对工作副本的更改。

关于只存储阶段性更改的相反问题(别名stash-index),请参阅此答案。

其他回答

另一个建议,与这个问题有关:

当您使用

$ git stash save -keep-index

你可能希望给stash一个消息,这样当你做一个git隐藏列表时,它会更明显地显示你之前隐藏了什么,特别是当你跟随stash操作进一步保存时。例如

$ git保存保存—keep-index“尚未进行更改”

(尽管实际上它确实包含了其他答案中提到的所有变化)。

例如,上面的语句之后可以立即加上:

$ git保存“功能X的阶段性变化”

但是要注意,你不能使用它

$ git stash apply "stash@{1}" ###所以并不完全符合你的要求

只恢复未分阶段的变化。

在git 2.7.4版本中,你可以:

git stash save --patch

git会问你是否添加你的更改到stash。 然后你只需回答y或n

你可以恢复工作目录,你总是这样做:

git stash pop

或者,如果你想在stash保存更改:

git stash apply

我对Python程序如何预提交感兴趣。这是代码。 https://github.com/pre-commit/pre-commit/blob/3fe38dff05957f609cf7b97f471b35a8d9e0659a/pre_commit/staged_files_only.py#L50

它在功能上等同于:

git diff-index --ignore-submodules --binary --exit-code --no-color --no-ext-diff $(git write-tree) -- >stash.patch
git checkout -- .

# Do stuff now

git apply stash.patch && rm stash.patch

这可以通过3个步骤完成:保存阶段性更改,保存所有其他内容,使用阶段性更改恢复索引。基本上就是:

git commit -m 'Save index'
git stash push -u -m 'Unstaged changes and untracked files'
git reset --soft HEAD^

这正是你想要的。

Git没有只存储未分阶段更改的命令。

但是,Git允许您指定要保存哪些文件。

git stash push --message 'Unstaged changes' -- app/controllers/products_controller.rb test/controllers/products_controller_test.rb

如果您只想在这些文件中保存特定的更改,请添加——patch选项。

git stash push --patch --message 'Unstaged changes' -- app/controllers/products_controller.rb test/controllers/products_controller_test.rb

——include-untracked选项允许你隐藏未跟踪的文件。

git stash push --include-untracked --message 'Untracked files' -- app/controllers/widgets_controller.rb test/controllers/widgets_controller_test.rb

运行git help stash(或man git-stash)获取更多信息。

注意:如果您的未分阶段更改相当混乱,@alesguzik的答案可能更简单。