git add --interactive “Ваш відредагований шматок не застосовується”


86

Я намагаюся 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

Я відповідаю розділенням, після чого "ні", щоб застосувати перший шматок. Другий кусень, я намагаюся редагувати. Спочатку я намагався видалити нижній рядок - це не спрацювало. Залишити кусень у спокої теж повністю не працює, і я не можу зрозуміти, чому.


Переконайтесь, що тут ви не додаєте -символи на початку рядків, які не існують у файлі; це різниця, і вона не може видалити рядки, яких там ще немає. Отже, якщо рядок у різниці починається з, +і ви змінюєте його на -git, переходить у WTF? тому що зараз рядок, позначений для видалення, не існує для початку (натомість цей рядок був позначений для додавання, а коли рядок, позначений для додавання, позначений для видалення, git не може видалити рядок, якого ще немає у файлі) .
leeand00

1
Перевірте також закінчення рядків (LF, CRLF), у моєму випадку це не стосується одного LF замість CRLF!
Альберто Рівеллі,

Відповіді:


37

Для цього конкретного прикладу вам потрібно налаштувати номери рядків у шматку. Змініть рядок:

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

так що замість цього читається:

@@ -2,7 +2,8 @@

16
Після невеликого копання я виявив, що ці рядки відображають "діапазон від файлу" та "діапазон до файлу". Я насправді не розумію логіки зміни 1 на 2. Я спробував, і це працює, але я не розумію, чому змінюється "діапазон від файлу". Вихідний файл однаковий, незалежно від того, чи я застосовую цілий патч, чи просто відредагований фрагмент. Чи можете ви пояснити далі чи вказати мені посилання на спуск щодо уніфікованого формату різниці. Мені не вдалося його знайти.
Джош

9
@Josh: stackoverflow.com/questions/2529441 / ... може допомогти, навіть якщо я не отримую повністю Ханки уніфікований формат. @William +1
VonC

5
@Josh: Розглядаючи це, здається, це може бути помилка. Після того, як ви відредагуєте Hunk, git намагається перевірити виправлення, перевіривши, чи застосовуються всі шматки (це може бути надмірно). На жаль, у цьому випадку це означає, що попередній шмат (який ви не застосовуєте) перевіряється, і є деяке перекриття, що призводить до помилки git apply --check. Я не знаю елегантного рішення; git може вчинити правильно, надмірно обережно тут.
Вільям Перселл,

22
Докладніше про зміну номерів рядків, будь ласка? Чому ми повинні це робити? І як? Що означає кожне число?
Білл

4
@WilliamPursell які версії git? Я перейшов на новий комп'ютер і запустив git v2.17.0, і раптом моє редагування виправлення більше ніколи не діє.
Денніс,

105

Це як у цій публікації git-add ?

Редагувати кусок вручну надзвичайно потужний, але також дещо складний, якщо ви ніколи цього не робили.
Найголовніше, про що слід пам’ятати: різниця завжди має відступи з одним символом на додаток до будь-якого іншого відступу.
Персонаж може бути:

  • пробіл (вказує незмінний рядок),
  • -вказівка на те, що рядок видалено,
  • або +вказівка на те, що рядок додано.

Більш нічого. Це має бути пробіл, a - або +. Будь-що інше, і ви отримаєте помилки
(для зміненого рядка немає символу, оскільки вони обробляються шляхом видалення старого рядка та додавання зміненого як нового).

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

І в цьому полягає вся хитрість. Якщо ви ніколи раніше цього не робили, Git скаже вам "Ваш відредагований шматок не застосовується. Редагувати ще раз?" так часто ти почнеш ненавидіти себе за свою нездатність зрозуміти це , хоча це здається настільки легким (або Git, бо він не може зрозуміти, що ти хочеш).

Щось досить часто мене спотикало, це те, що я забув відступ одного символу.
Я б позначив рядок символом -, який слід видалити, але в більшості текстових редакторів, який вставляє a -, він не перезаписує простір, який був там раніше. Це означає, що ви додаєте додатковий простір до цілого рядка, а це, в свою чергу, означає, що алгоритм diff не може знайти / зрівняти рядок у вихідному файлі, що, в свою чергу, означає, що Git буде кричати на вас .

Інша справа, що різниця все ще має сенс. "Sense" означає, що його можна застосовувати чисто. Саме те, як ви створюєте розумну різницю, здається трохи похмурим мистецтвом (принаймні для мене зараз), але ви завжди повинні пам’ятати, як виглядав оригінальний файл, а потім планувати свої -s та + s відповідно. Якщо ви будете редагувати свої куски досить часто, ви з часом зрозумієте це.

Дивіться також цей коміт на git add -p .

Ortomala Lokni «s відповідь відноситься до Хоакін Windmüller блозі" Вибірково добірних змін зробити з мерзотником (або Імма редагувати ваш красень) "

Замість підрахунку рядків, що Git хотів би зробити, це злити перекриваються шматки (коли їх редагують) перед тим, як застосовувати згаданий відредагований шматок.
Це було обговорено в середині 2018 року і дозволило б уникнути таких сценаріїв, як:

якщо ви розділите шматок, відредагуйте перший підканал, перетворивши кінцевий рядок контексту на видалення, тоді якщо ви спробуєте індексувати другий підханк, це не вдасться.


5
Дякую за посилання, але я це вже бачив. Я не додавав / не залишав додатковий рядок. Проблема була в номерах рядків, але я все ще не розумію виправлення.
Джош

9
Я не замінював видалене "-" пробілом - таким чином псуючи відступ. Дякую!!
pedorro

Тільки переконайтеся, що ви не неправильно зрозуміли порожню частину. Я думав, що всі незмінені рядки мають бути лише рядком із чорним кольором - замість просто символу відступу ... Якби годину "відредагований шматок не застосовується", поки я не зрозумів, чому: - /
олігофрен

@oligofren Я не впевнений, що розумію вас: що вам потрібно було зробити, щоб ваш відредагований кусень застосувався?
VonC

1
@VonC: Я спочатку подумав, що мені слід змінити - foo на `` (просто порожній пробіл, а не "порожній простір і весь рядок"). Мені знадобився час, щоб зрозуміти, що це повинно було бути `` foo ''.
олігофрен

48

Звичайно, я запізнююсь із цим, але тим не менш хотів зазначити для протоколу, що це питання обговорювалося минулого року в списку розсилки git, і, схоже, з тих пір мало що змінилося.

Ця особлива проблема випливає з розбиття та спроби редагування одного і того ж шматка. Аналіз, як спочатку розмістив Джефф Кінг, основної проблеми, по суті, полягає в наступному:

Хм Добре, я бачу. Перевірка "чи застосовується ця різниця" подає обидві частини розділеного патча до git-apply. Але, звичайно, друга частина ніколи не застосовуватиметься правильно, оскільки її контекст накладається на першу частину, але не враховує її.

Виконання перевірки за допомогою лише відредагованого виправлення буде працювати. Але це не враховує, що ваш відредагований патч потенційно не вдасться застосувати в довгостроковій перспективі, залежно від того, чи приймаєте ви іншу половину розділеного патча. І ми поки що не можемо цього знати, оскільки користувач, можливо, не сказав нам (вони могли пропустити першу половину, а потім повернутися до неї пізніше після кроку редагування).

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

Отже, загалом, я думаю, що розділення та редагування одного і того ж шматка є за своєю суттю небезпечним і призведе до такого роду проблем. І оскільки редагування забезпечує надмножину функціональних можливостей, я думаю, вам слід просто відредагувати і дозволити застосувати першу частину комбінації, або не залежно від ваших уподобань.

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


6
Дякую, це справді набагато простіше, ніж возитися з номерами рядків.
michiakig

3
Це було моє питання. Потрібен мій кусень, щоб бути менше. Виконано розкол в інтерактиві. Розкол був не тим, що я хотів, тому я вирішив спробувати відредагувати вручну. Постійно отримувало помилку. Розпочав, працював із першої спроби.
Кайл

Це найкраща відповідь у цій темі. Не розділяйте і не редагуйте. Просто відредагуйте.
Dr_Zaszuś

У моєму випадку додаткова проблема виникала через закінчення рядків Windows, показані як ^Mу файлі diff. Після того, як я врятував файл із закінченнями CR, інтерактивний патч редагування пройшов!
Dr_Zaszuś

Дякую, це зробило для мене фокус. Мені довелося попрацювати над величезним шматком, тому я розбив його, і все зламалося. Якщо його не розділяти, все працювало нормально.
Маттіас Фішер,

16

Якщо ви хочете не видаляти рядок, який був призначений для видалення, як у

 first line
-second line
 third line

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


1
Мені це було незрозуміло, я думав, що Git сказав мені зробити рядок єдиним пробілом.
JackHasaKeyboard

15

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

Секрети редагування шматків

Спочатку редагування кусочків може заплутати, інструкції, які git надає вам допомогу, але недостатні для початку.

# —||

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

Секретний соус - це ... підрахунок рядків:

  • Якщо ви видалите рядок, який починається з +, відніміть один до нового числа рядків (остання цифра заголовка куса) .
  • Якщо ви видалите рядок, який починається з - додайте його до нового числа рядків (остання цифра заголовка куса) .
  • Не видаляйте інші рядки (посилальні рядки).

Це повинно дозволити вам швидко змінити куски, щоб вибрати потрібні деталі.


1
Чи є спосіб автоматизувати редагування загального заголовка або налаштувати git для визначення відповідного підрахунку рядків?
Денніс,

Можливо, ви можете створити сценарій для свого улюбленого редактора для автоматизації цього. Можливо, для цього вже є деякі плагіни, але це залежить від редактора.
Ortomala Lokni,

13

Нещодавно я з читання цієї теми зрозумів, як робити ручне редагування.

Фокус, яким я скористався, полягає в тому, що якщо у мене різниця, як:

+ Line to add
+ Line to add
+ Line I dont want to include
+ Line I dont want to include

Фокус полягає в тому, щоб повністю видалити два рядки, які я не хочу, роблячи отриману різницю схожою:

+ Line to add
+ Line to add

Хоча це, швидше за все, очевидно для більшості людей, це було не для мене до сьогодні, і я думав, що повинен просто поділитися своїм досвідом. Скажіть, будь-ласка, чи існує небезпека для цього методу.


2
Я не можу вам подякувати! Я намагався змінити +в ' 'протягом , принаймні , одну годину.
soumer

Знаєте, божевілля - це те саме, і очікування іншого результату. Я говорив це собі 20 хвилин, перш ніж зрозумів, що мені просто потрібно видалити :)
solidak

7

Ви можете вручну редагувати номери рядків, що, безумовно, корисно в деяких випадках. Однак ви, мабуть, могли б уникнути цієї конкретної проблеми, НЕ спершу розколюючи шматок.

Якщо ви бачите, що пізніше вам, можливо, доведеться відредагувати щось у комбінації, яку автоматично вибрав Git, найкраще просто відредагувати весь блок, а не розділяти, індексувати половину, а потім редагувати другу половину. Git зробить кращу роботу, з’ясувавши це.


6

Я прийшов до цього запитання, шукаючи рішення тієї ж проблеми, і не міг зрозуміти, як змінити номери рядків (як пропонувалося вище) у комбінації, щоб git прийняв його у моєму випадку. Я знайшов набагато кращий спосіб зробити це, використовуючи git gui. Там ви можете вибрати рядки в різниці, які ви хочете поставити, потім клацніть правою кнопкою миші та виберіть "Поетапні рядки з коміту". Я пам’ятаю, git-cola теж має таку ж функціональність.


Це справді має бути відповіддю. git-colaсхоже, працює на Linux, Windows та MacOS.
leeand00

5

Додатковою проблемою, коли я отримав цю помилку, було те, що закінчення рядків змінилися, коли я зберегла файл редагування.

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

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

git config --global core.editor "notepad++"

1
Це спрацювало для мене. Але мені потрібен був повний шлях до notepad ++, і це зайняло деякий час, щоб виправитись: git config --global core.editor '"C:/Program\ Files\ \(x86\)/Notepad++/notepad++.exe"' (адаптуйте це відповідно до того, де notepad ++ встановлений на вашому ПК)
Аннабель

1
Точно така ж проблема для мене. Проблеми викликав саме Блокнот. Після того, як я переключив свій редактор за замовчуванням на Notepad ++, все знову почало працювати.
Johnny Oshika,

4

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


0

FYI, я отримував злегка взаємопов’язану помилку ... коли я додав виправлене, дотримуючись запропонованих вище інструкцій ... Однак, помилок не було. Я неодноразово отримував його, просячи мене поставити ту ж саму штуку ... Я помітив, що працюю зі старою версією Vim 7.4 ... Я модернізував vim, і зараз він працює, як очікувалося. Сподіваємось, це комусь допоможе ..

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.