В справочной странице git-rebase
есть раздел под названием «ВОССТАНОВЛЕНИЕ ОТ РЕБАЗЫ UPSTREAM», который достаточно хорошо описывает это.
Получение
Для вашего конкретного случая давайте разберемся, что происходит.Если вы просто выбираете, все, что вам нужно, это обновлять ветку удаленного отслеживания.Это по-прежнему работает нормально - оно выдаст вам предупреждение , хотя:
From <url>:
+ abc123...def456 master -> origin/master (forced update)
Потянув
Поток, будь то обычный (слияние) или перебазирование, вызывает выборку изнутри,Так что , если вы еще не получили, вы увидите предупреждение «принудительное обновление» .Если вы уже загрузили, предупреждение о принудительном обновлении было дано раньше, и сейчас нет принудительного обновления, чтобы предупредить.Вы также можете пропустить предупреждение о принудительном обновлении, если после него будет большой отчет о разнице.После выборки git-pull затем вызывает merge или rebase в соответствии с запросом.Вот где это становится действительно страшно.Что касается Git сейчас, коммиты C
и D
теперь просто локальные коммиты.Неважно, что в один прекрасный момент они были опубликованы.Таким образом, Git будет сливаться / перебазироваться, как обычно.
Слияние:
- A - B - L - M - N - O (origin/master)
\ \
C - D - X - Y - Z - Q (master)
Ребаз:
- A - B - L - M - N - O (origin/master) - C' - D' - X' - Y' - Z' (master)
Теперь любой из них может очень хорошо работатьв конфликты, если удаление коммитов C и D делает последующие коммиты другими. Конфликты слияния - это единственные другие ошибки, которые вы заметите. Но если они были изолированными изменениями, то все идет "хорошо".Если пользователь не замечает этого, он может затем протолкнуть эту историю, и, таким образом, вновь ввести удаленные коммиты!Иногда это может быть относительно мягким.Может быть, L на самом деле C с опечаткой, зафиксированной в сообщении фиксации, и MNO идентичны DEF, только с разными родителями.Так что повторное введение C и D не сделало бы ничего, кроме беспорядка в истории.Но, может быть, это ужасно опасно: возможно, удаление C исправило какую-то ужасную ошибку, и она только что была повторно введена.
Как избежать проблемы
И именно поэтому это действительно плохая идеяпереписать опубликованную историю.В лучшем случае заканчиваются дублирующиеся коммиты, а в худшем - пользователь неосознанно нарушает все.Поэтому, если это произойдет, самое первое, что вам нужно сделать, это сказать всем и указать им, как восстановиться.Следующее - внимательно следить за всем, что впоследствии публикуется, чтобы убедиться, что оно не вводит старые коммиты.Если вы находитесь на другой стороне этого, извлекая из публичного репо, надеюсь, вы достаточно доверяете сопровождающим, чтобы никогда не перебазировать стабильную ветку или сообщить вам, если они это сделают.Если вы им не доверяете, то рекомендуется извлекать, а затем объединять / перебазировать, а не извлекать данные, чтобы вы могли заметить сообщение «принудительное обновление» и действовать очень осторожно.
Локальное восстановление
Детали того, как восстановить, различаются;Я рекомендую вышеупомянутую справочную страницу.Трудно точно сказать, что вам нужно делать - это зависит от того, был ли C переписан в L (и, возможно, D в M) или это совершенно новые коммиты, и от того, хотите ли вы перебазировать или объединить.Если вы просто хотите перебазировать, достаточно перебазировать XYZ на O.Если вы хотите объединить, вы должны изменить XYZ на B или M, а затем объединить O.