当我在Git中更改文件时,如何只提交一些更改?
例如,我怎样才能在文件中更改的30行中只提交15行?
我相信 git add -e myfile 是最简单的方式(至少我的偏好),因为它只是打开一个文本编辑器,让你选择你想要分段的哪一行,你不选择哪一行 . 关于编辑命令:
git add -e myfile
添加内容:
添加的内容由以“”开头的行表示 . 您可以通过删除它们来阻止暂存任何添加行 .
删除内容:
删除的内容由以“ - ”开头的行表示 . 您可以通过将“ - ”转换为“”(空格)来阻止转移它们 .
修改内容:
修改后的内容由“ - ”行(删除旧内容)后跟“”行(添加替换内容)表示 . 您可以通过将“ - ”行转换为“”并删除“”行来防止暂存修改 . 请注意,仅修改对中的一半可能会对索引引入令人困惑的更改 .
有关 git add 的每个详细信息均可在 git --help add 上找到
git add
git --help add
您可以使用 git add --patch <filename> (或简称 -p ),git将开始将您的文件分解为它认为合理的文件"hunks"(文件的一部分) . 然后它会提示您这个问题:
git add --patch <filename>
-p
Stage this hunk [y,n,q,a,d,/,j,J,g,s,e,?]?
以下是每个选项的说明:
y为下一次提交暂存此块
n不要为下次提交暂存此块
q退出;不要把这个大块头或任何剩下的帅哥分开
这个大块头的阶段和所有后来的文件中的帅哥
d不要在文件中暂存这个大块或任何后来的黑客
g选择要转到的大块
/搜索与给定正则表达式匹配的块
j离开这个大块未定,看下一个未定的大块头
J离开这个大块未定,看下一个大块头
k离开这个大块未定,看到前面未定的大块头
K离开这个大块未定,看到前一个大块头
将当前的大块头分成了较小的帅哥
e手动编辑当前的大块头
?打印厚片帮助
如果文件尚未存储在存储库中,则可以先执行 git add -N <filename> . 之后你可以继续 git add -p <filename> .
git add -N <filename>
git add -p <filename>
之后,您可以使用:git diff --staged 检查您是否进行了正确的更改git reset -p 以不加掩饰的方式错误地添加了帅哥git commit -v 在编辑提交消息时查看您的提交 .
git diff --staged
git reset -p
git commit -v
请注意,这与 git format-patch 命令有很大不同,后者的目的是将提交数据解析为 .patch 文件 .
git format-patch
.patch
未来参考:https://git-scm.com/book/en/v2/Git-Tools-Interactive-Staging
您可以使用 git add --interactive 或 git add -p <file> ,然后使用 git commit ( not git commit -a );请参阅git-add联机帮助页中的交互模式,或者只需按照说明操作 .
git add --interactive
git add -p <file>
git commit
git commit -a
Modern Git也有 git commit --interactive (和 git commit --patch ,这是交互式提交中补丁选项的快捷方式) .
git commit --interactive
git commit --patch
如果您更喜欢从GUI执行此操作,则可以使用git-gui . 您只需标记要包含在提交中的块 . 我个人觉得比使用_728702更容易 . 其他git GUI,如QGit或GitX,也可能具有此功能 .
git gui 在diff视图下提供此功能 . 只需右键单击您感兴趣的行,您就会看到一个"stage this line to commit"菜单项 .
对于Atom用户,包github包括 git gui 样式的交互式临时表 . 对于快捷方式,请参阅包的documentation .
git gui
使用Atom允许使用具有深色背景的主题(默认情况下,git gui具有白色背景) .
如果你正在使用vim,你可能想尝试一个名为fugitive的优秀插件 .
您可以使用 :Gdiff 在工作副本和索引之间查看文件的差异,然后使用经典的vim diff命令(如 dp )向索引添加行或数据 . 将修改保存在索引中并使用 :Gcommit 进行提交,您就完成了 .
:Gdiff
dp
:Gcommit
非常好的介绍性截屏视频here(参见esp . part 2) .
我强烈建议使用Atlassian的SourceTree . (它是免费的 . )这使得这个微不足道 . 您可以快速轻松地分发各个代码或各行代码 .
值得注意的是,要将 git add --patch 用于 new file ,您需要首先使用 git add --intent-to-add 将文件添加到索引:
git add --patch
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
Whymarrh的答案就是我通常所做的,除非有时会有很多变化,我可以告诉我在进行事情时可能会犯错误,而且我想要一个承诺状态,我可以再次使用 .
如果您使用emacs,请查看Magit,它为emacs提供了一个git界面 . 它很好地支持staging hunks(部分文件) .
就像jdsumsion的回答一样,你也可以隐藏你当前的工作,但是然后使用像meld这样的difftool从存储中提取选定的更改 . 这样你甚至可以很容易地手动编辑帅哥,这在 git add -p 时有点痛苦:
git add -p
$ git stash -u $ git difftool -d -t meld stash $ git commit -a -m "some message" $ git stash pop
使用stash方法可以在提交之前测试代码是否仍然有效 .
对于那些谁使用 Git Extensions :
在“提交”窗口中,选择要部分提交的文件,然后在右窗格中选择要提交的文本,然后右键单击选择并从上下文菜单中选择“显示所选行” .
Intellij IDEA(我猜这个系列的所有其他产品)自v2018.1以来内置了对部分提交的支持
vim-gitgutter插件可以在不离开vim编辑器的情况下使用
:GitGutterStageHunk
除此之外,它还提供了其他很酷的功能,如某些现代IDE中的diff标志列
如果只有部分大块应该上演vim-fugitive
允许视觉范围选择,然后 :'<,'>diffput 或 :'<,'>diffget 来暂存/恢复单个线路更改 .
:'<,'>diffput
:'<,'>diffget
尝试了 git add -p filename.x ,但在Mac上,我发现gitx(http://gitx.frim.nl/或https://github.com/pieter/gitx)更容易提交我想要的行 .
git add -p filename.x
使用TortoiseGit:
右键单击该文件并使用上下文菜单→提交后恢复 . 这将按原样创建文件的副本 . 然后你可以编辑文件,例如在TortoiseGitMerge中,撤消您不想提交的所有更改 . 保存这些更改后,您可以提交该文件 .
对于emacs,还有gitsum
git-meld-index - 从网站引用:
git-meld-index运行meld - 或任何其他git difftool(kdiff3,diffuse等) - 允许您以交互方式对git索引(也称为git staging区域)进行更改 .
这类似于git add -p和git add --interactive的功能 . 在某些情况下,meld比git add -p更容易/更快速地使用 . 那是因为meld允许你,例如,:
查看更多背景信息
见行内差异
手动编辑并查看'live'差异更新(每次按键后更新)
导航到更改,而不是对要跳过的每个更改说'n'
Usage
在git存储库中,运行:
git meld-index
你会看到meld(或你配置的git difftool)弹出:
LEFT :临时目录合并从工作树复制的文件
RIGHT :带有索引内容的临时目录 . 这还包括尚未在索引中但在工作副本中被修改或未跟踪的文件 - 在这种情况下,您将看到HEAD中的文件内容 .
编辑索引(右侧)直到开心 . 记得在需要时保存 .
完成后,关闭meld,git-meld-index将更新索引以匹配刚刚编辑的meld右侧临时目录的内容 .
如上面的one answer所示,您可以使用 git add --patch filename.txt
git add --patch filename.txt
或短文 git add -p filename.txt
git add -p filename.txt
...但是对于已存在于您的存储库中的文件,最好直接在commit命令上使用--patch标志(如果您使用的是最新版本的git): git commit --patch filename.txt
git commit --patch filename.txt
......或者,简称 git commit -p filename.txt
git commit -p filename.txt
...然后使用提到的键(y / n等),选择要包含在提交中的行 .
添加上一个答案,如果您更喜欢使用命令行,输入 git add -e myfile 可让您选择逐行选择要提交的内容,因为此命令将打开一个具有差异的编辑器,如下所示:
您可能知道以 + 开头的行是添加,以 - 开头的行是删除 . 所以:
+
-
要暂停添加,只需删除该行即可 .
要不进行删除,只需将 - 替换为空格 `` .
这就是 git add -h 关于以这种方式添加文件的说法(修补文件):
git add -h
添加的内容添加的内容由以“”开头的行表示 . 您可以通过删除它们来阻止暂存任何添加行 . 删除的内容:删除的内容由以“ - ”开头的行表示 . 您可以通过将“ - ”转换为“”(空格)来阻止转移它们 . 修改内容:修改后的内容由“ - ”行(删除旧内容)后跟“”行(添加替换内容)表示 . 您可以通过将“ - ”行转换为“”并删除“”行来防止暂存修改 . 请注意,仅修改对中的一半可能会对索引引入令人困惑的更改 .
Caution: 不要改变文件的内容,这不是一个好的地方 . 只需更改已删除或添加的行的运算符即可 .
如果它在 Windows 平台上,在我看来 git gui 是来自 unstaged 文件的 stage / commit 几行的最佳工具
Windows
unstaged
stage
commit
1. Hunk wise:
从 unstagged Changes 部分选择文件
unstagged Changes
右键单击需要暂存的代码块
选择 Stage Hunk for commit
Stage Hunk for commit
2. Line wise:
选择要暂存的行/行
选择 Stage Lines for commit
Stage Lines for commit
3. If you want to stage the complete file except couple of lines:
按 Ctrl+T (Stage file to commit)
Ctrl+T (Stage file to commit)
所选文件现在移至 Staged Changes 部分
Staged Changes
选择 UnStage Lines for commit
UnStage Lines for commit
git-cola是一个很棒的GUI,内置了这个功能 . 只需选择要分段的行并按S.如果没有选择,则完成整个大块 .
22 回答
我相信
git add -e myfile
是最简单的方式(至少我的偏好),因为它只是打开一个文本编辑器,让你选择你想要分段的哪一行,你不选择哪一行 . 关于编辑命令:添加内容:
删除内容:
修改内容:
有关
git add
的每个详细信息均可在git --help add
上找到您可以使用
git add --patch <filename>
(或简称-p
),git将开始将您的文件分解为它认为合理的文件"hunks"(文件的一部分) . 然后它会提示您这个问题:以下是每个选项的说明:
y为下一次提交暂存此块
n不要为下次提交暂存此块
q退出;不要把这个大块头或任何剩下的帅哥分开
这个大块头的阶段和所有后来的文件中的帅哥
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
文件 .未来参考:https://git-scm.com/book/en/v2/Git-Tools-Interactive-Staging
您可以使用
git add --interactive
或git add -p <file>
,然后使用git commit
( notgit commit -a
);请参阅git-add联机帮助页中的交互模式,或者只需按照说明操作 .Modern Git也有
git commit --interactive
(和git commit --patch
,这是交互式提交中补丁选项的快捷方式) .如果您更喜欢从GUI执行此操作,则可以使用git-gui . 您只需标记要包含在提交中的块 . 我个人觉得比使用_728702更容易 . 其他git GUI,如QGit或GitX,也可能具有此功能 .
git gui 在diff视图下提供此功能 . 只需右键单击您感兴趣的行,您就会看到一个"stage this line to commit"菜单项 .
对于Atom用户,包github包括
git gui
样式的交互式临时表 . 对于快捷方式,请参阅包的documentation .使用Atom允许使用具有深色背景的主题(默认情况下,git gui具有白色背景) .
如果你正在使用vim,你可能想尝试一个名为fugitive的优秀插件 .
您可以使用
:Gdiff
在工作副本和索引之间查看文件的差异,然后使用经典的vim diff命令(如dp
)向索引添加行或数据 . 将修改保存在索引中并使用:Gcommit
进行提交,您就完成了 .非常好的介绍性截屏视频here(参见esp . part 2) .
我强烈建议使用Atlassian的SourceTree . (它是免费的 . )这使得这个微不足道 . 您可以快速轻松地分发各个代码或各行代码 .
值得注意的是,要将
git add --patch
用于 new file ,您需要首先使用git add --intent-to-add
将文件添加到索引:当我有很多更改,并最终会从更改中创建一些提交时,我想在暂存之前暂时保存我的起点 .
像这样:
Whymarrh的答案就是我通常所做的,除非有时会有很多变化,我可以告诉我在进行事情时可能会犯错误,而且我想要一个承诺状态,我可以再次使用 .
如果您使用emacs,请查看Magit,它为emacs提供了一个git界面 . 它很好地支持staging hunks(部分文件) .
就像jdsumsion的回答一样,你也可以隐藏你当前的工作,但是然后使用像meld这样的difftool从存储中提取选定的更改 . 这样你甚至可以很容易地手动编辑帅哥,这在
git add -p
时有点痛苦:使用stash方法可以在提交之前测试代码是否仍然有效 .
对于那些谁使用 Git Extensions :
在“提交”窗口中,选择要部分提交的文件,然后在右窗格中选择要提交的文本,然后右键单击选择并从上下文菜单中选择“显示所选行” .
Intellij IDEA(我猜这个系列的所有其他产品)自v2018.1以来内置了对部分提交的支持
vim-gitgutter插件可以在不离开vim编辑器的情况下使用
除此之外,它还提供了其他很酷的功能,如某些现代IDE中的diff标志列
如果只有部分大块应该上演vim-fugitive
允许视觉范围选择,然后
:'<,'>diffput
或:'<,'>diffget
来暂存/恢复单个线路更改 .尝试了
git add -p filename.x
,但在Mac上,我发现gitx(http://gitx.frim.nl/或https://github.com/pieter/gitx)更容易提交我想要的行 .使用TortoiseGit:
对于emacs,还有gitsum
git-meld-index - 从网站引用:
git-meld-index运行meld - 或任何其他git difftool(kdiff3,diffuse等) - 允许您以交互方式对git索引(也称为git staging区域)进行更改 .
这类似于git add -p和git add --interactive的功能 . 在某些情况下,meld比git add -p更容易/更快速地使用 . 那是因为meld允许你,例如,:
查看更多背景信息
见行内差异
手动编辑并查看'live'差异更新(每次按键后更新)
导航到更改,而不是对要跳过的每个更改说'n'
Usage
在git存储库中,运行:
你会看到meld(或你配置的git difftool)弹出:
LEFT :临时目录合并从工作树复制的文件
RIGHT :带有索引内容的临时目录 . 这还包括尚未在索引中但在工作副本中被修改或未跟踪的文件 - 在这种情况下,您将看到HEAD中的文件内容 .
编辑索引(右侧)直到开心 . 记得在需要时保存 .
完成后,关闭meld,git-meld-index将更新索引以匹配刚刚编辑的meld右侧临时目录的内容 .
如上面的one answer所示,您可以使用
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等),选择要包含在提交中的行 .
添加上一个答案,如果您更喜欢使用命令行,输入
git add -e myfile
可让您选择逐行选择要提交的内容,因为此命令将打开一个具有差异的编辑器,如下所示:您可能知道以
+
开头的行是添加,以-
开头的行是删除 . 所以:要暂停添加,只需删除该行即可 .
要不进行删除,只需将
-
替换为空格 `` .这就是
git add -h
关于以这种方式添加文件的说法(修补文件):Caution: 不要改变文件的内容,这不是一个好的地方 . 只需更改已删除或添加的行的运算符即可 .
如果它在
Windows
平台上,在我看来git gui
是来自unstaged
文件的stage
/commit
几行的最佳工具1. Hunk wise:
从
unstagged Changes
部分选择文件右键单击需要暂存的代码块
选择
Stage Hunk for commit
2. Line wise:
从
unstagged Changes
部分选择文件选择要暂存的行/行
选择
Stage Lines for commit
3. If you want to stage the complete file except couple of lines:
从
unstagged Changes
部分选择文件按
Ctrl+T (Stage file to commit)
所选文件现在移至
Staged Changes
部分选择要暂存的行/行
选择
UnStage Lines for commit
git-cola是一个很棒的GUI,内置了这个功能 . 只需选择要分段的行并按S.如果没有选择,则完成整个大块 .