我可以用git拆分已经拆分的大块头吗?

gre*_*ire 184 git patch split add

我最近发现了git 命令的patch选项add,我必须说它真的是一个很棒的功能.我还发现通过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;
 }
Run Code Online (Sandbox Code Playgroud)

如何仅将CSS注释删除添加到下一次提交?该s选项不再可用!

Mar*_*air 233

如果您正在使用git add -p,甚至在拆分后s,您没有足够小的更改,您可以使用e直接编辑补丁.

这可能有点令人困惑,但是如果你仔细按照编辑器窗口中的说明按下e后打开,你会没事的.在您引用的情况下,您可能希望-在这些行的开头替换空格:

-
-form.table-form #field_teacher + label,
-form.table-form #field_producer_distributor + label {
Run Code Online (Sandbox Code Playgroud)

...并删除以下行,即以该行开头的行+.如果您随后保存并退出编辑器,则只会删除CSS注释.

  • 请注意,您确实必须用**空格**替换它.我试着确定我可以删除`-`字符,Git抱怨我的补丁不适用. (24认同)
  • 酷解!我看到了但却被误解了......我虽然也会从工作树中删除更改. (8认同)
  • 实际上,从帮助文本来看并不是很明显.实际上,我发现自己经常使用它,因为我认为git真的鼓励你让每个提交尽可能精确和美观:) (6认同)
  • @Filype:我不知道为什么会发生这种情况,我担心 - 如果你正在运行`git add -p`并编辑了一个带有'e`的大块,它只会影响上演的内容,而不是你的工作树. (3认同)
  • 我猜你用' - '删除行的原因并用空格替换'+'然后你正在形成一个补丁,其中那些带有' - '的行已被删除,而行带有'' +已被添加(在补丁的眼中).或者另一种看待它的方式是,你实际上是做那些字符( - ,+)代表的动作(添加一行或删除它).只有剩下的'-'s和'+'行被记录为变化,其余的是"文件是如何"的. (2认同)

Jef*_*ett 55

让我们说你example.css看起来像这样:

.classname {
  width: 440px;
}

/*#field_teacher_id {
  display: block;
} */

form.table-form #field_teacher + label,
form.table-form #field_producer_distributor + label {
  width: 300px;
}

.another {
  width: 420px;
}
Run Code Online (Sandbox Code Playgroud)

现在让我们改变中间块中的样式选择器,当我们处理它时,删除一些我们不再需要的旧注释样式.

.classname {
  width: 440px;
}

#user-register form.table-form .field-type-checkbox label {
  width: 300px;
}

.another {
  width: 420px;
}
Run Code Online (Sandbox Code Playgroud)

这很容易,现在让我们承诺.但是等等,我想保持版本控制中的更改的逻辑分离,以便进行简单的逐步代码审查,这样我和我的团队就可以轻松地搜索提交历史记录以获取具体信息.

删除旧代码在逻辑上与其他样式选择器更改分开.我们需要两个不同的提交,所以让我们添加一个补丁.

git add --patch
Run Code Online (Sandbox Code Playgroud)
diff --git a/example.css b/example.css
index 426449d..50ecff9 100644
--- a/example.css
+++ b/example.css
@@ -2,12 +2,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;
 }

Stage this hunk [y,n,q,a,d,/,e,?]?
Run Code Online (Sandbox Code Playgroud)

哎呀,看起来变化太近了,所以git将它们混为一谈.

即使尝试通过按下来分割它也会s产生相同的结果,因为分割对于我们的精度变化来说不够精细.更改的行之间需要不变的行,以便git能够自动拆分补丁.

所以,让我们按下来手动编辑e

Stage this hunk [y,n,q,a,d,/,e,?]? e
Run Code Online (Sandbox Code Playgroud)

git将在我们选择的编辑器中打开补丁.

# Manual hunk edit mode -- see bottom for a quick guide
@@ -2,12 +2,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;
 }

# ---
# To remove '-' lines, make them ' ' lines (context).
# To remove '+' lines, delete them.
# Lines starting with # will be removed.
#
# If the patch applies cleanly, the edited hunk will immediately be
# marked for staging. If it does not apply cleanly, you will be given
# an opportunity to edit again. If all lines of the hunk are removed,
# then the edit is aborted and the hunk is left unchanged.
Run Code Online (Sandbox Code Playgroud)

让我们回顾一下目标:

如何仅将CSS注释删除添加到下一次提交?

我们想把它分成两个提交:

  1. 第一次提交涉及删除一些行(注释删除).

    要删除注释行,只需将它们单独保留,它们已被标记为跟踪版本控制中的删除,就像我们想要的那样.

    -/*#field_teacher_id {
    - display: block;
    -} */

  2. 第二个提交是一个更改,通过记录删除和添加来跟踪:

    • 删除(删除旧的选择线)

      要保留旧的选择器行(在此提交期间不要删除它们),我们希望...

      要删除' - '行,请将它们设为''

      ...字面上的意思更换负-标志用空格 character.

      So these three lines...

      -
      -form.table-form #field_teacher + label,
      -form.table-form #field_producer_distributor + label {

      ...将成为(注意所有3行中第一个的单个空格):


      form.table-form #field_teacher + label,
      form.table-form #field_producer_distributor + label {

    • 添加(添加了新的选择线)

      为了不注意在此提交期间添加的新选择器行,我们希望...

      要删除"+"行,请将其删除.

      ...字面意思是删除整行:

      +#user-register form.table-form .field-type-checkbox label {

      (好处:如果您碰巧使用vim作为编辑器,请按dd删除一行.Nano用户按Ctrl+ K)

保存时,您的编辑器应如下所示:

# Manual hunk edit mode -- see bottom for a quick guide
@@ -2,12 +2,7 @@
   width: 440px;
 }

-/*#field_teacher_id {
-  display: block;
-} */

 form.table-form #field_teacher + label,
 form.table-form #field_producer_distributor + label {
   width: 300px;
 }

# ---
# To remove '-' lines, make them ' ' lines (context).
# To remove '+' lines, delete them.
# Lines starting with # will be removed.
#
# If the patch applies cleanly, the edited hunk will immediately be
# marked for staging. If it does not apply cleanly, you will be given
# an opportunity to edit again. If all lines of the hunk are removed,
# then the edit is aborted and the hunk is left unchanged.
Run Code Online (Sandbox Code Playgroud)

现在让我们提交.

git commit -m "remove old code"
Run Code Online (Sandbox Code Playgroud)

为了确保,让我们看看上次提交的变化.

git show
Run Code Online (Sandbox Code Playgroud)
commit 572ecbc7beecca495c8965ce54fbccabdd085112
Author: Jeff Puckett <jeff@jeffpuckett.com>
Date:   Sat Jun 11 17:06:48 2016 -0500

    remove old code

diff --git a/example.css b/example.css
index 426449d..d04c832 100644
--- a/example.css
+++ b/example.css
@@ -2,9 +2,6 @@
   width: 440px;
 }

-/*#field_teacher_id {
-  display: block;
-} */

 form.table-form #field_teacher + label,
 form.table-form #field_producer_distributor + label {
Run Code Online (Sandbox Code Playgroud)

完美 - 您可以看到只有删除被包含在原子提交中.现在让我们完成工作并完成剩下的工作.

git add .
git commit -m "change selectors"
git show
Run Code Online (Sandbox Code Playgroud)
commit 83ec3c16b73bca799e4ed525148cf303e0bd39f9
Author: Jeff Puckett <jeff@jeffpuckett.com>
Date:   Sat Jun 11 17:09:12 2016 -0500

    change selectors

diff --git a/example.css b/example.css
index d04c832..50ecff9 100644
--- a/example.css
+++ b/example.css
@@ -2,9 +2,7 @@
   width: 440px;
 }

-
-form.table-form #field_teacher + label,
-form.table-form #field_producer_distributor + label {
+#user-register form.table-form .field-type-checkbox label {
   width: 300px;
 }
Run Code Online (Sandbox Code Playgroud)

最后,您可以看到最后一次提交仅包括选择器更改.

  • 另外,除了删除不想添加的行之外,还可以将“ +”替换为“#”。结果是一样的,但是也许您不满意删除(并且无法还原),或者想要在保存之前尝试一下。 (2认同)

vha*_*lac 9

如果你可以使用git gui,它允许你逐行进行更改.不幸的是,我不知道如何从命令行执行此操作 - 或者即使可能.

我过去使用的另一个选项是回滚部分更改(保持编辑器打开),提交我想要的位,撤消并从编辑器重新保存.不是很优雅,但完成工作.:)


编辑(git-gui用法):

我不确定msysgit和linux版本中的git-gui是否相同,我只使用了msysgit.但假设它是相同的,当你运行它时,有四个窗格:左上窗格是你的工作目录更改,左下角是你的阶段更改,右上角是所选文件的差异(是工作目录)或者分阶段),右下角用于描述提交(我怀疑你不需要它).当您单击右上角的文件时,您将看到差异.如果右键单击diff线,您将看到一个上下文菜单.需要注意的两个选项是"提交阶段大块"和"提交阶段线".您继续在要提交的行上选择"提交阶段行",您就完成了.您甚至可以选择多行并根据需要进行分级.您始终可以单击暂存框中的文件以查看您要提交的内容.

至于提交,您可以使用gui工具或命令行.