你怎么告诉git只存储索引?

Mal*_*ous 58 git

我刚刚使用"git add -p"为索引添加了一堆更改,我才意识到我错过了一个应该进入上一次提交的更改.

我现在不能提交--amend因为我已经将所有这些新的更改添加到索引中,并且我不想使用'git reset'将它们全部从索引中删除,因为它需要很长时间才能添加它们又回来了.

我需要的是像'git stash'这样只会隐藏索引的东西 - 它应该只保留工作文件.然后我可以存储索引,添加缺少的更改,提交它,然后弹出存储并使我的索引恢复原样.

它看起来不像'git stash'能够做到这一点,但我错过了什么吗?谢谢!

use*_*170 35

从版本2.35 开始,git在子命令中提供了选项--stagedgit stash push

-S
--staged

push该选项仅对和命令有效save

仅存储当前正在进行的更改。这与基本类似git commit,只是状态被提交到存储而不是当前分支。

--patch选项优先于该选项。

  • 索引的同义词列表不断增长:我们现在有使用“--cached”来指示索引的命令,有些命令只是将其称为“--index”(包括带有“--keep-”的“git stash”)索引`)和`--staged`。 (3认同)

Lei*_*ldt 31

我发现的最接近的是git stash --patch.它将引导您完成对工作树和索引的每个更改,以便您选择要存储的内容.

http://www.kernel.org/pub/software/scm/git/docs/git-stash.html

  • 这对我来说在合并冲突中不起作用。我得到一堆“需要合并”文件,然后: fatal: git-write-tree: 构建树时出错无法保存当前索引状态 (2认同)
  • 谢谢,这太棒了,我认为 stash 只能保存所有文件,这对我的工作流程来说是一个很大的改进 (2认同)

Lil*_*ard 23

最简单的方法是立即取消该更改,进行新的提交,然后创建第二个提交,只需要使用该更改进行修改,然后使用git rebase -i原始HEAD压缩它.

另一种方法是进行提交,标记,回滚git reset HEAD^,添加一个更改并修改HEAD,然后挑选标记的提交.


dol*_*ver 18

解决方案1:

为什么不作弊?

git stash --keep-index
Run Code Online (Sandbox Code Playgroud)

把目前没有在索引中的所有东西都拿走了.然后,

git stash
Run Code Online (Sandbox Code Playgroud)

只收集上演的东西.

git stash pop
Run Code Online (Sandbox Code Playgroud)

第一个存储,添加您的更改.然后,

git commit --amend ...
git reset --hard
Run Code Online (Sandbox Code Playgroud)

然后清理工作树

git stash pop --index
Run Code Online (Sandbox Code Playgroud)

将索引更改回来.

  • 如果你有很多变化,这是相当可怕的。您只需要保存和恢复索引,[正如我在此处的回答中所做的那样](/sf/answers/4264814711/)。 (4认同)

use*_*062 10

使用autosquash提交索引,创建修正提交和rebase:

git commit
git add -p                         # add the change forgotten from HEAD^
git commit --fixup HEAD^           # commits with "fixup! <commit message of HEAD^>"
git rebase --autosquash -i HEAD~3
Run Code Online (Sandbox Code Playgroud)

  • 但我发现这个更容易理解。 (2认同)

LeG*_*GEC 10

git stash 实际上是使用索引内容创建提交,然后添加一个提交,其中包含所有跟踪文件的内容

要查看此内容:创建一个存储,然后运行

git log --oneline --graph stash@{0}
Run Code Online (Sandbox Code Playgroud)

所以从技术上讲,当你藏匿时,你可以通过stash@{0}^2以下方式获取索引:

$ git show --name-only stash@{0}^2
$ git checkout stash@{0}^2 -- .
Run Code Online (Sandbox Code Playgroud)

您还可以存储,然后获取已跟踪但未添加的文件的内容:

# get the diff between what was indexed and the full stashed content :
$ git diff -p stash@{0}^2 stash@{0}  >  diff.patch
# apply this diff :
$ git apply diff.patch
Run Code Online (Sandbox Code Playgroud)

  • 您还可以使用`git stash apply --index`返回索引,然后可选地使用`git checkout丢弃其他所有内容. (3认同)

小智 9

这里的大多数答案都相当复杂、危险,或者并不适用于所有情况。由于有很多“正在进行的”更改(在索引和工作树中),我什至不想考虑硬重置、隐藏、过早提交每个更改只是为了使其恢复生机或其他任何事情那应该有效。我唯一想做的就是更改索引本身。

幸运的是,有一个简单的方法可以做到这一点!

git diff --cached > 1.diff
git reset
# add and commit changes that should be separate
git apply --cached 1.diff
Run Code Online (Sandbox Code Playgroud)

现在你就拥有了!将当前索引保存为差异,重置它,添加并提交单独的更改,然后将更改重新应用到您保存的索引。

如果您想要分离的更改已应用于索引(并且您不想费心删除它们),则必须git reset HEAD^先使用一个附加更改git apply才能将索引重置为您执行操作时的状态差异。否则,补丁将不会再次应用(因为它已经在您的提交中应用),并且git绝对拒绝部分应用补丁。

  • 如果索引和工作树中的现有更改足够独立,重置不会妨碍您识别要在第 3 行提交的更改的能力,则效果很好。 (2认同)

小智 6

这似乎有效.我没有在所有情况下测试它以确保它是健壮的:

git commit -m _stash && git stash && git reset HEAD^ && git stash save  && git stash pop stash@{1}
Run Code Online (Sandbox Code Playgroud)

但是,它有效地临时提交索引,存储工作目录,恢复提交以获取索引,将其保存为另一个存储,然后从存储中再次恢复原始工作目录.

将其添加为git别名可以简化这一过程:

[alias]
    istash = "!f() { git commit -m _stash && git stash && git reset HEAD^ && git stash save $1 && git stash pop stash@{1}; }; f"
Run Code Online (Sandbox Code Playgroud)

这允许我使用它像:

git istash [optional stash name]
Run Code Online (Sandbox Code Playgroud)

  • 这是有问题的,如果有新文件添加到索引中,会产生奇怪的结果。 (2认同)

ima*_*son 5

magcs for emacs允许您使用命令magit-stash-index执行此操作