`git stash` во время конфликта слияния - PullRequest
23 голосов
/ 25 января 2012

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

Мы запустили 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 stash@{1}

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

Ответы [ 5 ]

24 голосов
/ 21 сентября 2012

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

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

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

git stash apply --index
git update-ref MERGE_HEAD d7a9884a380f81b2fbf002442ee9c9eaf34ff68d
1 голос
/ 10 августа 2013

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

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

$ 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
#

Затем я создал патч и сбросил ветку обратно до предварительной.состояние слияния:

$ 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"

Итак, ГОЛОВА 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

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

0 голосов
/ 21 ноября 2013

Мое решение выйти из этого (git stash pop во время конфликта слияния) было:

  • создать и оформить новый (местный) филиал mytevenbranch

    git branch mytevenbranch && git checkout mytevenbranch

  • совершить в этом mytevenbranch

    git commit -m "мое грязное слияние и сквош"

  • оформить заказ myoriginalfranch

    git checkout myoriginalbranch

  • объединить правильно (без всплывающих окон / применить на этот раз!)

  • сквош слияние mytevenfranch на myoriginal ветку

    git merge - сквош mytevenbranch

0 голосов
/ 21 сентября 2012

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

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>: Когда заданы или --patch, git checkout не переключает ветви.Он обновляет именованные пути в рабочем дереве из файла индекса или из именованного(чаще всего коммит).

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

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

0 голосов
/ 26 января 2012

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

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

...