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


当前回答

我不知道如何在命令行上执行,只使用SourceTree。假设您已经更改了文件A,并且在文件B中有两个更改块。如果您只想将第二个块存储在文件B,而其他所有内容都保持不变,请执行以下操作:

舞台上的一切对工作副本执行更改,以撤消文件A中的所有更改(例如,启动外部diff工具并使文件匹配)使文件B看起来好像只应用了第二个更改。(例如,启动外部diff工具并撤消第一个更改。)使用“保留暂存更改”创建存储。取消标记所有内容完成!

其他回答

自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内容

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

由于在Git中创建分支很简单,您可以创建一个临时分支并将各个文件检入其中。

另一种方法是:

# Save everything
git stash 

# Re-apply everything, but keep the stash
git stash apply

git checkout <"files you don't want in your stash">

# Save only the things you wanted saved
git stash

# Re-apply the original state and drop it from your stash
git stash apply stash@{1}
git stash drop stash@{1}

git checkout <"files you put in your stash">

在我(再次)来到这个页面并不喜欢前两个答案(第一个答案只是不回答问题,我不太喜欢使用-p交互模式)之后,我想到了这个问题。

这一想法与@VonC建议的使用存储库外的文件相同,您可以将所需的更改保存在某个位置,删除存储库中不需要的更改,然后重新应用您移开的更改。然而,我使用了git隐藏作为“某处”(因此,最后还有一个额外的步骤:移除你放在隐藏中的cahnges,因为你也把它们移到了一边)。

我已经回顾了这个问题的答案和评论以及一些类似的线索。请注意,为了能够隐藏任何特定的跟踪/未跟踪文件,以下命令都不正确:

git stash-p(--patch):手动选择大块,不包括未跟踪的文件git stash-k(--keep index):隐藏所有跟踪/未跟踪的文件,并将它们保存在工作目录中git stash-u(--包括未跟踪的):隐藏所有已跟踪/未跟踪的文件git stash-p(--patch)-u(--include untracked):无效命令

目前,能够隐藏任何特定跟踪/未跟踪文件的最合理方法是:

暂时提交不想隐藏的文件添加并隐藏弹出临时提交

在回答另一个问题时,我为这个过程编写了一个简单的脚本,这里有SourceTree中执行该过程的步骤。

解决方案

本地更改:

file_A(已修改)未暂存file_B(已修改)未暂存file_C(已修改)未暂存

要创建仅包含file_C上的更改的存储“my_stash”:

1. git add file_C
2. git stash save --keep-index temp_stash
3. git stash save my_stash
4. git stash pop stash@#{1}

完成。


解释

将file_C添加到临时区域创建一个名为“temp_stash”的临时存储,并将更改保存在file_C上只使用file_C上的更改创建所需的存储(“my_stash”)将“temp_stash”(file_A和file_B)中的更改应用于本地代码并删除存储

您可以在步骤之间使用gitstatus来查看发生了什么。