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

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

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

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

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

以下是每个选项的说明:

  • 为下一次提交做好准备
  • ñ不要为下一次提交做好准备
  • 退出; 不要把这个大块头或者剩下的任何东西放在一边
  • 一个阶段这个大块头和所有后来在文件中的大块头
  • d不要把这个大块头或者后面的任何一个大块头放在文件中
  • gselect一个大块去
  • /search匹配给定的正则expression式的大块
  • j留下这个笨蛋,看下一个未定的大块头
  • J离开这个笨蛋,看下一个大块头
  • k离开这个大块未定,看到以前未定的大块
  • K离开这个大块未定,见前面的大块
  • 把当前的大块分成小块
  • e手动编辑当前的大块
  • 打印大块的帮助

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

之后,您可以使用:
git diff --staged检查你是否进行了正确的修改
git reset -p to stagage misckedly added hunk
git commit -v在编辑提交消息时查看您的提交。

注意这和git format-patch命令有很大的不同,目的是将提交数据parsing为.patch文件。

未来的参考: https : //git-scm.com/book/en/v2/Git-Tools-Interactive-Staging

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

现代的Git也有git commit --interactive (和git commit --patch ,这是在交互提交中修补选项的捷径)。

如果你更喜欢从GUI来做,你可以使用git-gui 。 你可以简单地标记你想包含在提交中的块。 我个人觉得比使用git add -i更容易。 其他的git GUI,如QGit或者GitX,也可能有这个function。

git gui在diff视图下提供了这个function。 只需右键单击您感兴趣的行,您应该看到一个“阶段这行提交”菜单项。

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

添加内容:

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

删除的内容:

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

修改内容:

修改后的内容由“ – ”行(删除旧内容),后跟“+”行(添加replace内容)表示。 您可以通过将“ – ”行转换为“”来防止修改,并删除“+”行。 请注意,修改只有一半的对可能会引起混乱的索引变化。

有关git add每个细节都可以在git --help add

如果您使用的是vim,您可能需要尝试一下名为“ 逃犯”的优秀插件。

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

非常好的介绍性截屏(见第2部分 )。

我强烈build议使用Atlassian的SourceTree 。 (它是免费的。)它使这个微不足道的。 您可以快速轻松地分阶段代码或单独的代码行。

在这里输入图像描述

当我有很多的变化,并最终会从变化创build一些提交,然后我想暂时保存我的起点。

喜欢这个:

 $ 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 

Whymarrh的答案就是我通常所做的,除了有时候会有很多的变化,而且我可以告诉我在做事的时候可能会犯一个错误,而且我想要一个可以重返的状态。

值得注意的是,使用git add --patch作为新文件,你需要首先添加文件索引与git add --intent-to-add

 git add -N file git add -p file 

你应该使用emacs,看看Magit ,它提供了一个emacs的git界面。 它支持staging hunk (文件的部分)相当好。

就像jdsumsion的回答一样,你也可以隐藏你当前的工作,然后使用一个diff工具像meld从存储中提取选定的更改。 这样,你甚至可以手动编辑hunk,这很容易,在git add -p有点痛苦:

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

在提交之前,使用存储方法可以让您有机会testing代码是否仍然有效。

vim-gitgutter插件可以在没有离开vim编辑器的情况下使用

 :GitGutterStageHunk 

除此之外,它还提供了其他很酷的function,如一些现代IDE中的差异标志列

如果只有一部分人应该上演vim-fagitive

 :Gdiff 

允许视觉范围select,然后:'<,'>diffput:'<,'>diffget阶段/恢复单个行更改。

对于那些使用Git扩展的人

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

尝试了git add -p filename.x ,但在Mac上,我发现gitx( http://gitx.frim.nl/或https://github.com/pieter/gitx )更容易提交我想要的线。

随着TortoiseGit:

右键单击该文件并使用Context Menu → Restore after commit 。 这将创build一个文件的副本。 然后你可以编辑这个文件,例如在TortoiseGitMerge中,撤销所有你不想提交的改变。 保存这些更改后,您可以提交该文件。

对于emacs还有gitsum

git-meld-index – 从网站引用:

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

这与git add -p和git add –interactive的function类似。 在某些情况下,融合比git add -p更容易/更快速。 那是因为meld允许你,例如:

  • 看更多的上下文
  • 见线内差异
  • 手动编辑并查看“实时”差异更新(每次按键后更新)
  • 导航到一个变化,不要说'n'你想要跳过每一个变化

用法

在一个git仓库中运行:

 git meld-index 

你会看到meld(或你configuration的git difftool)popup:

LEFT :从工作树复制的临时目录

RIGHT :包含索引内容的临时目录。 这还包括那些还没有在索引中,但在工作副本中被修改或未被跟踪的文件 – 在这种情况下,您将会看到来自HEAD的文件内容。

编辑索引(右侧),直到快乐。 记得在需要时进行保存。

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

正如上面的一个答案所示,您可以使用git add --patch filename.txt

或者短格式的git add -p filename.txt

…但是对于已经存在于你的仓库中的文件,使用commit命令直接使用–patch标志会更好一些(如果你使用的是最新版本的git): git commit --patch filename.txt

…或者,再次,短格式的git commit -p filename.txt

…然后使用提到的键(y / n等)来select要包含在提交中的行。

如果它在Windows平台上,在我看来, git gui是最好的工具,从unstaged文件中stage / commit几行

1.聪明:

  • 从未加unstagged Changes部分select文件
  • 右键单击需要上演的代码块
  • selectStage Hunk for commit

2.明智的:

  • 从未加unstagged Changes部分select文件
  • select要进行的线/线
  • selectStage Lines for commit

3.如果您想要完整的文件,除了几行:

  • 从未加unstagged Changes部分select文件
  • 按下Ctrl+T (Stage file to commit)
  • 所选文件现在移到Staged Changes部分
  • select要进行的线/线
  • selectUnStage Lines for commit

git-cola是一个很棒的graphics用户界面,并且内置了这个function。 只需select线路,然后按S键。 如果没有select,完整的大块是上演。