Как разрешить конфликт git stash без фиксации?

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

Мой текущий подход очень непонятен, потому что я делаю это следующим образом:

git stash pop -> CONFLICT
git stash drop
[resolve conflict]
[add conflict files]
git reset HEAD <all files that are in commit-mode>

[Обновить] Способ воспроизведения:

mkdir foo; cd foo; git init
echo "1" > one
echo "2" > two
git add -A; git commit -m "first"
echo "1.1" > one
echo "2.1" > two
git stash
echo "2.2" > two
git commit -a -m "second"
echo "Only this file would stay in HEAD without the conflict" > third
git add third
git stash pop
git status

2016-06-27: Добавлен новый файл под названием "третий", чтобы показать, что обходные решения, такие как решение от scy, работают только для пустых HEAD, но не исправляют начальную проблему, в которой HEAD не имеет такое же содержимое, как и для git stash pop без конфликта.

Ответы

Ответ 1

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

git status говорит:

# On branch master
# Unmerged paths:
#   (use "git reset HEAD <file>..." to unstage)
#   (use "git add/rm <file>..." as appropriate to mark resolution)
#
#   both modified:      src/js/globals.tpl.js
no changes added to commit (use "git add" and/or "git commit -a")

Хорошо. Я решил пойти с предложением Git: я разрешил конфликт и совершил:

vim src/js/globals.tpl.js
# type type type …
git commit -a -m WIP   # (short for "work in progress")

Теперь моя рабочая копия находится в состоянии, которое я хочу, но я создал коммит, который я не хочу иметь. Как мне избавиться от этой фиксации без изменения моей рабочей копии? Подождите, там есть популярная команда!

git reset HEAD^

Моя рабочая копия не была изменена, но фиксация WIP исчезла. Это именно то, что я хотел! (Обратите внимание, что здесь я не использую --soft, потому что если в вашем кошельке есть файлы с автоматическим объединением, они автоматически ставятся и, следовательно, вы закончите тем, что эти файлы будут снова поставлены после reset.)

Но осталась еще одна вещь: Страница man для git stash pop напоминает нам, что "Применение состояния может привести к сбою с конфликтами, в этом случае оно не будет удалено из списка. Вам нужно разрешить конфликты вручную и вызовите git stash drop вручную после этого." Итак, что именно мы делаем сейчас:

git stash drop

И сделано.

Ответ 2

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

Следующее решение кажется мне намного более чистым, а также предложило Git - выполнить git status в репозитории с конфликтом:

Unmerged paths:
  (use "git reset HEAD <file>..." to unstage)
  (use "git add <file>..." to mark resolution)

Давайте сделаем то, что предлагает Git без каких-либо фиксаций:

  • Вручную (или с помощью какого-либо инструмента слияния GUI) разрешите конфликт (ы).
  • Используйте git reset, чтобы отмечать конфликты (конфликты) как разрешенные и неактивные изменения. Вы можете выполнить его без каких-либо параметров, а Git удалит все из индекса. Вам не нужно выполнять git add раньше.
  • Наконец, удалите stash с git stash drop, потому что Git не делает этого в конфликте.

Итак:

$ git stash pop

# ...manually resolve conflict(s)

$ git reset

$ git stash drop

Примечание. добавление файлов в индекс после разрешения конфликта является целенаправленным. Таким образом, вы можете отличить изменения от предыдущего тайника и изменения, внесенные вами после разрешения конфликта. Если вам это не нравится, вы всегда можете использовать git reset, чтобы удалить все из индекса.

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

Ответ 3

Вместо добавления изменений, которые вы делаете для разрешения конфликта, вы можете использовать git reset HEAD file для разрешения конфликта без изменения ваших изменений.

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

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

Ответ 4

git checkout stash -- .

работал у меня.

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

Ответ 5

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

git stash apply --index

вот полное объяснение:

http://git-scm.com/book/en/Git-Tools-Stashing

Ответ 6

git stash branch будет работать, что создает для вас новую ветку, проверяет фиксация, на которой вы были, когда вы спрятали свою работу, снова использует вашу работу и затем сбрасывает тайник, если он применяется успешно. this

Ответ 7

Самый быстрый способ, который я нашел, - разрешить конфликт, затем сделать git add -u, а затем сделать git reset HEAD, который даже не связан с фиксацией.

Ответ 8

В соответствии с git вопросами по типу после фиксации конфликта git add <file> - правильный курс действий.

После прочтения этого комментария я понял, что изменения автоматически добавляются в индекс (по дизайну). Поэтому git add <file> завершает процесс разрешения конфликтов.

Ответ 9

git add .
git reset

git add . будет обрабатывать ВСЕ файлы, сообщающие git, что вы разрешили конфликт

git reset будет отключать ВСЕ поставленные файлы без создания фиксации