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

我最近发现了git的patch选项add命令,我必须说这真的是一个奇妙的function。 我还发现,通过点击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; } 

我如何才能将CSS注释删除仅添加到下一个提交? s选项不可用了!

如果你使用git add -p ,甚至在用s分割之后,你没有足够小的改变,你可以直接使用e来编辑补丁。

这可能有点令人困惑,但是如果你仔细按照编辑器窗口中的说明按下e后会打开,那么你会没事的。 在引用的情况下,您可能想要在这些行的开始处用空格replace-

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

…并删除以下行,即以+开头的行。 如果您保存并退出编辑器,只需删除CSS注释即可。

假设你的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; } 

现在让我们改变中间块的样式select器,当我们在它的时候,删除一些我们不再需要的旧的注释样式。

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

这很容易,现在让我们承诺。 但是等等,我想维护版本控制中的变化的逻辑分离,以便简单的逐步代码审查,并且使我的团队和我可以轻松地search提交历史logging以获取具体信息。

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

 git add --patch 
 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,?]? 

哎呀,看起来变化太接近了,所以git把它们放在一起。

即使试图通过按s 分割它也会得到相同的结果,因为分割对于我们的精度更改而言不够精细。 更改的行之间不需要更改行 ,git可以自动分割修补程序。

所以,我们通过按e来手动编辑

 Stage this hunk [y,n,q,a,d,/,e,?]? e 

git会在我们select的编辑器中打开这个补丁。

 # 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. 

我们来回顾一下目标:

我如何才能将CSS注释删除仅添加到下一个提交?

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

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

    为了移除注释行,只留下它们,它们已经被标记为跟踪我们想要的版本控制中的删除。

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

  2. 第二次提交是通过logging删除和添加进行跟踪的更改:

    • 删除(删除旧的select器行)

      为了保持这个提交期间的旧select器行不被删除,我们希望…

      要删除' – '行,使他们'

      字面意思是用空格replace减号 字符。

      所以这三条线…

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

      …将成为( 注意所有三条线中的第一个的单个空间):


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

    • 添加(添加了新的select器行)

      为了不关注在这个提交期间添加的新的select器行,我们要…

      要删除“+”行,请删除它们。

      字面意思是删除整行:

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

      (奖金:如果您碰巧使用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. 

现在让我们承诺。

 git commit -m "remove old code" 

为了确保,让我们看看上次提交的更改。

 git show 
 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 { 

完美 – 你可以看到只有删除被包含在primefaces提交中。 现在让我们完成这个工作,然后完成剩下的工作。

 git add . git commit -m "change selectors" git show 
 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; } 

最后你可以看到最后一次提交只包含select器更改。

如果你可以使用git gui,它可以让你逐行改变。 不幸的是,我不知道如何从命令行执行 – 甚至是可能的。

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


编辑(git-gui使用):

我不知道如果在msysgit和Linux版本的git-gui是相同的,我只使用了msysgit之一。 但假设它是相同的,当你运行它时,有四个窗格:左上窗格是你的工作目录的变化,左下angular是你的阶段变化,右上angular是所选文件的差异(是否工作目录或上演),右下angular是提交的描述(我怀疑你不会需要它)。 当你点击右上angular的文件时,你会看到差异。 如果你右键点击一个差异线,你会看到一个上下文菜单。 需要注意的两个选项是“提交阶段”和“提交阶段”。 你一直在你要提交的行select“提交阶段行”,你就完成了。 如果你愿意的话,你甚至可以select几行并分级。 你总是可以点击登台框中的文件来查看你正在做什么。

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

一种方法是跳过块, git add任何你需要的,然后再运行git add 。 如果这是唯一的块,你可以分割它。

如果你担心提交的顺序,只需使用git rebase -i