Commit only part of a file in Git
当我在Git中对一个文件进行更改时,如何只提交其中的一些更改?
例如,如何在一个文件中更改的30行中只提交15行?
你可以使用
1 | Stage this hunk [y,n,q,a,d,/,j,J,g,s,e,?]? |
以下是每个选项的说明:
- Y为下一次提交准备这个模块
- n不为下一次提交准备此块
- Q退出;不要将此块或任何剩余块放入阶段
- 将此块和文件中的所有后续块放入阶段
- D不准备此块或文件中的任何后期块
- g选择要转到的块
- /搜索与给定regex匹配的块
- JABBD离开这个混蛋还没决定,看下一个未定混蛋
- JABBD离开这个混蛋还没决定,看下一个混蛋
- KBBD离开这个混蛋还没决定,见上一个未定混蛋
- KBBD离开这个混蛋还没决定,见前一个混蛋
- s将当前的大块拆分为较小的大块
- e手动编辑当前hunk
- ?打印Hunk帮助
如果文件还不在存储库中,您可以先执行
之后,您可以使用:
git diff --staged 检查是否进行了正确的更改。git reset -p 到unstage错误地添加了大块git commit -v 在编辑提交消息时查看提交。
注意,这与
未来参考:Git工具-交互式登台
您可以使用
现代Git也有
如果您喜欢从GUI执行,可以使用Git GUI。您可以简单地标记要包含在提交中的块。我个人认为它比使用
GitGUI在diff视图下提供此功能。只需右键单击您感兴趣的行,您就会看到一个"准备这行提交"菜单项。
我相信
新增内容:
Added content is represented by lines beginning with"+". You can prevent staging any addition lines by deleting them.
删除的内容:
Removed content is represented by lines beginning with"-". You can prevent staging their removal by converting the"-" to a"" (space).
修改内容:
Modified content is represented by"-" lines (removing the old content) followed by"+" lines (adding the replacement content). You can prevent staging the modification by converting"-" lines to"", and removing"+"
lines. Beware that modifying only half of the pair is likely to introduce confusing changes to the index.
关于
如果您使用的是Vim,那么您可能需要尝试一个名为"逃犯"的优秀插件。
您可以看到使用
非常好的介绍性电影放映(特别是第2部分)。
我强烈推荐使用来自亚特兰蒂斯的sourcetree。(它是免费的。)它使这变得微不足道。您可以快速、轻松地准备单个代码块或单个代码行。
值得注意的是,要对新文件使用
1 2 | git add -N file git add -p file |
当我有很多更改,并且最终将从这些更改中创建一些提交时,那么我希望在分段之前暂时保存我的起点。
这样地:
1 2 3 4 5 6 7 8 9 | $ 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 |
Whymarh的答案是我通常做的事情,除了有时会有很多变化,我可以告诉你我可能会在安排事情的时候犯错误,我希望有一个承诺的状态,我可以退回到第二关。
如果您使用emacs,请看一下magit,它为emacs提供了一个git接口。它非常支持分段大块(文件的一部分)。
就像jdsumsion的答案一样,您也可以存储当前的工作,但是可以使用像meld这样的不同工具从存储中提取所选的更改。这样,您甚至可以非常容易地手动编辑大块,这在
1 2 3 4 | $ git stash -u $ git difftool -d -t meld stash $ git commit -a -m"some message" $ git stash pop |
使用stash方法让您有机会在提交代码之前测试代码是否仍然有效。
对于使用git扩展的用户:
在"提交"窗口中,选择要部分提交的文件,然后在右窗格中选择要提交的文本,然后右键单击所选内容并从上下文菜单中选择"准备选定的行"。
Intellij IDEA(我猜是该系列的所有其他产品)内置了对自v2018.1以来部分提交的支持。
vim gitgutter插件可以在不离开vim编辑器的情况下使用
1 | :GitGutterStageHunk |
除此之外,它还提供了其他很酷的特性,如一些现代IDE中的diff符号列。
如果只有一部分人是逃犯
1 | :Gdiff |
允许视觉范围选择,然后选择
试用了
乌龟土:
right click on the file and use
Context Menu → Restore after commit . This will create a copy of the file as it is. Then you can edit the file, e.g. in TortoiseGitMerge and undo all the changes you don't want to commit. After saving those changes you can commit the file.
对于Atom用户,包Github以
使用Atom允许使用具有深色背景的主题(默认情况下,
Git Meld指数——网站引用:
git-meld index运行meld或任何其他git difftool(kdiff3、diffuse等),以允许您以交互方式将更改转移到git索引(也称为git临时区域)。
这类似于git-add-p和git-add-interactive的功能。在某些情况下,meld比git add-p更容易/更快地使用。这是因为meld允许您,例如:
- 查看更多上下文
- 参见行内差异
- 手动编辑并查看"实时"差异更新(每次按键后更新)
- 导航到一个更改,而不对要跳过的每个更改说"n"
用法
在Git存储库中,运行:
1 | git meld-index |
您将看到meld(或配置的git difftool)弹出:
左:从工作树复制的临时目录包含文件
右:包含索引内容的临时目录。这还包括索引中还没有的文件,但是在工作副本中被修改或取消了跟踪——在本例中,您将从头部看到文件内容。
编辑索引(右手边),直到满意为止。需要时记得保存。
完成后,关闭meld,git meld index将更新索引,以匹配刚才编辑的meld右侧临时目录的内容。
对于emacs,还有gitsum
在前面的回答中添加,如果您更喜欢使用命令行,输入
如您所知,以
- 如果不准备添加内容,只需删除该行即可。
- 为了不进行删除,只需将
- 替换为空格。
这就是
added content
Added content is represented by lines beginning with"+". You can
prevent staging any addition lines by deleting them.removed content:
Removed content is represented by lines beginning with"-". You can
prevent staging their removal by converting the"-" to a""
(space).modified content:
Modified content is represented by"-" lines (removing the old
content) followed by"+" lines (adding the replacement content).
You can prevent staging the modification by converting"-" lines to
"", and removing"+" lines. Beware that modifying only half of the
pair is likely to introduce confusing changes to the index.
注意:不要更改文件的内容,这不是一个好的地方。只需更改删除或添加行的运算符。
如上面的一个答案所示,您可以使用
git add --patch filename.txt
或者简称
git add -p filename.txt
…但是对于存储库中已经存在的文件,在S中最好直接在commit命令上使用--patch标志(如果您使用的是最新的足够版本的git):
git commit --patch filename.txt
…或者,同样的,简短的形式
git commit -p filename.txt
…然后使用上述键(Y/N等)选择要包含在提交中的行。
问这个问题已经10年了。我希望这个答案对某些人有用。正如在这里的答案中提到的,在GUI不是一个选项的地方,Andrew Shadura的crecord扩展帮助带来一个ncurses窗口,我们可以在其中选择要提交的行。
按如下方式设置扩展:
1 2 3 4 | 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并调用它,如下所示:
1 | git crecord |
这将显示可以使用的ncurses接口,如下所示。在ncurses窗口中按以下键将执行某些操作:
1 2 3 4 | 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 |
显示示例usage的屏幕放映
Git-Cola是一个很好的图形用户界面,并且内置了这个功能。只需选择要分级的行,然后按s。如果没有进行选择,则将执行完整的Hunk。
如果在
1。聪明的:
- 从
unstagged Changes 部分选择文件 - 右键单击需要分段的代码块
- 选择
Stage Hunk for commit 。
2。线型:
- 从
unstagged Changes 部分选择文件 - 选择要分段的行
- 右键单击并选择
Stage Lines for commit 。
三。如果要暂存除两行以外的完整文件:
- 从
unstagged Changes 部分选择文件 - 按
Ctrl+T (Stage file to commit) 。 - 所选文件现在移动到
Staged Changes 部分 - 选择要分段的行
- 右键单击并选择
UnStage Lines for commit 。