Могу ли я разделить уже разделенный кусок с git?


Я недавно обнаружил в Git до 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;
 }

как я могу добавить только удаление комментариев CSS к следующему обязательству ? Элемент s опция больше не доступна!

4 144

4 ответа:

если вы используете git add -p и даже после разделения с s, у вас нет достаточно маленького изменения, вы можете использовать e для непосредственного редактирования патча.

это может быть немного запутанным, но если вы внимательно следуйте инструкциям в окне редактора, которое откроется после нажатия кнопки e тогда все будет хорошо. В случае, если вы процитировали, вы хотели бы заменить - с пробелом в начало этих строк:

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

теперь давайте изменим селекторы стилей в среднем блоке, и пока мы на нем, удалите какой-то старый закомментированный стиль, который нам больше не нужен.

.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
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, чтобы иметь возможность автоматически разделить патч.

Итак, давайте вручную edit его нажатием e

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

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.

давайте рассмотрим цель:

как я могу добавить удаление комментариев CSS только к следующему фиксации ?

мы хотим разделить это на два коммита:

  1. первая фиксация включает в себя удаление некоторых строк (удаление комментариев).

    удалить закомментированные строки, просто оставить их в покое, они уже отмечены для отслеживания изменений в системе управления версиями как мы хотим.

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

  2. вторая фиксация-это изменение, которое отслеживается Запись Как удалений, так и дополнений:

    • удаление (старые селекторные линии удалены)

      чтобы сохранить старые селекторные линии (не удалять их во время этой фиксации), мы хотим...

      чтобы удалить ' - 'строки, сделайте их''

      ...что буквально означает замену минуса - знаки пробел символ.

      Итак, эти три русло...

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

теперь давайте совершим.

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 {

Perfect-вы можете видеть, что только удаления были включены в эту атомарную фиксацию. Теперь давайте закончим работу и сделаем все остальное.

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

наконец, вы можете увидеть, что последняя фиксация включает только селектор изменения.

Если вы можете использовать Git gui, он позволяет вам поэтапно изменять строку за строкой. К сожалению, я не знаю как это сделать из командной строки - или даже если это возможно.

еще один вариант, который я использовал в прошлом, - откат части изменения (держите редактор открытым), зафиксируйте биты, которые я хочу, отмените и повторно сохраните из редактора. Не очень элегантно, но делает свою работу. :)


EDIT (использование Git-gui):

Я не уверен, что Git-gui-это то же самое версии msysgit и linux, я использовал только msysgit. Но предполагая, что это то же самое, когда вы запускаете его, есть четыре панели: верхняя левая панель-это ваши рабочие изменения каталога, нижняя левая-ваши изменения этапов, верхняя правая-разница для выбранного файла (будь то рабочий каталог или этап), а нижняя правая-для описания фиксации (я подозреваю, что вам это не понадобится). При нажатии на файл в правом верхнем углу, вы увидите разницу. Если вы щелкните правой кнопкой мыши на строке дифференциала, вы увидите контекстное меню. Два варианта, которые следует отметить,- это "stage hunk for commit"и" stage line for commit". Вы продолжаете выбирать "stage line for commit" на линиях, которые вы хотите зафиксировать, и все готово. Вы даже можете выбрать несколько строк и поставить их, если хотите. Вы всегда можете щелкнуть файл в промежуточном поле, чтобы увидеть, что вы собираетесь совершить.

Что касается фиксации, вы можете использовать либо инструмент gui, либо командную строку.

один из способов сделать это, чтобы пропустить кусок, git add все, что вам нужно, а затем запустить git add снова. Если это единственный кусок, вы сможете разделить его.

Если вы беспокоитесь о порядке обязывает, просто использовать git rebase -i.