Отмена всплывающего окна в Git

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

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

Ответ 1

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

Обратное слияние требует, чтобы все текущие изменения были перенесены в индекс:

  • git add -u

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

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

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

Здесь пример, показывающий, как рабочая копия (через 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 [email protected]{0}: -- $(git write-tree) [email protected]{0}^1
Auto-merging foo.c
 $ git status
# On branch trunk
nothing to commit (working directory clean)

Ответ 2

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

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

Легко.

Ответ 3

Изменить: из документации git help stash в поп-секции:

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

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

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

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

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

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

===

Я пытаюсь воспроизвести вашу проблему, но все, что я получаю, когда usin 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

Я не вижу, что git пытается объединить мои изменения, он просто терпит неудачу. У вас есть какие-либо действия, которые мы можем выполнить, чтобы помочь вам?

Ответ 4

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

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

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) Избавьтесь от исправления patch/unpatch

git rebase -i HEAD^^^

удалите две строки с "слиянием" и "обратным патчем" в нем.

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

git reset HEAD^

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

Ответ 5

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

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

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

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

Ответ 6

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

Ответ 7

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

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

Ответ 8

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

Ответ 9

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

git reset .
git checkout .
git clean -f

Ответ 10

Если не было никаких ступенчатых изменений до git stash pop, как в вопросе, тогда должны работать следующие две команды.

git diff --name-only --cached | xargs git checkout --ours HEAD
git ls-tree [email protected]{0}^3 --name-only | xargs rm

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

От man git stash: The working directory must match the index. Какой @DavidG указывает, stash pop не удастся, если конфликтуют конфликтующие файлы, которые в настоящее время не обработаны. Таким образом, нам не нужно беспокоиться о том, чтобы разматывать конфликты слияния, не возвращаясь к HEAD. Любые оставшиеся измененные файлы затем не привязаны к кошельку и были изменены до stash pop

Если бы были поэтапные изменения, я не понимаю, можем ли мы полагаться на одни и те же команды, и вы можете попробовать использовать метод @Ben Jackson. Предложения оценены.

Вот настройка тестирования для всех различных случаев https://gist.github.com/here/4f3af6dafdb4ca15e804

# Result:
# Merge succeeded in m (theirs)
# Conflict in b
# Unstaged in a
# Untracked in c and d

# Goal:
# Reverse changes to successful merge m
# Keep our version in merge conflict b
# Keep our unstaged a
# Keep our untracked d
# Delete stashed untracked c

Ответ 11

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

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

Простой git reset HEAD прервал разрешение конфликта и оставил незафиксированные (и UNWANTED) изменения.

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