Почему `git stash -p` иногда терпит неудачу?

I ♥ git stash -p. Но иногда после удовлетворительного сеанса y, n и s, я получаю это:

Saved working directory and index state WIP on foo: 9794c1a lorum ipsum
error: patch failed: spec/models/thing_spec.rb:65
error: spec/models/thing_spec.rb: patch does not apply
Cannot remove worktree changes

Почему?

67 голосов | спросил John Bachir 19 FebruaryEurope/MoscowbSat, 19 Feb 2011 01:46:51 +0300000000amSat, 19 Feb 2011 01:46:51 +030011 2011, 01:46:51

5 ответов


0

git stash -p должен давать меньше ошибок в Git 2.17 (Q2 2018).
До этого "git add -p" (который разделяет логику с git stash) был ленив в объединении разделенных патчей перед передачей результата в базовый «git apply», что приводило к ошибкам в угловом регистре; логика для подготовки патча, который будет применен после выбора фрагментов.

См. commit 3a8522f , commit b3e0fcf , commit 2b8ea7f (05 марта 2018 г.), commit fecc6f3 a href = "https://github.com/git/git/commit/23fea4c240218d519da01e6d2d64264084a7334c" rel = "nofollow noreferrer"> commit 23fea4c , совершают 902f414 (01 марта 2018), а commit 11489a6 , commit e4d671c , Филиппа Вуда (phillipwood) .
(Объединено с Junio ​​C Hamano - gitster - в commit 436d18f , 14 марта 2018 г.)

  

add -p: скорректировать смещения последующих блоков, когда они пропущены

(добавить, но опять же, можно применить к тайнику)

  

Поскольку commit 8cbd431 ("git-add--interactive: заменить лом   пересчет с apply --recount ", 2008-7-2, Git v1.6.0-rc0), если кусок пропущен, то мы полагаемся на строки контекста, чтобы применить последующие фрагменты справа   место.

     

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

     

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

Вы можете увидеть некоторые тесты здесь .


Git 2.19 улучшает git add -p: когда пользователь редактирует патч в "git add -p ", а редактор пользователя настроен на произвольное удаление конечных пробелов, пустая строка, которая не изменяется в патче, станет полностью пустой (вместо строки с единственным SP на нем).
Код, введенный в таймфрейме Git 2.17, не смог разобрать такой патч, но теперь он научился замечать ситуацию и справляться с ней.

См. commit f4d35a6 (11 июня 2018 г.) по Филипп Вуд (phillipwood) .
(Объединено с Junio ​​C Hamano - gitster - в commit 5eb8da8 , 28 июня 2018 г.)

  

add -p: исправлен подсчет пустых строк контекста в отредактированных патчах

     

recount_edited_hunk(), представленный в commit 2b8ea7f ("add -p:   вычислить дельту смещения для отредактированных исправлений ", 2018-03-05, Git v2.17.0) требуется, чтобы все строки контекста начинались с пробела, пустые строки не учитываются.
  Это было сделано для того, чтобы избежать каких-либо проблем с пересчетом, если пользователь вводил пустые строки в конце при редактировании патча.

     

Однако это ввело регрессию в 'git add -p', так как редакторы, как правило, удаляют конечные пробелы из пустых строк контекста. когда патчи редактируются, тем самым вводя пустые строки, которые должны быть   подсчитывали.
  «git apply» знает, как обращаться с такими пустыми строками, и POSIX сообщает, что наличие или отсутствие пробела в пустой контекстной строке определяется реализацией (см. команда diff ).

     

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

ответил VonC 17 MaramSat, 17 Mar 2018 02:54:54 +03002018-03-17T02:54:54+03:0002 2018, 02:54:54
0

Это происходит для меня всякий раз, когда я пытаюсь разбить кусок на более мелкие фрагменты, которые расположены слишком близко друг к другу (менее 3 строк между изменениями). Краткое объяснение состоит в том, что в патче есть контекстные строки, которые конфликтуют с вашими локальными изменениями. Более полное объяснение ниже.


Предположим, у меня есть git-репо со следующими незафиксированными изменениями:

--- a/pangram
+++ b/pangram
@@ -1,8 +1,8 @@
 The
-quick
+relatively quick
 brown
 fox
-jumps
+walks
 over
 the
 lazy

Если я прячу первое изменение, я получаю:

--- a/pangram
+++ b/pangram
@@ -1,5 +1,5 @@
 The
-quick
+relatively quick
 brown
 fox
 jumps

Команда git stash действительно успешно сохранила исправление (проверьте git stash list), но затем git использует этот патч в обратном порядке, чтобы удалить сохраненные изменения из моего рабочего каталога. Контекст после фрагмента имеет «скачки», которые не соответствуют «прогулкам» в моем рабочем каталоге. Так что Git выручает с

ошибка: патч не выполнен: панграмма: 1
ошибка: панграмма: патч не применяется
Невозможно удалить изменения рабочего дерева

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


Я бы назвал это ошибкой в ​​поддержке разбиения фрагментов в git. Если он знает, что разделяет изменения слишком близко, он может сбрить несколько строк контекста из патча или изменить его, чтобы иметь измененные строки контекста вместо первоначальных. В качестве альтернативы, если разделение фрагментов в этом закрытии официально не поддерживается, оно фактически должно отказаться от разделения фрагментов в этом закрытии.

ответил Mu Mind 7 +04002012-10-07T01:08:57+04:00312012bEurope/MoscowSun, 07 Oct 2012 01:08:57 +0400 2012, 01:08:57
0

После того, как произошел сбой git stash -p таким же образом, мне повезло с этим обходным решением (git 2.0.2):

  • git add -p, разделяя те же самые фрагменты, но с обратными ответами (от "y" до add «сохраняет» изменения, от «n» до stash сохраняет изменения.)
  • git stash -k, чтобы сохранить индекс и спрятать все остальное
  • git reset, чтобы продолжить работу над моими файлами

Я не уверен, почему git add -p не удалось так же, как git stash -p сделал. Я думаю, потому что добавление работает с индексом, а не создает файл патча?

ответил Johann 17 +04002014-10-17T04:34:32+04:00312014bEurope/MoscowFri, 17 Oct 2014 04:34:32 +0400 2014, 04:34:32
0

Принятый ответ на данный момент может, к сожалению, потерпеть неудачу, даже в Git 2.17.

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

git stash show -p | patch -p1 -R

Это не удастся с отклонениями, но шансы хорошие, большинство блоков будет применено правильно и, по крайней мере, сэкономит вам время повторного просмотра всех файлов.

ответил Elliott Slaughter 7 PMpSat, 07 Apr 2018 23:46:34 +030046Saturday 2018, 23:46:34
0

Применение состояния может привести к конфликту; в этом случае он не удаляется из списка. Вам нужно разрешить конфликты вручную и вручную вызвать git stash drop

ответил dean jase 22 J000000Friday11 2011, 03:16:24

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132