Прерывание всплывающего окна в Git - PullRequest
217 голосов
/ 15 декабря 2011

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

Я пытался git merge --abort, но git утверждал, что слияние не происходит. Есть ли простой способ прервать всплывающее окно, не разрушая изменения, которые у меня были изначально в каталоге?

Ответы [ 12 ]

226 голосов
/ 07 апреля 2015

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

git reset HEAD --hard
git checkout my_correct_branch
git stash pop

Easy.

44 голосов
/ 22 января 2013

Хорошо, я думаю, что сработал "git stash unapply".Это сложнее, чем git apply --reverse, потому что вам нужно действие обратного объединения в случае, если с помощью git stash apply.

было выполнено какое-либо объединение. Для обратного объединения требуется вставить все текущие изменения в индекс:

  • git add -u

Затем инвертируйте merge-recursive, что было сделано git stash apply:

  • git merge-recursive stash@{0}: -- $(git write-tree) stash@{0}^1

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

Учитывая, что ваш исходный git stash apply не удался, я предполагаю, что обратное также может не сработать, так как некоторые вещи, которые он хочет отменить, не были выполнены.1025 *

Вот пример, показывающий, как рабочая копия (через git status) снова становится чистой:

 $ git status
# On branch trunk
nothing to commit (working directory clean)
 $ git stash apply
Auto-merging foo.c
# On branch trunk
# Changed but not updated:
#   (use "git add <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
#       modified:   foo.c
#
no changes added to commit (use "git add" and/or "git commit -a")
 $ git add -u
 $ git merge-recursive stash@{0}: -- $(git write-tree) stash@{0}^1
Auto-merging foo.c
 $ git status
# On branch trunk
nothing to commit (working directory clean)
43 голосов
/ 12 ноября 2012

Редактировать: из документации git help stash в секции pop:

Применение состояния может завершиться с конфликтом; в этом случае он не удаляется из списка. Вам нужно разрешить конфликты вручную и вручную вызвать git stash drop.

Если используется опция --index, то пытается восстановить не только изменения рабочего дерева, но и изменения индекса. Однако это может не сработать, если у вас есть конфликты (которые хранятся в индексе, и поэтому вы больше не можете применять изменения, как они были изначально).

Попробуйте скопировать все ваши репо в новый каталог (чтобы у вас была его копия) и запустите:

git stash show и сохраните этот вывод где-нибудь, если вам это нужно.

затем: git stash drop, чтобы выбросить конфликтующий тайник затем: git reset HEAD

Это должно оставить ваше репо в том состоянии, в котором оно было раньше (надеюсь, я все еще не смог воспроизвести вашу проблему)

===

Я пытаюсь воспроизвести вашу проблему, но все, что я получаю при использовании git stash pop, это:

error: Your local changes to the following files would be overwritten by merge:
...
Please, commit your changes or stash them before you can merge.
Aborting

В чистом виде:

git init
echo hello world > a
git add a & git commit -m "a"
echo hallo welt >> a
echo hello world > b
git add b & git commit -m "b"
echo hallo welt >> b
git stash
echo hola mundo >> a
git stash pop

Я не вижу мерзавца, пытающегося объединить мои изменения, он просто терпит неудачу. Есть ли у вас какие-либо шаги по репро, которые мы можем выполнить, чтобы помочь вам?

6 голосов
/ 26 марта 2015

Если вам не нужно беспокоиться о любых других внесенных вами изменениях и вы просто хотите вернуться к последнему коммиту, тогда вы можете сделать:

4 голосов
/ 22 января 2013

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

СДЕЛАЙТЕ РЕЗЕРВНОЕ КОПИРОВАНИЕ ПЕРЕД !!Я не знаю, сработает ли это для вас, поэтому скопируйте весь репозиторий на тот случай, если он не сработает.

1) Исправьте проблемы слияния и устраните все конфликты, выбрав все изменения, которые появятсяиз патча (в tortoisemerge это отображается как единое целое. REMOETE (их)).

git mergetool

2) Зафиксируйте эти изменения (они уже будут добавлены с помощью команды mergetool).Дайте ему сообщение коммита «слияние» или что-то, что вы помните.

git commit -m "merge"

3) Теперь у вас по-прежнему будут локальные неотмеченные изменения, которые вы начали изначально, с новым коммитом из патча (мы можем избавиться от этого позже).Теперь внесите ваши неустановленные изменения

git add .
git add -u .
git commit -m "local changes"

4) Отмените патч.Это можно сделать с помощью следующей команды:

git stash show -p | git apply -R

5) Зафиксируйте эти изменения:

git commit -a -m "reversed patch"

6) Избавьтесь от изменений патча / открепления

git rebase -i HEAD^^^

, удалите две строки с 'merge' и 'reversed patch' в нем.

7) Верните ваши неизменные изменения и отмените фиксацию «локальных изменений»

git reset HEAD^

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

3 голосов
/ 20 января 2017

Я решил это несколько иначе. Вот что случилось.

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

Простой git reset HEAD прервал разрешение конфликта и оставил незафиксированные (и НЕОБХОДИМЫЕ ) изменения.

Несколько git co <filename> вернули индекс в исходное состояние. Наконец, я переключил ветку с git co <branch-name> и запустил новый git stash pop, который разрешился без конфликтов.

2 голосов
/ 15 ноября 2012

Некоторые идеи:

  • Используйте git mergetool для разделения файлов слияния на оригинальные и новые части.Надеюсь, одним из них является файл с вашими изменениями, не являющимися тайниками.

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

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

1 голос
/ 19 января 2013

Если DavidG прав, что он не выдвинул тайник из-за конфликта слияния, тогда вам просто нужно очистить ваш рабочий каталог. Быстро git commit все, что тебя волнует. (Вы можете reset или squash сделать коммит позже, если вы еще не закончили.) Тогда со всем, что вам небезразлично, git reset все остальное, что git stash pop выгрузит в ваш рабочий каталог.

1 голос
/ 18 января 2013

Я мог бы воспроизвести чистый git stash pop в «грязном» каталоге, с незафиксированными изменениями, но пока не всплывающим, что вызывает конфликт слияния.

Если при конфликте слияния тайник, который вы пытались применить, не исчез, вы можете попробовать просмотреть git show stash@{0} (опционально с --ours или --theirs) и сравнить с git statis git diff HEAD. Вы должны увидеть, какие изменения произошли от применения тайника.

1 голос
/ 16 декабря 2011

Используйте git reflog, чтобы получить список всех изменений, внесенных в вашу историю Git.Скопируйте идентификатор действия и введите git reset ACTION_ID

...