当我对Git中的文件进行更改时,如何才能只提交部分更改?

例如,如何在文件中更改的30行中只提交15行?


您可以使用:

git add --patch <filename>

或简称:

git add -p <filename>

Git会将你的文件分解成它认为合理的“大块”(文件的一部分)。然后,它将提示您以下问题:

Stage this hunk [y,n,q,a,d,/,j,J,g,s,e,?]?

以下是每个选项的描述:

你准备好下一个任务不要为下一次提交准备这个大块q退出;不要表演这个大块头或任何剩余的大块头将这个大块和所有后续大块放在文件中不要在文件中放置这个大块或任何后面的大块选择一个帅哥/搜索与给定正则表达式匹配的大块j让这个男人还没决定,看看下一个还没决定的男人J让这个男人犹豫不决,看看下一个男人让这个男人还没决定,看看之前那个还没决定的男人K让这个男人犹豫不决,看看上一个男人我们把现在的大块分成更小的大块e手动编辑当前大块然后,您可以通过用#替换+/-来手动编辑大块(谢谢veksen)? 打印大块帮助

如果文件还不在存储库中,可以先执行gitadd-N<filename>。然后,您可以继续使用gitadd-p<filename>。

之后,您可以使用:

gitdiff—暂存以检查是否暂存了正确的更改git重置-p以取消页面错误添加的大块gitcommit-v在编辑提交消息时查看提交。

注意,这与git格式补丁命令有很大不同,后者的目的是将提交数据解析为.patch文件。

未来参考:Git工具-交互式暂存


gitgui在diff视图下提供了此功能。只需右键单击您感兴趣的行,就会看到一个“stage this line to commit”菜单项。


您可以使用gitadd--interactive或gitadd-p<file>,然后使用gitcommit(而不是gitcommit-a);请参阅gitadd手册页中的交互模式,或简单地按照说明进行操作。

现代Git还提供了gitcommit——交互式(和gitcommit补丁,这是交互式提交中补丁选项的快捷方式)。

如果您喜欢从GUI执行,可以使用gitgui。通过右键单击并选择以下选项,您可以简单地标记要包含在提交中的块:

为提交准备Hunk

如果您只想添加大块的某些行,也可以选择所需的行,右键单击它们,然后:

提交的暂存行

我个人觉得这比使用git add-I更容易。其他git GUI,如Qbit或GitX,也可能具有此功能。


如果您使用emacs,请查看Magit,它为emacs提供了一个git接口。它非常支持分段大块(文件的一部分)。


对于emacs,还有gitsum


尝试了gitadd-p filename.x,但在mac上,我找到了gitx(http://gitx.frim.nl/或https://github.com/pieter/gitx)让我更容易地完成我想要的任务。


如果你正在使用vim,你可能想尝试一个叫做逃犯的优秀插件。

您可以使用:Gdiff查看文件在工作副本和索引之间的差异,然后使用经典的vim diff命令(如dp)将行或块添加到索引中。将修改保存在索引中,并使用:Gcommit提交,就完成了。

这里有非常好的介绍性放映(特别是第2部分)。


当我有很多更改,并且最终将根据这些更改创建一些提交时,我希望在暂存之前暂时保存我的起点。

这样地:

$ git stash -u
Saved working directory and index state WIP on master: 47a1413 ...
$ git checkout -p stash
... step through patch hunks
$ git commit -m "message for 1st commit"
$ git checkout -p stash
... step through patch hunks
$ git commit -m "message for 2nd commit"
$ git stash pop

Whymharh的回答是我通常会做的,但有时会有很多变化,我可以告诉你,我可能会在表演过程中犯错误,我想要一个可以依靠第二次传球的坚定状态。


就像jdsumsion的答案一样,你也可以隐藏你当前的工作,但然后使用像meld这样的困难工具从隐藏中提取所选的更改。这样,您甚至可以非常容易地手动编辑大块,这在gitadd-p中有点麻烦:

$ git stash -u
$ git difftool -d -t meld stash
$ git commit -a -m "some message"
$ git stash pop

如果代码仍然有效,那么使用stash方法可以在提交之前进行测试。


如上面的一个答案所示,您可以使用git add--补丁文件名.txt

或简称git add-p文件名.txt

…但对于存储库中已经存在的文件,在s中,直接在commit命令上使用--patch标志要好得多(如果您使用的是足够新的git版本):gitcommit--补丁文件名.txt

…或者,再次,简称gitcommit-p文件名.txt

…然后使用上述键(y/n等)选择要包含在提交中的行。


我强烈建议使用Atlassian的SourceTree。(这是免费的。)这让事情变得微不足道。您可以快速轻松地分段单个大块代码或单个代码行。


值得注意的是,要为新文件使用git-add--patch,您需要首先使用git-add--intent添加文件到索引:

git add -N file
git add -p file

vim-gitgolf插件可以在不离开vim编辑器的情况下使用

:GitGutterStageHunk

除此之外,它还提供了其他很酷的功能,如一些现代IDE中的差异符号列

如果只有一部分人被安排逃亡

:Gdiff

允许视觉范围选择,然后:“<,”>diffput或:“<”>diffget暂存/还原单个行更改。


使用TortoiseGit:

右键单击文件并使用上下文菜单→ 提交后恢复。这将按原样创建文件的副本。然后您可以编辑该文件,例如在TortoiseGitMerge中,并撤消所有不想提交的更改。保存这些更改后,您可以提交文件。


如果是在Windows平台上,我认为gitgui是一个很好的工具,可以从未分页的文件中暂存/提交几行代码

1.愚蠢:

从未标记的更改部分选择文件右键单击需要暂存的代码块选择要提交的阶段Hunk

2.逐行:

从未标记的更改部分选择文件选择要暂存的行右键单击并选择要提交的阶段行

3.如果您想暂存除几行之外的完整文件:

从未标记的更改部分选择文件按Ctrl+T(要提交的阶段文件)所选文件现在移动到分段更改部分选择要暂存的行右键单击并选择UnStage Lines进行提交


git meld索引--引用自网站:

git-meld-index运行meld——或任何其他gitdifftool(kdiff3、diffuse等)——允许您以交互方式将更改转移到git索引(也称为git暂存区)。

这与git add-p和git add-interactive的功能类似。在某些情况下,meld比gitadd-p更容易/更快使用。这是因为meld允许你,例如:

查看更多上下文参见行内差异手动编辑并查看“实时”差异更新(每次按键后更新)导航到更改,而不必对要跳过的每个更改说“n”

用法

在git存储库中,运行:

git meld-index

您将看到meld(或您配置的gitdifftool)弹出:

左:从工作树复制的临时目录连续文件

RIGHT:包含索引内容的临时目录。这还包括尚未在索引中但在工作副本中已修改或未跟踪的文件——在本例中,您将从HEAD中看到文件内容。

编辑索引(右手边)直到满意。记得在需要时保存。

完成后,关闭meld,git meld索引将更新索引,以匹配刚刚编辑的meld右侧临时目录的内容。


对于使用Git扩展的用户:

在提交窗口中,选择要部分提交的文件,然后在右窗格中选择要提交的文本,然后右键单击所选内容并从上下文菜单中选择“暂存选定行”。


git-cola是一个很棒的GUI,并且内置了这个功能。只需选择要分段的行,然后按S。如果没有选择,则将分段完整的大块。


我相信git add-e myfile是最简单的方法(至少是我的首选),因为它只需打开一个文本编辑器,让您选择要暂存的行和不暂存的行。关于编辑命令:

添加的内容:

添加的内容由以“+”开头的行表示。您可以通过删除添加行来防止暂存任何添加行。

删除的内容:

删除的内容由以“-”开头的行表示。通过将“-”转换为“”(空格),可以防止临时删除它们。

修改内容:

修改后的内容由“-”行(删除旧内容)和“+”行(添加替换内容)表示。您可以通过将“-”行转换为“”并删除“+”来防止暂存修改线请注意,仅修改其中的一半可能会对索引带来混乱的变化。

git-add的所有细节都可以在git-help-add上找到


IntelliJ IDEA(以及我猜该系列的所有其他产品)自2018.1版起就内置了对部分提交的支持。


对于Atom用户,包github包括gitgui风格的交互式登台。有关快捷方式,请参阅软件包的文档。

使用Atom可以处理具有深色背景的主题(默认情况下,gitgui具有白色背景)。


加上前面的回答,如果您更喜欢使用命令行,输入git add-e myfile可以让您选择逐行选择要提交的内容,因为此命令将打开一个具有不同之处的编辑器,如下所示:

正如你可能知道的那样,以+开头的行是加法,以-开头的行则是删除。因此:

要不进行添加,只需删除该行。要不进行删除,只需用空格替换。

这就是git add-h所说的通过这种方式添加文件(修补文件):

添加的内容添加的内容由以“+”开头的行表示。你可以通过删除添加行来防止暂存任何添加行。删除的内容:删除的内容由以“-”开头的行表示。你可以通过将“-”转换为“”来防止临时删除(空格)。修改内容:修改的内容由“-”行表示(删除旧的内容),后跟“+”行(添加替换内容)。您可以通过将“-”行转换为“”,并删除“+”行。请注意,仅修改这对组合很可能会给指数带来令人困惑的变化。

注意:不要更改文件的内容,这不是一个好地方。只需更改删除或添加行的运算符即可。


这个问题已经问了10年了。我希望这个答案对某人有用。正如这里的答案中所提到的,在GUI不是选项的情况下,AndrejShadura的gitcrecord工具有助于提供一个交互式窗口,我们可以在其中选择要提交的行。

按如下方式设置扩展:

git clone https://github.com/andrewshadura/git-crecord
cd git-crecord
./setup.py install
ln -s $PWD/git-crecord ~/.local/bin/git-crecord

cd到git repo并按如下方式调用它:

git crecord

这将带来一个交互式界面,可以使用如下所示。按下以下键将执行某些操作:

f       hunk toggle fold (arrow keys can also be used)
space   toggle hunk selection
a       toggle commit or amend
c       confirm and open commit window

显示示例用法的屏幕广播


如果你碰巧在使用VS代码,那你就幸运了。选择要暂存的范围,然后使用Git:Sstage Selected Ranges暂存它们,如果需要,请提交。

我录制了一张gif图来演示我的意思:


您可以使用EclipseIDE,每个修改的本地文件都可以与暂存区域进行比较,在这个并排的diff视图中,您可以自由选择从本地复制到暂存区域的大块,或者相反,从暂存区域回滚本地更改。

但还有更多:),所有图形化的git客户端都会做大块分段(gitadd-p),但我知道没有人能做到这一点:直接在分段区域进行编辑,这样就可以更精细地拾取同一行或同一大块上的多个更改(甚至可以写入/删除/更新本地从未存在的内容),就像“gitadd-e”在补丁级别工作,但没有破坏补丁内容的风险。此外,由于它在diff视图中使用了常规文本编辑器,因此您可以使用语法颜色来帮助您,并且可以执行文本替换操作(更改所有缩进类型、重命名在许多地方使用的本地变量等),以便在提交“真正”更改之前开始单独提交一些重新格式化/重构,但不需要在同一提交中嵌入所有文件更改。

当然,Eclipse更面向Java,但由于其强大的gitstaging编辑器,它也可以用于其他语言。有一个基于Eclipse的免费产品,只关注git操作,名为GitEye:https://www.collab.net/downloads/giteye但使用基本的Eclipse发行版似乎维护得不太好,比如:https://www.eclipse.org/downloads/packages/release/2020-12/r/eclipse-ide-java-developers

编辑:由于IntelliJ 2020.3允许使用真正的git索引,因此现在可以像Eclipse一样直接编辑暂存区域


我想把lazygit添加到工具列表中。这是一个不错的命令行gui(即,即使不允许X转发,也可以通过ssh工作)。它具有广泛的功能(例如,选择要提交的行、交互式重基)、有用的着色,并且使用起来相对简单。可以以多种方式安装(go、conda、包管理器等)。仍在积极开发/维护。


从2018年答案的评论来看:

很遗憾,Visual Studio没有此选项。大约10年前,替代源代码控制系统Mercurial在Visual Studio中支持此功能。自从我使用Git以来,我真的很怀念它。

现在(2022年8月)支持:

Git Line登台发布!我们很高兴地宣布在Visual Studio 2022中发布Line登台支持。行分段,也称为交互式分段,使您能够在不同的提交中拆分更改的代码行。在提交更改之前,还可以使用行分段来检查更改。将更改后的代码行或代码段标记为通过分段进行审查,并在完成后提交分段的更改。通过将Visual Studio 2022更新到17.3版或更高版本,开始使用Line staging。阅读我们的Line登台文档,了解有关如何使用和自定义此功能的更多信息。


在所有这些工具中,我最喜欢Fork(虽然不是免费的)!

与其他游戏相比,它使用起来非常时尚优雅,单击鼠标旁边的按钮可以进行大块或线条分段。

另一个选择是GitKraken,有趣但更复杂和强大!