Как мне восстановить / повторно синхронизировать после того, как кто-то отправил перебазирование или сброс в опубликованную ветку?

StackOverflow https://stackoverflow.com/questions/4084868

Вопрос

Мы все слышали, что никогда не следует переделывать опубликованные работы, что это опасно и т.д.Однако я не видел опубликованных рецептов того, как справиться с ситуацией в случае перебазирования является опубликовано.

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

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

git fetch
git checkout foo
git reset --hard origin/foo

Это просто отбросит локальное состояние foo в пользу его истории в соответствии с удаленным репозиторием.

Но как справиться с ситуацией, если кто-то внес существенные локальные изменения в эту ветку?

Это было полезно?

Решение

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

git checkout foo
git branch old-foo origin/foo # BEFORE fetching!!
git fetch
git rebase --onto origin/foo old-foo foo
git branch -D old-foo

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

Ресирование похоже на насилие: если это не решает вашу проблему, вам просто нужно больше этого. ☺.

Вы можете сделать это без закладки, конечно, если вы посмотрите на добеду origin/foo Примите удостоверение личности и используйте это.

Это также как вы занимаетесь ситуацией, когда вы забыли сделать закладку до забрать. Ничего не потеряно - вам просто нужно проверить Refricge для удаленной ветви:

git reflog show origin/foo | awk '
    PRINT_NEXT==1 { print $1; exit }
    /fetch: forced-update/ { PRINT_NEXT=1 }'

Это будет распечатать идентификатор фиксации, который origin/foo указал до самой последней приемы, которая изменила свою историю.

Вы можете просто просто

git rebase --onto origin/foo $ Commit. foo

Другие советы

Я бы сказал Восстановление из Upstream Rabase Раздел страницы человека GIT-REBASE охватывает в значительной степени все это.

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

Начиная с git 1.9 / 2.0 Q1 2014, вам не нужно будет отмечать источник вашей предыдущей ветви перед ее повторным размещением в перезаписанной восходящей ветви, как описано в Аристотель Пагальцис's ответ:
Видишь фиксация 07d406b и зафиксировать d96855f :

После работы над topic ветвь, созданная с помощью git checkout -b topic origin/master, история филиала удаленного отслеживания origin/master возможно, они были перемотаны назад и перестроены заново, что привело к появлению истории такой формы:

                   o---B1
                  /
  ---o---o---B2--o---o---o---B (origin/master)
          \
           B3
            \
             Derived (topic)

где origin/master используется для указания на коммиты B3, B2, B1 и теперь он указывает на B, и ваш topic ветка была начата поверх него еще тогда, когда origin/master был в B3.

В этом режиме используется повторный журнал origin/master чтобы найти B3 в качестве точки развилки, так что topic может быть переустановлен поверх обновленного origin/master Автор::

$ fork_point=$(git merge-base --fork-point origin/master topic)
$ git rebase --onto origin/master $fork_point topic

Вот почему git merge-base у команды появилась новая опция:

--fork-point::

Найдите точку, в которой ветвь (или любая история, ведущая к <commit>) разветвленный из другой ветви (или любой ссылки) <ref>.
Это не просто поиск общего предка двух коммитов, но также учитывается повторный журнал <ref> чтобы увидеть, ведет ли история к <commit> разветвленная от более раннего воплощения ветви <ref>.


Тот самый "git pull --rebase" команда вычисляет точку разветвления перебазируемой ветви, используя записи reflog из "base" ветвь (обычно ветвь с удаленным отслеживанием), на которой была основана работа ветви, чтобы справиться со случаем, в котором "базовая" ветвь была перемотана и перестроена заново.

Например, если история выглядела так, где:

  • текущий наконечник "base" филиал находится в B, но ранее fetch заметил , что его кончик раньше был B3 а потом B2 а потом B1 прежде чем перейти к текущему коммиту, и
  • ветвь, переназначаемая поверх последней "базы", основана на фиксации B3,

он пытается найти B3 пройдя через выходные данные "git rev-list --reflog base" (т.е. B, B1, B2, B3) до тех пор , пока он не найдет коммит, который является предком текущего tip " .Derived (topic)".

Внутренне мы имеем get_merge_bases_many() который может вычислить это за один раз.
Мы бы хотели, чтобы база слияния между Derived и фиктивная фиксация слияния, которая привела бы к объединению всех исторических подсказок "base (origin/master)".
Когда такая фиксация существует, мы должны получить единственный результат, который в точности соответствует одной из записей reflog "base".


Git 2.1 (3 квартал 2014) добавит, сделает эту функцию более надежной для этого:видишь зафиксировать 1e0dacd Автор: Джон Кипинг (johnkeeping)

правильно обработайте сценарий, в котором у нас есть следующая топология:

    C --- D --- E  <- dev
   /
  B  <- master@{1}
 /
o --- B' --- C* --- D*  <- master

где:

  • B' является исправленной версией B это не патч, идентичный B;
  • C* и D* идентичны ли патчи C и D соответственно и конфликтуют текстуально, если применяются в неправильном порядке;
  • E текстуально зависит от D.

Правильный результат git rebase master dev это что B идентифицируется как точка развилки dev и master, так что C, D, E есть ли коммиты, которые необходимо воспроизвести master;но C и D идентичны ли патчи с C* и D* и поэтому может быть отброшен, так что конечным результатом будет:

o --- B' --- C* --- D* --- E  <- dev

Если точка развилки не определена, то сбор B на ветку , содержащую B' приводит к конфликту, и если коммиты, идентичные патчу, неправильно идентифицированы, то выбор C на ветку , содержащую D (или эквивалентно D*) приводит к конфликту.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top