我想使用这个工作流:
进行一些改变。 将未分阶段的更改保存到存储中。 用阶段中的东西做一些事情(构建、测试等)。 提交。 恢复未分阶段的更改。
有办法完成第二步吗?
例子:
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
我想使用这个工作流:
进行一些改变。 将未分阶段的更改保存到存储中。 用阶段中的东西做一些事情(构建、测试等)。 提交。 恢复未分阶段的更改。
有办法完成第二步吗?
例子:
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
当前回答
我使用了一个别名,它接受一个字符串作为消息发送到存储条目。
mystash = "!f() { git commit -m hold && git stash push -m \"$1\" && git reset HEAD^; }; f"
哪一个:
提交索引中的所有内容, 将更改的内容存储在工作树中(当然可以添加-u或-a), 将最后一次提交重置回工作尝试(可能需要使用——soft将其保留在索引中)。
其他回答
没有阶段性变化的隐藏
——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.35+ (Q1 2022)开始,你现在可以在Git stash推送上使用——staging标志(man)来只stage你的索引的变化。
既然你的问题正好相反,我们有两个选择:
像这样反向操作:
git stash push --staged # Stash staged changes
git stash # Stash everything else
git stash pop stash@{1} # Restore staged changes stash
阶段性的更改是你想要保存的,而不是你想要保留的。现在你可以运行:
git stash push --staged
我从另一个S/O帖子的回答中得到了这个信息。
这是(在我看来)最好的解决方案,这完全符合OP的要求。它只存储未暂存的、被跟踪的文件——无需不必要的提交或使用——keep-index存储所有更改的文件
它列出了所有未分段的、跟踪的更改(git diff——name-only),将换行符转换为空格(| tr '\n' ' ' '),并使用git stash push存储所有这些文件:
git stash push $(git diff --name-only | tr '\n' ' ')
扩展前面的回答,我有时会有一组复杂的更改,但希望先提交一个单独的更改。例如,我可能发现了一个错误或其他不正确的代码,我想在进行阶段性更改之前修复它。一个可行的方法是:
首先把所有东西都藏起来,但保留阶段性的变化
$ git保存——keep-index[——include-untracked]
现在也将阶段性更改单独保存
$ git保存
为解决问题做出改变;和测试;提交:
$ git add[——interactive][——patch] $ git commit -m"fix…"
现在恢复之前的更改:
$ git隐藏pop
解决任何冲突,并注意如果存在冲突,git将应用而不是删除顶部的隐藏条目。
(…然后提交分阶段的更改,并恢复所有其他更改的存储,然后继续…)