Я пытаюсь взять ветку с изменениями и вернуть ее, чтобы она была идентичной тому апстриму, от которого она расходилась. Изменения как местные , так и не были вытеснены на GitHub, так что ни один git reset
или git rebase
действительно жизнеспособны, так как они меняют историю, что это плохо с ответвлением , которая уже была нажата.
Я также пробовал использовать git merge
различные стратегии, но ни одна из них не отменяет локальные изменения, то есть, если бы я добавил файл, слияние могло бы вернуть другие файлы в очередь, но у меня все равно будет тот файл, которого нет у восходящего потока иметь.
Я мог бы просто создать новую ветку в восходящем потоке, но мне бы очень хотелось, чтобы слияние, с точки зрения истории ревизий, применяло все изменения, чтобы взять мою ветку и снова сделать ее идентичной восходящей, чтобы я мог безопасно отправить это изменение без затирания истории. Есть такая команда или серия команд?
источник
Ответы:
Вы можете объединить свою восходящую ветку со своей
dev
веткой с помощью специального драйвера слияния «keepTheirs» :см. « «
git merge -s theirs
»Необходимо, но я знаю, что его не существует ».В вашем случае
.gitattributes
потребуется только один и такойkeepTheirs
сценарий:git merge --strategy=theirs
Симулятор # 1Отображается как слияние с восходящим потоком в качестве первого родителя.
Джефроми упоминает (в комментариях)
merge -s ours
, объединив вашу работу в восходящем потоке (или во временной ветке, начиная с восходящего потока), а затем переместив вашу ветку вперед к результату этого слияния:(Изменить 2011):
OP сообщил об этом рабочем процессе в этом сообщении в блоге :
git merge --strategy=theirs
Симулятор # 2Отображается как слияние с нашим в качестве первого родителя.
(предложено jcwenger )
git merge --strategy=theirs
Симулятор # 3В этом сообщении в блоге упоминается :
git merge --strategy=theirs
Симулятор # 4(тот же пост в блоге)
git merge --strategy=theirs
Симулятор # 5(предложено Бараком А. Перлмуттером ):
git merge --strategy=theirs
Симулятор # 6(предложено все тем же Майклом Гебецройтером ):
git merge --strategy=theirs
Симулятор # 7источник
git checkout upstream; git merge -s ours downstream; git checkout downstream; git merge upstream
. (При необходимости используйте временную ветвь в восходящем направлении.) Это дает преимущество записи вышестоящего предка в качестве первого родителя, так что слияние означает «поглотить эту устаревшую ветвь темы», а не «уничтожить эту ветвь темы и заменить это с апстримом ».Мне кажется, вам просто нужно сделать:
Если нет изменений для продвижения вверх по течению, и вы просто хотите, чтобы восходящая ветвь была вашей текущей ветвью, это сделает это. Делать это локально не вредно, но вы потеряете все локальные изменения **, которые не были отправлены в мастер.
** На самом деле изменения все еще присутствуют, если вы зафиксировали их локально, так как коммиты все еще будут в вашем
git reflog
, обычно в течение как минимум 30 дней.источник
Теперь это можно сделать довольно легко:
Это синхронизирует ваше локальное репо с источником и сохраняет историю.
источник
git merge -s recursive -Xtheirs
не объединяет двоичные файлы автоматически, поэтому вы попадаете в конфликтную ситуацию, которую нужно разрешать вручную. Рабочие процессы на основеgit merge -s ours
этого не страдают.git show
при фиксации слияния отображаются только разрешения конфликтов, и-Xtheirs
, очевидно, нет разрешения конфликтов, если они используются.Еще одна симуляция для
git merge -s theirs ref-to-be-merged
:Альтернативой двойному сбросу будет применение обратного патча:
источник
HEAD^2
) Метод исправления сработал.^
неправильно. Иногда другие нажатия клавиш, такие как «ctrl-c», отображаются как «^ C». - Если вы действительно набрали правильный "^", вы обнаружили серьезную ошибку в своей версии git.git reset --hard HEAD^^2; git reset --soft HEAD@{1}
Также есть способ с небольшой помощью команды сантехников - ИМХО, самый простой. Скажем, вы хотите подражать «их» для случая с двумя ветвями:
Это объединяет произвольное количество голов (2 в приведенном выше примере), используя дерево одной из них (полоса в приведенном выше примере, предоставляющая дерево «их»), игнорируя любые проблемы с различиями / файлами (дерево фиксации - это команда низкого уровня, поэтому она не заботится о них). Обратите внимание, что голова может быть только 1 (что эквивалентно выбору вишни с «их»).
Обратите внимание, что родительский заголовок указывается первым, может влиять на некоторые вещи (см., Например, --first-parent команды git-log), так что имейте это в виду.
Вместо git-show можно использовать все, что может выводить дерево и хэши фиксации - все, что используется для синтаксического анализа (cat-file, rev-list, ...). Вы можете следить за всем с помощью git commit --amend, чтобы интерактивно украсить сообщение фиксации.
источник
Тяжелая рука, но черт возьми, что может пойти не так?
cp -r .git /tmp
git checkout y
rm -rf .git && cp -r /tmp/.git
.источник
перейдите в удаленную ветвь восходящего потока и выполните операцию
git merge
со стратегией слияния, установленной наours
.Вся история по-прежнему будет присутствовать, но у вас будет дополнительная фиксация слияния. Здесь важно начать с версии, в которой вы хотите быть, и слиться
ours
с веткой, в которой находится github.источник
--strategy=theirs
, за исключением того, что самое близкое--strategy=recursive -X=theirs
не совсем так.--strategy=theirs
прямо противоположно--strategy=ours
. Вы начинаете с противоположного конца (так что начните с github и выполните слияние другим способом).--strategy=theirs
, в чем проблема. Ближайший из--strategy=recursive -X theirs
них не совсем противоположный, поскольку он не удалит посторонние локальные изменения, если они не конфликтуют.git checkout dev; git merge origin/master --strategy=ours
иgit checkout origin/master; git merge dev --strategy=ours
ours
стратегии дает возможность полностью реализоватьtheirs
стратегию.Используйте git reset НАЗАД!
Вы можете сделать ветку похожей на любую другую фиксацию
git reset
, но вы должны делать это круговым способом.Чтобы ветка при фиксации
<old>
выглядела как фиксация<new>
, вы можете сделатьчтобы сделать
<new>
содержимое рабочего дерева.Тогда сделай
чтобы вернуть ветку к исходной фиксации, но оставив рабочее дерево в
<new>
состоянии .Затем вы можете добавить и зафиксировать изменения, чтобы ваша ветка точно соответствовала содержимому
<new>
фиксации.Это противоречит интуиции, что для перехода из
<old>
состояния в состояние<new>
вам нужно выполнитьgit reset
от<new>
до<old>
. Однако с этой опцией--mixed
рабочее дерево остается,<new>
а указатель ветки установлен на<old>
, так что, когда изменения зафиксированы, ветка выглядит так, как мы хотим.Предупреждение
Не теряйте отслеживание своих коммитов, например, забывайте, что
<old>
делаете, когда делаетеgit reset --hard <new>
.источник
Я следил за этими ролями:
Получение источника, жесткий сброс из ветки, затем рекурсивный из их, а затем принудительное нажатие на ветку
НА СВОЙ СОБСТВЕННЫЙ РИСК
источник