我想使用这个工作流:
有办法完成第二步吗?
例子:
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 stash push有一个选项--keep-index,这正是你所需要的。
git stash push
--keep-index
因此,运行git stash push --keep-index。
git stash push --keep-index
git stash save --keep-index
此外,Re:
为什么不在提交更改之后提交它们呢?——心
答:因为你应该总是签入测试代码:)这意味着,你需要用只有您即将提交的更改运行测试
当然,作为一个有经验的程序员,你天生就有测试和检查这些更改的冲动——只是开玩笑的
扩展前面的回答,我有时会有一组复杂的更改,但希望先提交一个单独的更改。例如,我可能发现了一个错误或其他不正确的代码,我想在进行阶段性更改之前修复它。一个可行的方法是:
首先把所有东西都藏起来,但保留阶段性的变化
$ git保存——keep-index[——include-untracked]
现在也将阶段性更改单独保存
$ git保存
为解决问题做出改变;和测试;提交:
$ git add[——interactive][——patch] $ git commit -m"fix…;
$ git add[——interactive][——patch]
$ git commit -m"fix…;
现在恢复之前的更改:
$ git隐藏pop
解决任何冲突,并注意,如果有冲突,git将应用,但不删除了顶部的隐藏项。
(…然后提交分阶段的更改,并恢复所有其他更改的存储,然后继续…)
另一个建议,与这个问题有关:
当您使用
$ git stash save -keep-index
你可能希望给stash一个消息,这样当你执行git stash list时,它会更明显地显示你之前存储了什么,特别是当你在stash操作之后进一步保存时。例如
git stash list
$ git保存保存—keep-index“尚未进行更改”
(尽管实际上它确实包含了其他答案中提到的所有变化)。
例如,上面的语句之后可以立即加上:
$ git保存“功能X的阶段性变化”
不过要注意,你不能然后使用
$ git stash apply "stash@{1}" ###所以并不完全符合你的要求
只恢复未分阶段的变化。
这可以通过3个步骤完成:保存阶段性更改,保存所有其他内容,使用阶段性更改恢复索引。基本上就是:
git commit -m 'Save index' git stash push -u -m 'Unstaged changes and untracked files' git reset --soft HEAD^
这正是你想要的。
使用git version 2.7.4你可以做:
git version 2.7.4
git stash save --patch
git
y
n
你可以恢复工作目录,你总是这样做:
git stash pop
或者,如果你想在stash保存更改:
git stash apply
使用实例添加未分期(未添加到提交)的文件到stash。
git stash -k
如果你想将新添加的文件(不是阶段性的-不是绿色的)也包含到stash中,请执行以下操作:
git stash -k -u
然后可以提交暂存文件。在此之后,您可以使用命令返回最后存储的文件:
Git没有只存储未分阶段更改的命令。
但是,Git允许您指定要保存哪些文件。
git stash push --message 'Unstaged changes' -- app/controllers/products_controller.rb test/controllers/products_controller_test.rb
如果你只想在这些文件中保存特定的更改,可以添加--patch选项。
--patch
git stash push --patch --message 'Unstaged changes' -- app/controllers/products_controller.rb test/controllers/products_controller_test.rb
--include-untracked选项可以让你保存未跟踪的文件。
--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)获取更多信息。
git help stash
man git-stash
注意:如果你的非分阶段更改相当混乱,@alesguzik的回答可能更容易。
2022:我在&;__abc1 &;中提到,Git 2.35 (Q1 2022)带有&;__abc2 &;(man):
此选项仅对推送和保存命令有效。 仅保存当前暂存的更改。 这类似于基本的git commit,除了状态被提交到stash而不是当前分支
此选项仅对推送和保存命令有效。
仅保存当前暂存的更改。 这类似于基本的git commit,除了状态被提交到stash而不是当前分支
git commit
2019:该命令的现代形式是git stash push [--] [<pathspec>...],因为Git 2.16+ (git stash save已弃用)
git stash push [--] [<pathspec>...]
git stash save
你可以将其与通配符表单结合起来,例如:
git stash push --all --keep-index ':(glob)**/*.testextension'
但这并不适用于Windows Git,直到Git 2.22 (Q2 2019),参见发行2037,考虑git stash已在C中重新实现(而不是shell脚本)
git stash
参见提交7 db9302 (11 Mar 2019) by Thomas Gummerer (tgummerer)。 参见提交1366年c78, 提交7 b556aa (07 Mar 2019) by 约翰内斯·辛德林(dscho)。 (由Junio C Hamano—gitster—在提交0 ba1ba4中合并,22 Apr 2019)
tgummerer
dscho
gitster
内置的stash:再次处理:(glob)路径specs 当传递一个路径规格列表给,比如说git add时,我们需要 小心使用原始形式,而不是路径规格的解析形式 这很重要,比如打电话的时候 git stash -- ':(glob)**/*.txt' ,其中原始形式包括:(glob)前缀,而解析 然而,在内置的git stash中,我们传递了解析后的(即不正确的)表单,而git add将失败并返回错误消息: fatal: pathspec '**/*.txt' did not match any files 在git stash从工作树中删除更改的阶段,即使refs/stash实际上已经成功更新。
内置的stash:再次处理:(glob)路径specs
stash
:(glob)
git add
这很重要,比如打电话的时候
git stash -- ':(glob)**/*.txt'
,其中原始形式包括:(glob)前缀,而解析
然而,在内置的git stash中,我们传递了解析后的(即不正确的)表单,而git add将失败并返回错误消息:
fatal: pathspec '**/*.txt' did not match any files
在git stash从工作树中删除更改的阶段,即使refs/stash实际上已经成功更新。
refs/stash
我使用了一个别名,它接受一个字符串作为消息发送到存储条目。
mystash = "!f() { git commit -m hold && git stash push -m \"$1\" && git reset HEAD^; }; f"
哪一个:
-u
-a
--soft
-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作为别名参数传递),然后重置临时提交以获得分阶段的更改。
--message
它类似于@Simon Knapp的回答,但有一些小的区别——它对所采取的临时操作使用--quiet,并且它接受存储push的任意数量的参数,而不是硬编码-m,并且它确实将--soft添加到最终重置中,以便索引保持它开始时的状态。它还在提交时使用--no-verify,以避免通过提交前钩子(HT: @Granfalloner)对工作副本进行更改。
--quiet
push
-m
--no-verify
关于只存储阶段性变化(别名stash-index)的相反问题,请参阅这个答案。
stash-index
据我所知,目前不可能用git stash push在工作树中保存只有的未分阶段更改,即保存从索引状态的更改。该命令保存工作树中的所有更改(分阶段和非分阶段更改),即更改--keep-index0,即使使用选项--keep-index1将工作树状态设置为索引状态而不是HEAD状态(因此在用git stash pop从HEAD状态恢复更改时产生冲突)。如果git stash push有一个选项-U|--unstaged,只保存非阶段性更改(对我来说,选项--keep-index是有缺陷的),这将是非常方便的,因为它已经有一个选项-S|--staged,只保存阶段性更改。
-U|--unstaged
-S|--staged
所以现在你必须模仿
git stash push --unstaged git stash pop
使用临时文件:
git diff >unstaged git restore . git apply unstaged rm unstaged
你的用例是在提交部分更改之前进行测试,它已经在参考文档中,但是有缺陷的选项--keep-index会产生冲突。下面是带有模拟选项-U|--unstaged的版本:
git init echo one >file git add file git commit echo two >>file git add file echo three >>file git diff >unstaged git restore . test git commit git apply unstaged rm unstaged
为了更好地理解存储,我认为在每一步查看工作树、索引和HEAD的状态是很重要的。让我们看看你的用例。
git init
echo one >file
git add file
echo two >>file
echo three >>file
git diff >unstaged
git restore .
test
git apply unstaged
rm unstaged
这是(在我看来)最好的解决方案,这完全符合OP的要求。它只存储未暂存的、跟踪的文件——没有不必要的提交,也没有使用--keep-index存储所有更改的文件
它列出了所有未分段的、跟踪的更改(git diff --name-only),将换行符转换为空格符(| tr '\n' ' '),并使用git stash push存储所有这些文件:
git diff --name-only
| tr '\n' ' '
git stash push $(git diff --name-only | tr '\n' ' ')
从Git 2.35+ (Q1 2022)开始,你现在可以在git stash push上使用--staged标志(男人。)来只进行在你的索引中的更改。
--staged
既然你的问题正好相反,我们有两个选择:
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帖子的这个答案中得到了这个信息。
pre-commit
它在功能上等同于:
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
重新思考:没有必要只将存储数据限制在工作树更改上,但是可以稍后在应用时决定只应用存储的工作树更改。
因此,在储存时间,只要像往常一样做:
git stash [-k|--keep-index]
在申请的时候
git cherry-pick -m2 -n stash
解释:-m2选择对阶段提交的第二个父元素的更改,这是存储的索引状态。-n|--no-commit阻止自动提交。stash@{1}将是堆栈中第二个藏物的ref…
-m2
-n|--no-commit
stash@{1}