git stash и отредактированные скряги

Мне очень нравятся git add -p и git stash, но иногда у меня возникает следующая проблема, которая воспроизводится следующей последовательностью команд:

  • git add -p my_file: затем я редактирую кусок вручную (используя e), потому что разделение, которое предлагает git, мне не подходит
  • git stash --keep-index: затем я провожу небольшое тестирование, и если тесты проходят, не фиксирую
  • git stash pop: теперь возникает проблема: файл my_file теперь считается конфликтующим, а git полностью испортил мой отредактированный кусок, поэтому мне нужно отредактировать файл, удалить ненужные метки слияния и запустить git add my_file за которым следует git reset HEAD

Я озадачен, потому что это происходит только при редактировании лома вручную. Я не понимаю, как это вообще должно иметь значение.


Чтобы воспроизвести проблему:

  • touch newfile
  • git add newfile
  • git commit -m 'newfile'
  • добавить две строчки в файл
  • git add -p newfile
  • отредактируйте блок (e), удалите одну из строк в блоке, затем выйдите из git add (q)
  • git stash --keep-index
  • git stash pop

Теперь файл newfile находится в несмешанном состоянии. Обратите внимание, что проблема возникает только с фрагментами, отредактированными вручную. Нет никаких проблем с приведенными выше командами, если вы не редактируете какой-либо кусок вручную.

Между прочим, предыдущее состояние файла находится на третьем этапе (git show :3:newfile), а ранее подготовленная версия находится на втором этапе (git show :2:newfile). Таким образом, я мог бы с помощью какой-то черной магии git поместить вторую стадию в этот индекс и третью стадию в рабочее репо ... но я не знаю, как это сделать, поэтому делаю это вручную. :-(


person Olivier Verdier    schedule 30.10.2010    source источник
comment
Я пробовал несколько раз, но не могу воспроизвести вашу проблему с git версии 1.7.2.3. Какую версию ты используешь?   -  person Sven Marnach    schedule 31.10.2010
comment
Я использую версию 1.7.3.1 в Mac OS X.   -  person Olivier Verdier    schedule 31.10.2010
comment
Попробовал еще раз с разными случайными правками в git add -p - и у меня это всегда работает нормально. Кстати, я на Linux. Похоже на ошибку - я бы рекомендовал спросить в списке рассылки git, они довольно быстро реагируют.   -  person Sven Marnach    schedule 31.10.2010
comment
Согласно списку рассылки, это не ошибка, это ожидаемое поведение. Но я не понимаю, почему ...   -  person Olivier Verdier    schedule 03.11.2010
comment
Ответ Фрэнка решает проблему.   -  person axk    schedule 14.10.2011


Ответы (3)


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

git add --patch <files>

git stash --keep-index

<test the indexed changes>

git reset --hard

git stash pop --index

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

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

person frank    schedule 14.03.2011
comment
+1, это работает. Я сам пришел к тому же решению, но пропустил переключатель --index. Это логичный способ сделать что-то, учитывая, что он хранит как индекс, так и неустановленные изменения, поэтому, чтобы избежать конфликта слияния между поэтапными изменениями в рабочей копии и в спрятанных, необходимо сначала удалить их из рабочей копии (т. Е. Сделать хард ресет). - person axk; 14.10.2011

Я задал вопрос в списке рассылки git. Я описываю ожидаемое поведение. Это не ошибка. :-(

Вот ответ, который я получил:

Если вы не редактировали фрагмент вручную, каждый фрагмент будет либо в состоянии HEAD, либо в состоянии A, и применение разницы между HEAD и A к такому файлу будет либо без операции (фрагмент уже применен), либо с успешным приложением. .

Для меня это серьезное ограничение git add --patch, и я не понимаю, каким образом такое поведение может быть кому-то полезно, но я научусь жить с этим.

person Olivier Verdier    schedule 03.11.2010
comment
Похоже, проблема в том, что когда вы выполняете git stash --keep-index, он сохраняет как поэтапные, так и неустановленные изменения, с той лишь разницей, что он сохраняет поэтапные изменения в рабочей копии. И когда вы пытаетесь применить тайник, поэтапные изменения находятся как в рабочей копии, так и в тайнике, вызывая конфликт. В случае неотредактированных блоков, когда они ответили, он запоминает, какие блоки присутствуют в рабочей копии, а какие нет, и не применяет единожды присутствующие, избегая конфликтов слияния. Для отредактированного фрагмента применяется только его часть, это не годится. - person axk; 14.10.2011

git stash --keep-index сохраняет ваш индекс, но по-прежнему добавляет его содержимое как часть тайника.

Попробуйте git stash save -p - немного утомительнее сохранить тайник, но, вероятно, вы сделаете то, что хотите.

person bstpierre    schedule 31.10.2010
comment
Как это объясняет, что git считает, что конфликт существует только, когда у меня есть отредактированный вручную фрагмент? - person Olivier Verdier; 31.10.2010
comment
Потому что ваши индексы не совпадают, когда вы git stash pop. - person Scott; 01.11.2010
comment
@Scott: извините, я не понимаю вашего ответа ...: - / почему возникает конфликт только тогда, когда был вручную отредактированный кусок? - person Olivier Verdier; 01.11.2010
comment
@Olivier - см. Комментарий Свена выше: стоит спросить в списке git, чтобы узнать, нашли ли вы ошибку. - person bstpierre; 01.11.2010