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

发布于 2024-11-14 20:12:14 字数 567 浏览 3 评论 0原文

我最近发现了 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

睫毛溺水了 2024-11-21 20:12:14

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

这可能有点令人困惑,但如果您仔细按照按 e 后打开的编辑器窗口中的说明进行操作,那么您'会没事的。在您引用的情况下,您需要将这些行开头的 - 替换为空格:

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

... 并删除以下行,即以 开头的行+。如果您随后保存并退出编辑器,则只会删除 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:

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

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

单身情人 2024-11-21 20:12:14

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

现在让我们更改中间块中的样式选择器,并删除一些我们不再需要的旧注释样式。

.classname {
  width: 440px;
}

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

.another {
  width: 420px;
}

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

删除旧代码在逻辑上是分离的从其他样式选择器更改。我们将需要两个不同的提交,所以让我们为补丁添加块。

git add --patch
diff --git a/example.css b/example.css
索引 426449d..50ecff9 100644
---a/example.css
+++ b/example.css
@@ -2,12 +2,7 @@
   宽度:440px;
 }
 
-/*#field_teacher_id {
- 显示:块;
-} */
-
-form.table-form #field_teacher + 标签,
-form.table-form #field_ Producer_distributor +标签{
+#user-register form.table-form .field-type-checkbox 标签 {
   宽度:300px;
 }
 
上演这个大块头 [y,n,q,a,d,/,e,?]?

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

即使尝试通过按 s分割也会得到相同的结果,因为分割对于我们的精度更改来说不够细粒度。 更改的行之间需要有未更改的行,以便 git 能够自动拆分补丁。

因此,让我们通过按 e 手动编辑它,

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

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

# 手动块编辑模式 - 请参阅底部的快速指南
@@ -2,12 +2,7 @@
   宽度:440px;
 }
 
-/*#field_teacher_id {
- 显示:块;
-} */
-
-form.table-form #field_teacher + 标签,
-form.table-form #field_ Producer_distributor +标签{
+#user-register form.table-form .field-type-checkbox 标签 {
   宽度:300px;
 }
 
# ---
# 要删除 '-' 行,请将它们设为 ' ' 行(上下文)。
# 要删除“+”行,请将其删除。
# 以 # 开头的行将被删除。
#
# 如果补丁应用干净,编辑后的块将立即被
# 标记为暂存。如果应用不干净,您将被给予
# 再次编辑的机会。如果把大块头的所有线条都去掉,
# 然后编辑被中止,块保持不变。

让我们回顾一下目标:

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

我们希望将其分为两个提交:

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

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

    -/*#field_teacher_id {
    - 显示:块;
    <代码>-} */

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

    • 删除(删除旧的选择器行)

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

      <块引用>

      要删除“-”行,请将其改为“ ”

      ...字面意思是用空格 字符替换减号 - 符号。

      所以这三行...

      <代码>-
      -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)

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

# 手动块编辑模式 - 请参阅底部的快速指南
@@ -2,12 +2,7 @@
   宽度:440px;
 }
 
-/*#field_teacher_id {
- 显示:块;
-} */
 
 form.table-form #field_teacher + 标签,
 form.table-form #field_ Producer_distributor + 标签 {
   宽度:300px;
 }
 
# ---
# 要删除 '-' 行,请将它们设为 ' ' 行(上下文)。
# 要删除“+”行,请将其删除。
# 以 # 开头的行将被删除。
#
# 如果补丁应用干净,编辑后的块将立即被
# 标记为暂存。如果应用不干净,您将被给予
# 再次编辑的机会。如果把大块头的所有线条都去掉,
# 然后编辑被中止,块保持不变。

现在让我们承诺吧。

git commit -m "remove old code"

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

git show

<前><代码>提交 572ecbc7beecca495c8965ce54fbccabdd085112
作者:Jeff Puckett [电子邮件受保护]>
日期: 2016 年 6 月 11 日星期六 17:06:48 -0500

删除旧代码

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

-/*#field_teacher_id {
- 显示:块;
-} */

form.table-form #field_teacher + 标签,
form.table-form #field_ Producer_distributor + 标签 {

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

git add .
git commit -m "change selectors"
git show

<前><代码>提交83ec3c16b73bca799e4ed525148cf303e0bd39f9
作者:Jeff Puckett [电子邮件受保护]>
日期: 2016 年 6 月 11 日星期六 17:09:12 -0500

改变选择器

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

-
-form.table-form #field_teacher + 标签,
-form.table-form #field_ Producer_distributor +标签{
+#user-register form.table-form .field-type-checkbox 标签 {
宽度:300px;
}

最后您可以看到最后一次提交仅包含选择器更改。

Let's say your example.css looks like this:

.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;
}

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.

.classname {
  width: 440px;
}

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

.another {
  width: 420px;
}

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.

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,?]?

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

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

git will open the patch in our editor of choice.

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

Let's review the goal:

How can I add the CSS comment removal only to the next commit ?

We want to split this into two commits:

  1. 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;
    -} */

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

      To remove '-' lines, make them ' '

      ...which literally means replacing the minus - signs with a space character.

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

      To remove '+' lines, delete them.

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

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

Now let's commit.

git commit -m "remove old code"

And just to make sure, let's see the changes from the last commit.

git show
commit 572ecbc7beecca495c8965ce54fbccabdd085112
Author: Jeff Puckett <[email protected]>
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 {

Perfect - you can see that only the deletions were included in that atomic commit. Now let's finish the job and commit the rest.

git add .
git commit -m "change selectors"
git show
commit 83ec3c16b73bca799e4ed525148cf303e0bd39f9
Author: Jeff Puckett <[email protected]>
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;
 }

Finally you can see the last commit only includes the selector changes.

话少心凉 2024-11-21 20:12:14

如果您可以使用 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.

半寸时光 2024-11-21 20:12:14

一种方法是跳过该块,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 run git 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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文