git add --interactive "Ваш отредактированный кусок не применяется" - PullRequest
77 голосов
/ 17 июля 2010

Я пытаюсь использовать git add --interactive для выборочного добавления некоторых изменений в мой индекс, но я постоянно получаю сообщение "Ваш отредактированный кусок не применяется. Редактировать снова ...". Я получаю это сообщение, даже если я выбрал опцию e, и немедленно сохраняю / закрываю свой редактор. Другими словами, патч не применяется вообще, патч не применяется.

Вот точный пример, который я использую (я пытаюсь собрать небольшую демонстрацию):

Оригинальный файл:

first change
second change off branch
third change off branch
second change
third change
fourth change

Новый файл:

Change supporting feature 1
first change
second change off branch
third change off branch
second change
third change
fourth change
bug fix 1
change supporting feature 1

Я пытаюсь показать, как использовать git add --interactive только для добавления строки «исправление ошибки 1» в индекс. Запустив интерактивное добавление в файл, я выбираю режим патча. Это дарит мне

diff --git a/newfile b/newfile
index 6d501a3..8b81ae9 100644
--- a/newfile
+++ b/newfile
@@ -1,6 +1,9 @@
+Change supporting feature 1
 first change
 second change off branch
 third change off branch
 second change
 third change
 fourth change
+bug fix 1
+change supporting feature 1

Я отвечаю разделением, а затем "нет", чтобы применить первый кусок. Второй кусок я пытаюсь отредактировать. Первоначально я попытался удалить нижнюю строку - это не сработало. Оставить кусок полностью в покое тоже не получится, и я не могу понять, почему.

Ответы [ 11 ]

98 голосов
/ 17 июля 2010

Это как в этом git-add post ?

Ручное редактирование блока очень мощно, но также и немного сложно, если вы никогда не делали этого раньше.
Самая важная вещь, которую нужно иметь в виду: разница всегда имеет один символ в дополнение к любому другому отступу.
Символ может быть либо:

  • пробел (указывает на неизменную строку),
  • a -, указывающий, что строка была удалена,
  • или +, указывающий, что строка была добавлена.

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

Поскольку вы открыли diff в своем любимом текстовом редакторе (вы сконфигурировали Git для использования вашего любимого текстового редактора, верно?), Вы можете делать все, что захотите - при условии, что полученный дифференциал будет корректно применяться. .

И в этом заключается хитрость. Если вы никогда не делали этого раньше, Git скажет вам: «Ваш отредактированный кусок не применяется. Редактировать снова?» так часто вы начнете ненавидеть себя за неспособность понять это , даже если это кажется таким простым (или Git, потому что он не может понять, чего вы хотите).

Одна вещь, которая часто приводила меня в замешательство, заключалась в том, что я забыл один отступ символа.
Я бы пометил строку с - для удаления, но в большинстве текстовых редакторов, которые вставляют -, он не перезаписывает пространство, которое было там раньше. Это означает, что вы добавляете дополнительный пробел ко всей строке, что, в свою очередь, означает, что алгоритм сравнения не может найти / сопоставить строку в исходном файле, что, в свою очередь, означает, что Git будет кричать на вас .

Другое дело, что разница все еще имеет смысл. «Смысл» означает, что его можно наносить аккуратно. Точно то, как вы создаете разумную разницу, кажется немного темным искусством (по крайней мере, для меня сейчас), но вы всегда должны помнить, как выглядел оригинальный файл, а затем соответственно планировать свои -s и + s. Если вы будете редактировать свои фрагменты достаточно часто, вы в конечном итоге сможете их освоить.

Смотрите также этот коммит на git add -p .

Ортомала Локни * ответ относится к Хоакин Виндмюллер сообщение в блоге " Выборочно выберите изменения для фиксации с мерзавцем (или иммой отредактируй свой кусок) "

Вместо подсчета строк Git хотел бы объединить перекрывающиеся фрагменты (когда они редактируются) перед применением указанного отредактированного блока.
Это было обсуждено в середине 2018 , и избегало бы сценария как:

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

43 голосов
/ 21 декабря 2010

Конечно, я опоздал на это, но тем не менее хотел упомянуть, что этот вопрос обсуждался в прошлом году в списке рассылки git , и похоже, что с тех пор мало что изменилось.

Эта конкретная проблема возникает из-за разделения и при попытке отредактировать один и тот же блок. Анализ, как первоначально опубликовано Джеффом Кингом, основной проблемы по существу таков:

Hm. Да я вижу. Проверка "применяется ли это изменение" обе части сплит патч для git-apply. Но, конечно, вторая часть никогда не будет правильно применять, потому что его контекст перекрывается с первой частью, но не принимает это во внимание.

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

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

Так что в общем, я думаю, что разделение и редактирование одного и того же куска по своей сути опасно и собирается привести к такого рода проблемам. И потому что редактирование обеспечивает расширенный набор функций, я думаю, вы должны просто отредактируйте и разрешите применение первой части блока или не зависит от ваших предпочтений.

Выбрав для редактирования только раздел, ранее не разделенный, вам не придется иметь дело с номерами строк.

38 голосов
/ 17 июля 2010

Для этого конкретного примера вам нужно настроить номера строк в блоке.Измените строку:

@@ -1,6 +2,8 @@

так, чтобы вместо нее читалось:

@@ -2,7 +2,8 @@
13 голосов
/ 25 марта 2013

Если вы не хотите удалять строку, подготовленную для удаления, как в

 first line
-second line
 third line

там, где вы хотите сохранить вторую строку, убедитесь, что вы заменяете - пробелом, а не удаляете всю строку (как если бы вы избавились от добавленной строки). Git будет использовать строку для контекста.

11 голосов
/ 07 апреля 2011

Я недавно узнал из этой ветки, как работать с ручным редактированием.

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

7 голосов
/ 24 января 2018

Важно также правильно изменить заголовок блока (например, @@ -1,6 +1,9 @@). Хоакин Виндмюллер раскрывает секрет редактирования заголовка куска в одном из своих сообщений в блоге .

Секреты редактирования кряков

Редактирование блоков может поначалу сбивать с толку, инструкции, которые дает вам помощь, но этого недостаточно для начала работы.

# —||

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

Секретный соус ... подсчитывает строки:

  • Если вы удалите строку, начинающуюся с +, то вычтите одну из них на счетчик новой строки (последнюю цифру заголовка блока) .
  • Если вы удалите строку, начинающуюся с -, то добавьте одну к количеству новой строки (последней цифре заголовка блока) .
  • Не удаляйте другие строки (справочные линии).

Это должно позволить вам быстро модифицировать кадры для выбора частей ты хочешь.

6 голосов
/ 20 марта 2012

Вы можете редактировать номера строк вручную, это определенно полезно в некоторых случаях. Тем не менее, вы, вероятно, могли бы избежать этой конкретной проблемы, НЕ разбив ломоть.

Если вы видите, что вам, вероятно, понадобится отредактировать что-то позднее в блоке, который Git автоматически выбрал, лучше всего отредактировать весь блок, а не разделять, размещать половину и затем редактировать вторую половину. Git справится с этим лучше.

6 голосов
/ 06 октября 2011

Я пришел к этому вопросу в поисках решения той же проблемы и не мог понять, как изменить номера строк (как предложено выше) в блоке, чтобы git принял его в моем случае. Я нашел гораздо лучший способ сделать это, используя git gui. Там вы можете выбрать строки в diff, которые хотите поставить, затем щелкните правой кнопкой мыши и выберите «Stage lines from commit». Я помню, что git-cola имеет такую ​​же функциональность.

5 голосов
/ 13 ноября 2012

Еще одна проблема, с которой я столкнулся, когда я получил эту ошибку, заключалась в том, что окончания строк менялись при сохранении файла редактирования.

Я использовал Windows и использовал Блокнот для своих правок (сохраняет только с окончаниями строк Windows).).Мой код был написан с помощью Notepad ++, и я настроил его на конец строки в стиле Unix / Linux.

Когда я изменил свои настройки на Notepad ++ в качестве редактора git по умолчанию, я смог внести изменения в блок.

git config --global core.editor "notepad++"
3 голосов
/ 20 июня 2018

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

...