在Git中只提交文件的一部分

问题描述 投票:2485回答:23

当我在Git中对文件进行更改时,如何只提交一些更改?

例如,我怎样才能在文件中更改的30行中只提交15行?

git git-commit
23个回答
3366
投票

您可以使用git add --patch <filename>(或简称为-p),git将开始将您的文件分解为它认为合理的“帅哥”(文件的一部分)。然后它会提示您这个问题:

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

以下是每个选项的说明:

  • y为下一次提交提供此块
  • n不要为下次提交暂存此块
  • 退出不要把这个大块头或任何剩下的帅哥放在一边
  • 这个大块头和后来所有人都在文件中的一个阶段
  • d不要在文件中放置这个大块或任何后来的黑客
  • g选择一个大块去
  • /搜索与给定正则表达式匹配的块
  • j离开这个大块未定,看下一个未定的大块头
  • J离开这个大块未定,看下一个大块头
  • k离开这个大块未定,看到先前未定的大块头
  • K离开这​​个大块未定,看看上一个大块头
  • 将当前的大块头分成了较小的帅哥
  • e手动编辑当前的大块头
  • ?打印大块帮助

如果该文件尚未存储在存储库中,您可以先执行git add -N <filename>。之后你可以继续使用git add -p <filename>

之后,您可以使用:

  • git diff --staged检查你是否进行了正确的更改
  • git reset -p突然错误地添加了帅哥
  • git commit -v在编辑提交消息时查看您的提交。

请注意,这与git format-patch命令有很大不同,.patch命令的目的是将提交数据解析为Git Tools - Interactive Staging文件。

参考未来:git add --interactive


9
投票

enter image description here(我猜这个系列的所有其他产品)自v2018.1以来内置支持部分提交

git add -p


8
投票

就像jdsumsion的回答一样,你也可以隐藏你当前的工作,但是然后使用像meld这样的difftool从存储中提取选定的更改。这样你甚至可以很容易地手动编辑帅哥,这在$ git stash -u $ git difftool -d -t meld stash $ git commit -a -m "some message" $ git stash pop 时有点痛苦:

vim-gitgutter

使用stash方法可以在提交代码之前测试代码是否仍然有效。


8
投票

对于那些使用Git Extensions的人:

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


6
投票

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

vim-fugitive

除此之外,它还提供了其他很酷的功能,例如在一些现代IDE中的diff标志列

如果只有部分大块应该上演:Gdiff

:'<,'>diffput

允许视觉范围选择然后:'<,'>diffgetgit add -p filename.x分阶段/恢复单独的线变化。


5
投票

尝试了http://gitx.frim.nl/,但在Mac上,我发现gitx(https://github.com/pieter/gitxContext Menu → Restore after commit)更容易完全提交我想要的线条。


4
投票

使用TortoiseGit:

右键单击该文件并使用git add -e myfile。这将按原样创建文件的副本。然后你可以编辑文件,例如在TortoiseGitMerge中,撤消您不想提交的所有更改。保存这些更改后,您可以提交该文件。


4
投票

添加上一个答案,如果您更喜欢使用命令行,输入enter image description here可以选择逐行选择要提交的内容,因为此命令将打开一个带有差异的编辑器,如下所示:

+

你可能知道以qazxsw poi开头的行是加法,以qazxsw poi开头的行是删除。所以:

  • 要不添加添加,只需删除该行。
  • 要不删除删除只需将-替换为空格-

这就是关于以这种方式添加文件(修补文件)的说法:

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

删除的内容:删除的内容由以“ - ”开头的行表示。您可以通过将“ - ”转换为“”(空格)来阻止转移它们。

修改内容:修改后的内容用“ - ”行(删除旧内容)后跟“+”行(添加替换内容)表示。您可以通过将“ - ”行转换为“”并删除“+”行来阻止暂存修改。请注意,仅修改对中的一半可能会对索引引入令人困惑的更改。

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


3
投票

对于git add -h用户,包Atom包括github风格的交互式舞台。对于快捷方式,请参阅包的git gui

使用Atom允许使用具有深色背景的主题(默认情况下,documentation具有白色背景)。


2
投票

对于emacs,还有git gui


2
投票

gitsum - 从网站上引用:

git-meld-index运行meld - 或任何其他git difftool(kdiff3,diffuse等) - 允许您以交互方式对git索引(也称为git staging区域)进行更改。

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

  • 看到更多背景
  • 看行内差异
  • 手动编辑并查看“实时”差异更新(每次按键后更新)
  • 导航到更改,而不是对要跳过的每个更改都说'n'

用法

在git存储库中,运行:

git-meld-index

你会看到meld(或你配置的git difftool)弹出:

LEFT:包含从工作树复制的文件的临时目录

右:具有索引内容的临时目录。这还包括尚未在索引中但在工作副本中被修改或未跟踪的文件 - 在这种情况下,您将从HEAD中看到文件内容。

编辑索引(右侧)直到开心。记得在需要时保存。

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


236
投票

你可以使用git add -p <file>git commit,然后使用git commit -a(不是git-add);请参阅git commit --interactive联机帮助页中的交互模式,或者只需按照说明操作即可。

Modern Git也有git commit --patch(和git-gui,它是交互式提交中补丁选项的快捷方式)。

如果您更喜欢从GUI进行,可以使用git add -i。您只需标记要包含在提交中的块。我个人觉得比使用git add -e myfile更容易。其他git GUI,如QGit或GitX,也可能具有此功能。


2
投票

问这个问题已经10年了。我希望这个答案对某人有用。正如答案git meld-index 中提到的那样,GUI不是一个选项,Andrew Shadura的here有助于带来一个ncurses窗口,我们可以在其中选择要提交的行。

设置扩展名如下:

crecord extension

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

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

这将打开ncurses接口,可以使用如下所示。在ncurses窗口中按下以下键将执行某些操作:

git crecord

截屏显示样本用法


1
投票

正如上面的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 所示,你可以使用one answer

或短形式的 git add --patch filename.txt

...但是对于已存在于您的存储库中的文件,最好直接在commit命令上使用--patch标志(如果您使用的是最新版本的git): git add -p filename.txt

......或者,再次,短形式的 git commit --patch filename.txt

...然后使用提到的键(y / n等),选择要包含在提交中的行。


0
投票

git commit -p filename.txt 是一个很棒的GUI,内置了这个功能。只需选择要分段的行并按S.如果没有选择,则完成整个大块。


0
投票

如果它在git-cola平台上,在我看来Windows是非常好的工具git gui / stage来自commit文件的几行

1. Hunk明智:

  • unstaged部分选择文件
  • 右键单击需要暂存的代码块
  • 选择unstagged Changes

2.直线:

  • Stage Hunk for commit部分选择文件
  • 选择要暂存的行/行
  • 右键单击并选择unstagged Changes

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

  • Stage Lines for commit部分选择文件
  • unstagged Changes
  • 选定的文件现在移动到Ctrl+T (Stage file to commit)部分
  • 选择要暂存的行/行
  • 右键单击并选择Staged Changes

130
投票

git gui在diff视图下提供此功能。只需右键单击您感兴趣的行,您就会看到“暂存此行提交”菜单项。


69
投票

我相信git add是最简单的方法(至少我的偏好),因为它只是打开一个文本编辑器,让你选择你想要分段的哪一行,你不选择哪一行。关于编辑命令:

添加内容:

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

删除内容:

删除的内容由以“ - ”开头的行表示。您可以通过将“ - ”转换为“”(空格)来阻止转移它们。

修改内容:

修改后的内容由“ - ”行(删除旧内容)后跟“+”行(添加替换内容)表示。您可以通过将“ - ”行转换为“”并删除“+”行来阻止暂存修改。请注意,仅修改对中的一半可能会对索引引入令人困惑的更改。

关于git --help add的每一个细节都可以在fugitive上找到


42
投票

如果你正在使用vim,你可能想尝试一下名为:Gdiff的优秀插件。

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

非常好的介绍性截屏part 2(见esp.SourceTree)。


28
投票

我强烈建议使用Atlassian的git add --patch。 (它是免费的。)这使得这个微不足道。您可以快速轻松地分发各个代码或各行代码。


24
投票

值得注意的是,要将git add --intent-to-add用于新文件,您需要首先使用git add -N file git add -p file 将文件添加到索引:

$ 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

22
投票

当我有很多更改,并最终会从更改中创建一些提交时,我想在暂存之前暂时保存我的起点。

像这样:

Magit

Whymarrh的答案就是我通常所做的,除非有时候会有很多变化,我可以告诉我在进行事情时可能会犯错误,我想要一个忠诚的状态,我可以再次使用。


12
投票

如果您使用emacs,请查看staging hunks,它为emacs提供了一个git界面。它很好地支持Intellij IDEA(部分文件)。

© www.soinside.com 2019 - 2024. All rights reserved.