如何在我的分支中只存储多个已更改文件中的一个?


当前回答

有时,我在提交分支之前对其进行了不相关的更改,我想将其移动到另一个分支并单独提交(如master)。我这样做:

git stash
git checkout master
git stash pop
git add <files that you want to commit>
git commit -m 'Minor feature'
git stash
git checkout topic1
git stash pop
...<resume work>...

请注意,第一个stash和stash pop可以取消,您可以在结账时将所有更改转移到主分支,但前提是没有冲突。此外,如果您要为部分更改创建新分支,则需要隐藏。

假设没有冲突和新分支,您可以简化它:

git checkout master
git add <files that you want to commit>
git commit -m 'Minor feature'
git checkout topic1
...<resume work>...

甚至不需要Stash。。。

其他回答

VonC将文件复制到Git存储库外部的“中间”解决方案的问题是,您会丢失路径信息,这使得稍后将一堆文件复制回来有些麻烦。

A发现使用tar(类似的工具可能会这样做)而不是复制更容易:

tar cvf/tmp/stash.tar路径/to/some/file路径/to/some/other/file(…等)git签出路径/to/some/file-path/to/some/other/file暂存tar xvf/tmp/stash.tar等等(见VonC的“中间”建议)

git stash push -p -m "my commit message"

-p让我们选择应该隐藏的大块;也可以选择整个文件。

系统将提示您对每个大块执行一些操作:

   y - stash this hunk
   n - do not stash this hunk
   q - quit; do not stash this hunk or any of the remaining ones
   a - stash this hunk and all later hunks in the file
   d - do not stash this hunk or any of the later hunks in the file
   g - select a hunk to go to
   / - search for a hunk matching the given regex
   j - leave this hunk undecided, see next undecided hunk
   J - leave this hunk undecided, see next hunk
   k - leave this hunk undecided, see previous undecided hunk
   K - leave this hunk undecided, see previous hunk
   s - split the current hunk into smaller hunks
   e - manually edit the current hunk
   ? - print help

免责声明:以下答案适用于2.13之前的git。对于2.13及以上的数字,请查看下面的另一个答案。


警告

正如评论中所指出的那样,这将所有的东西都放进了储藏室,无论是暂存的还是未暂存的。--keep索引只是在存储完成后保留索引。这可能会在以后弹出存储时导致合并冲突。


这将隐藏您以前未添加的所有内容。只需git添加要保留的内容,然后运行它。

git stash --keep-index

例如,如果要将旧提交拆分为多个变更集,可以使用以下过程:

gitrebase-i<最后一次提交>将某些更改标记为编辑。git重置HEAD^git add<您要在此更改中保留的文件>git stash—保留索引必要时修理一下。不要忘记git添加任何更改。git提交吉特藏弹根据需要,从第5步开始重复。git rebase—继续

自Git 2.13(2017年第二季度)以来,您可以使用Git stash推送来存储单个文件:

git stash push [-m <message>] [--] [<pathspec>...]

当路径规范被赋予“git stash push”时,新的stash只记录与路径规范匹配的文件的修改状态有关详细信息,请参阅“Stash changes to specific files”。

简化示例:

 git stash push path/to/file

此功能的测试用例显示了更多选项:

test_expect_success 'stash with multiple pathspec arguments' '
    >foo &&
    >bar &&
    >extra &&
    git add foo bar extra &&

    git stash push -- foo bar &&   

    test_path_is_missing bar &&
    test_path_is_missing foo &&
    test_path_is_file extra &&

    git stash pop &&
    test_path_is_file foo &&
    test_path_is_file bar &&
    test_path_is_file extra

最初的答案(下图,2010年6月)是关于手动选择你想要隐藏的东西。

Casebash注释:

这(隐藏的补丁原始解决方案)很好,但我经常修改很多文件,所以使用补丁很烦人

bukzor的回答(2011年11月投票通过)提出了一个更实际的解决方案,基于git add+git stash--保留索引。去看看并投票给他的答案,这应该是官方的答案(而不是我的答案)。

关于该选项,chhh在评论中指出了另一种工作流:

你应该在这样一个隐藏之后“git-reset-soft”,以获得清晰的分段:为了达到原始状态-这是一个清晰的暂存区,只有一些选择的未暂存修改,可以轻轻地重置索引以获取(而不需要像bukzor那样提交任何操作)。


(原答案2010年6月:手动储存)

然而,git-stash-save补丁可以让你实现你想要的部分存储:

使用--patch,您可以从HEAD和要隐藏的工作树之间的差异中交互选择大块。存储项的构造使其索引状态与存储库的索引状态相同,并且其工作树仅包含您以交互方式选择的更改。然后,所选更改将从工作树回滚。

然而,这将保存完整的索引(这可能不是您想要的,因为它可能包含其他已索引的文件)和部分工作树(看起来可能像您想要隐藏的文件)。

git stash --patch --no-keep-index

可能更合适。


如果--patch不起作用,手动过程可能会:

对于一个或多个文件,中间解决方案是:

将它们复制到Git存储库之外(实际上,eleotlecram提出了一个有趣的替代方案)暂存把它们复制回来git stash#这次,只存储您想要的文件git stash pop stash@{1}#重新应用所有文件修改gitcheckout--afile#在任何本地修改之前将文件重置为HEAD内容

在这个相当繁琐的过程结束时,您将只存储一个或多个文件。

如果您只想隐藏一些已更改的文件,只需在Stage中添加其他文件,然后执行git stash push--keep index

它将隐藏所有未暂存的更改文件