`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}
Пожалуйста, помогите!
Ответы
Ответ 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