我可以用 git 拆分已经拆分的块吗?
我最近发现了 git 的 add
命令的 patch
选项,我必须说这确实是一个很棒的功能。 我还发现,通过按 s 键可以将一个大块分成较小的块,这增加了提交的精度。 但是,如果我想要更高的精度,如果分割块不够小怎么办?
例如,考虑这个已经分裂的大块:
@@ -34,12 +34,7 @@
width: 440px;
}
-/*#field_teacher_id {
- display: block;
-} */
-
-form.table-form #field_teacher + label,
-form.table-form #field_producer_distributor + label {
+#user-register form.table-form .field-type-checkbox label {
width: 300px;
}
How can I add the CSS comment removing only to the next commit? s
选项不再可用!
I've recently discovered git's patch
option to the add
command, and I must say it really is a fantastic feature.
I also discovered that a large hunk could be split into smaller hunks by hitting the s key, which adds to the precision of the commit.
But what if I want even more precision, if the split hunk is not small enough?
For example, consider this already split hunk:
@@ -34,12 +34,7 @@
width: 440px;
}
-/*#field_teacher_id {
- display: block;
-} */
-
-form.table-form #field_teacher + label,
-form.table-form #field_producer_distributor + label {
+#user-register form.table-form .field-type-checkbox label {
width: 300px;
}
How can I add the CSS comment removal only to the next commit ? The s
option is not available anymore!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
如果您使用
git add -p
,即使在使用 s 拆分之后,您也没有足够小的更改,您可以使用 e 直接编辑补丁。这可能有点令人困惑,但如果您仔细按照按 e 后打开的编辑器窗口中的说明进行操作,那么您'会没事的。在您引用的情况下,您需要将这些行开头的
-
替换为空格:... 并删除以下行,即以
开头的行+。如果您随后保存并退出编辑器,则只会删除 CSS 注释。
If you're using
git add -p
and even after splitting with s, you don't have a small enough change, you can use e to edit the patch directly.This can be a little confusing, but if you carefully follow the instructions in the editor window that will be opened up after pressing e then you'll be fine. In the case you've quoted, you would want to replace the
-
with a space at the beginning of these lines:... and delete the following line, i.e. the one that begins with
+
. If you then save and exit your editor, just the removal of the CSS comment will be staged.假设您的
example.css
如下所示:现在让我们更改中间块中的样式选择器,并删除一些我们不再需要的旧注释样式。
这很容易,现在让我们承诺吧。 但是等等,我想保持版本控制中更改的逻辑分离,以便进行简单的逐步代码审查,以便我和我的团队可以轻松搜索提交历史记录以了解具体信息。
删除旧代码在逻辑上是分离的从其他样式选择器更改。我们将需要两个不同的提交,所以让我们为补丁添加块。
哎呀,看起来这些变化太接近了,所以 git 把它们整合在一起了。
即使尝试通过按 s 来分割也会得到相同的结果,因为分割对于我们的精度更改来说不够细粒度。 更改的行之间需要有未更改的行,以便 git 能够自动拆分补丁。
因此,让我们通过按 e 手动编辑它,
git 将在我们选择的编辑器中打开补丁。
让我们回顾一下目标:
我们希望将其分为两个提交:
第一个提交涉及删除一些行(删除注释)。
要删除注释行,只需保留它们即可,它们已经被标记为跟踪版本控制中的删除,就像我们想要的那样。
-/*#field_teacher_id {
- 显示:块;
<代码>-} */
第二次提交是更改,通过记录删除和添加来跟踪:
删除(删除旧的选择器行)
为了保留旧的选择器行(在提交期间不要删除它们),我们想要...
<块引用>
要删除“-”行,请将其改为“ ”
...字面意思是用空格
字符替换减号
-
符号。所以这三行...
<代码>-
-form.table-form #field_teacher + 标签,
-form.table-form #field_ Producer_distributor + 标签 {
...将变成(注意所有 3 行中第一行的单个空格):
<代码>
form.table-form #field_teacher + 标签,
form.table-form #field_ Producer_distributor + 标签 {
添加(添加了新的选择器行)
为了不注意此提交期间添加的新选择器行,我们希望...
<块引用>
要删除“+”行,请将其删除。
...字面意思是删除整行:
+#user-register form.table-form .field-type-checkbox 标签 {
(奖励:如果您碰巧使用 vim 作为编辑器,请按 d< /kbd>d 删除一行。 Nano 用户按Ctrl+K)
您的编辑器保存时应该如下所示:
现在让我们承诺吧。
为了确保确定,让我们看看上次提交后的更改。
完美 - 您可以看到该原子提交中仅包含删除。现在让我们完成工作并完成剩下的工作。
最后您可以看到最后一次提交仅包含选择器更改。
Let's say your
example.css
looks like this:Now let's change the style selectors in the middle block, and while we're at it, delete some old commented-out style we don't need anymore.
That was easy, now let's commit. But wait, I want to maintain logical separation of changes in version control for simple step-wise code review, and so that my team and I can easily search commit history for specifics.
Deleting old code is logically separate from the other style selector change. We're going to need two distinct commits, so let's add hunks for a patch.
Whoops, looks like the changes are too close, so git has hunked them together.
Even trying to split it by pressing s has the same result because the split isn't granular enough for our precision changes. Unchanged lines are required between changed lines for git to be able to automatically split the patch.
So, let's manually edit it by pressing e
git will open the patch in our editor of choice.
Let's review the goal:
We want to split this into two commits:
The first commit involves deleting some lines (comment removal).
To remove the commented lines, just leave them alone, they are already marked to track the deletions in version control just like we want.
-/*#field_teacher_id {
- display: block;
-} */
The second commit is a change, which is tracked by recording both deletions and additions:
Deletions (old selector lines removed)
To keep the old selector lines (do not delete them during this commit), we want...
...which literally means replacing the minus
-
signs with a spacecharacter.
So these three lines...
-
-form.table-form #field_teacher + label,
-form.table-form #field_producer_distributor + label {
...will become (notice the single space at the first of all 3 lines):
form.table-form #field_teacher + label,
form.table-form #field_producer_distributor + label {
Additions (new selector line added)
To not pay attention to the new selector line added during this commit, we want...
...which literally means to delete the whole line:
+#user-register form.table-form .field-type-checkbox label {
(Bonus: If you happen to be using vim as your editor, press dd to delete a line. Nano users press Ctrl+K)
Your editor should look like this when you save:
Now let's commit.
And just to make sure, let's see the changes from the last commit.
Perfect - you can see that only the deletions were included in that atomic commit. Now let's finish the job and commit the rest.
Finally you can see the last commit only includes the selector changes.
如果您可以使用 git gui,它允许您逐行进行更改。不幸的是,我不知道如何从命令行执行此操作 - 或者即使这是可能的。
我过去使用的另一个选项是回滚部分更改(保持编辑器打开),提交我想要的部分,从编辑器撤消并重新保存。不是很优雅,但完成了工作。 :)
编辑(git-gui 用法):
我不确定 msysgit 和 linux 版本中的 git-gui 是否相同,我只使用过 msysgit 版本。但假设它是相同的,当您运行它时,有四个窗格:左上窗格是您的工作目录更改,左下角是您的阶段更改,右上角是所选文件的差异(无论是工作目录还是工作目录)或已上演),右下角用于描述提交(我怀疑您不需要它)。当您单击右上角的文件时,您将看到差异。如果右键单击差异行,您将看到一个上下文菜单。需要注意的两个选项是“stage hunk for commit”和“stage line for commit”。您继续在要提交的行上选择“提交的阶段行”,然后就完成了。如果需要,您甚至可以选择多行并上演它们。您始终可以单击暂存框中的文件来查看要提交的内容。
至于提交,您可以使用 gui 工具或命令行。
If you can use git gui, it allows you to stage changes line by line. Unfortunately, I don't know how to do it from the command line - or even if it is possible.
One other option I've used in the past is rolling back part of the change (keep the editor open), commit the bits I want, undo and re-save from the editor. Not very elegant, but gets the job done. :)
EDIT (git-gui usage):
I am not sure if the git-gui is the same in msysgit and linux versions, I've only used the msysgit one. But assuming it is the same, when you run it, there are four panes: top-left pane is your working directory changes, bottom-left is your stages changes, top-right is the diff for the selected file (be it working dir or staged), and bottom right is for description of the commit (I suspect you won't need it). When you click a file in the top-right one, you will see the diff. If you right-click on a diff line, you'll see a context menu. The two options to note are "stage hunk for commit" and "stage line for commit". You keep selecting "stage line for commit" on the lines you want to commit, and you are done. You can even select several lines and stage them if you want. You can always click the file in the staging box to see what you are bout to commit.
As for committing, you can use either the gui tool or the command line.
一种方法是跳过该块,
git add
无论您需要什么,然后再次运行git add
。如果这是唯一的块,您将能够拆分它。如果您担心提交的顺序,只需使用 git rebase -i 即可。
One way to do it is to skip the chunk,
git add
whatever else you need, and then rungit add
again. If this is the only chunk, you'll be able to split it.If you're worried about the order of commits, just use
git rebase -i
.