Подтвердить что ты не робот

`git stash` во время конфликта слияния

Мы сделали что-то плохое.

Мы побежали git stash save во время конфликта слияния, и теперь мы не можем восстановить нашу работу.

Что мы пробовали:

git pull -Xours origin master
git stash apply --index

и

 git pull origin master
 git stash save --keep-index "merge conflicts"
 git stash apply [email protected]{1}

Пожалуйста, помогите!

4b9b3361

Ответ 1

Проблема заключается в том, что git stash не сохраняет ссылку на ветку, которую вы пытались объединить. Во время слияния это сохраняется в файле с именем MERGE_HEAD.

Чтобы исправить это и вернуться к предыдущему состоянию, вам нужно найти ревизию (пусть она притворяется d7a9884a380f81b2fbf002442ee9c9eaf34ff68d), которую вы пытались объединить, и установить MERGE_HEAD после применения тарелки.

Затем вы можете применить stash (с -index для повторной настройки всего, что было поставлено раньше) и установить MERGE_HEAD:

git stash apply --index
git update-ref MERGE_HEAD d7a9884a380f81b2fbf002442ee9c9eaf34ff68d

Ответ 2

Учитывая ваш последний комментарий: вы можете использовать

git stash megre --no-commit <branch>

чтобы поместить индекс в состояние "слияния" без внесения изменений

затем измените его тем, что вы хотите:

если вы уже разработали свое слияние в тире:

git reset #to remove the "conflicts" flags
git checkout <initial commit> -- ./ #to revert everything to the previous working state,
git stash apply   #apply your changes

и как только все будет в желаемом состоянии, git commit


О bukzor комментарий: на самом деле существует большая разница между git checkout <tree-ish> и git checkout <tree-ish> -- <files>.

Из ссылка на git checkout

  • git checkout <branch>: эта форма переключает ветки, обновляя индекс, рабочее дерево и HEAD, чтобы отразить указанную ветку или зафиксировать.

  • git checkout [-p|--patch] <tree-ish> -- <pathspec>: Когда <paths> или --patch, git checkout не переключает ветки. Он обновляет именованные пути в рабочем дереве из индексного файла или из имени < tree-ish > (чаще всего коммит).

git checkout <initial commit> действительно отбрасывает информацию о слиянии.

git checkout <initial commit> -- ./ (обратите внимание на дополнительный -- ./), с другой стороны, сохранит информацию о слиянии и вернет каждый отслеживаемый файл в свое состояние в <initial commit>.

Ответ 3

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

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

$ git status
# Changes not staged for commit:
#   (use "git add <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
#   modified:   myproject/src/main/java/com/acme/package3/Class3.java
#   modified:   myproject/src/main/java/com/acme/package3/Class4.java
#

Затем я создал патч и reset ветвь назад в состояние предварительного слияния:

$ git diff HEAD > ~/merge-with-resolved-conflicts.patch
$ git reset --hard HEAD

Затем я создал временную ветвь (полученную из ветки назначения слияния) и применил исправление:

$ git checkout -b my-temp-branch
$ git apply ~/merge-with-resolved-conflicts.patch
$ git commit -a -m "Merge with resolved conflicts"

Итак, HEAD my-temp-branch теперь содержит все, что было объединено, включая файлы с разрешенными конфликтами и файлы с оставшимися конфликтами.

Затем я переключился на исходную ветвь, снова слился и посмотрел на статус git

$ git checkout my-branch
$ git merge other-branch
$ git status

Статус показывает полный список файлов с конфликтами:

# Unmerged paths:
#   (use "git add <file>..." to mark resolution)
#
#   both modified:      myproject/src/main/java/com/acme/package1/Class1.java
#   both modified:      myproject/src/main/java/com/acme/package2/Class2.java
#   both modified:      myproject/src/main/java/com/acme/package3/Class3.java
#   both modified:      myproject/src/main/java/com/acme/package3/Class4.java
#

Теперь мне нужно было сравнить эти два списка файлов. Любые файлы во втором списке, но не первый, уже были разрешены (в этом примере Class1.java и Class2.java). Поэтому для каждого из этих файлов я вытащил версию с конфликтами, разрешенными из временной ветки (например, cherry-pick, но для отдельных файлов, а не для целой фиксации):

$ git checkout my-temp-branch myproject/src/main/java/com/acme/package1/Class1.java
$ git checkout my-temp-branch myproject/src/main/java/com/acme/package2/Class2.java

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

Ответ 4

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

Убедитесь, что вы действительно сделали кошелек. См. Вывод git stauts и git stash show

Ответ 5

Мое решение выйти из этого (git всплывающее окно при конфликте слияния):

  • создать и проверить новый (локальный) ветвь mytemporarybranch

    git ветвь mytemporarybranch && & git checkout mytemporarybranch

  • зафиксировать в этой mytemporarybranch

    git commit -m "мое беспорядочное слияние и сквош"

  • checkout myoriginalbranch

    git checkout myoriginalbranch

  • сливаться правильно (ни один сквош поп/не применим на этот раз!)

  • squash объединить mytemporarybranch на ветку миоригина.

    git merge --squash mytemporarybranch