Я объединил ветку с устаревшей локальной главной веткой и нажал. Как я могу отменить?

#git

#git

Вопрос:

Я работал над веткой для проекта, который был более чем на 100 коммитов впереди master. За последние несколько дней коллега внес некоторые изменения в master, и я так и не перенес новые изменения в свою локальную среду.

В спешке, чтобы развернуть свою работу, я забыл сначала извлечь из источника / мастера, и я объединил свою большую ветку с моим локальным мастером и отправил в удаленный репозиторий.

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

Какие у меня есть варианты?

Комментарии:

1. Вам пришлось принудительно нажимать, чтобы ваш push удалил уже существующие ревизии, которых у вас не было, верно? Попросите любого из ваших коллег, у которого есть более поздние версии, принудительно нажать на эту ветку, чтобы ваши изменения вышли из окна на удаленном компьютере.

2. Я этого не сделал. Я только что сделал «git push» в своей главной ветке. Я надеялся, что смогу сам отменить изменения, потому что они относятся к более позднему часовому поясу, и скоро будут выходные. Но, надеюсь, они смогут сделать то, что вы сказали.

3. Нажатие без --force не должно было сработать. Ваш локальный мастер «разошелся» с удаленным мастером. Чего-то не хватает. Сделайте git fetch , а затем не могли бы вы показать нам соответствующие части git log --oneline --graph --decorate --all please?

Ответ №1:

НЕ ПАНИКУЙТЕ. Все это можно восстановить.

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


Вы никогда не должны были иметь возможность нажимать без --force . Произошло что-то еще. Давайте изобразим это на графике.

Я работал над веткой для проекта, который был более чем на 100 коммитов впереди master. За последние несколько дней коллега внес некоторые изменения в master, и я так и не перенес новые изменения в свою локальную среду.

Давайте назовем это на 3 коммита вперед. Ваш локальный репозиторий выглядит следующим образом.

           [origin/master]
A - B - C [master]
         
          D - E - F [feature]
  

И пульт выглядит так.

 A - B - C - G - H - I [master]
  

В спешке, чтобы развернуть свою работу, я забыл сначала извлечь из origin / master, и я объединил свою большую ветку с моим локальным мастером…

После этого слияния ваш репозиторий будет выглядеть следующим образом:

           [origin/master]
A - B - C --------- M [master]
                  /
          D - E - F [feature]
  

… и отправил в удаленный репозиторий.

Вы не могли бы обойтись без --force этого, потому что ваш локальный мастер и мастер источника разошлись. Это станет более понятным, если мы посмотрим на ваш репозиторий после git fetch .

           G - H - I [origin/master]
         /
A - B - C --------- M [master]
                  /
          D - E - F [feature]
  

Ваш мастер не может быть применен простым добавлением коммитов в origin / master . git push не будет работать.

Здесь чего-то не хватает. Это может быть так…

  • Вы использовали git push --force .
  • Ваш коллега никогда не нажимал на мастер.
  • ???

В любом случае, вот как это исправить.

  1. Отправьте своего коллегу в git push --force их главную ветку.

Это восстанавливает их версию master.

  1. Если вы удалили свою ветку, создайте ее заново непосредственно перед слиянием.

Вам это понадобится, чтобы повторить слияние. В приведенном выше примере это было бы git branch feature F .

  1. git fetch

Это обновит ваше представление о происхождении. теперь origin / master должен быть в работе вашего коллеги.

 $ git fetch

          G - H - I [origin/master]
         /
A - B - C --------- M [master]
                  /
          D - E - F [feature]
  
  1. Проверка мастера и git reset --hard origin/master .

Это уничтожит ваши локальные изменения в master и восстановит их в origin / master, фактически отменяя слияние. Он просто перемещает вашу master метку туда, где origin/master она есть.

 $ git checkout master
$ git reset --hard origin/master

                      [origin/master]
A - B - C - G - H - I [master]
         
          D - E - F [feature]
  
  1. Повторите слияние.
 $ git merge feature

                    [origin/master]
A - B - C - G - H - I - M [master]
                      /
          D - E ----- F [feature]
  
  1. git push .
 $ git push

                          [origin/master]
A - B - C - G - H - I - M [master]
                      /
          D - E ----- F [feature]
  

Как только все это будет решено, подумайте о том, чтобы сделать master защищенной веткой, к которой нельзя напрямую подключиться; все изменения в master должны проходить через этап интеграции, такой как запрос на извлечение или слияние. GitLab и Github предлагают защищенные ветки. Или это можно сделать с помощью перехватов.

Это позволяет избежать ошибок и гарантирует, что master является стабильной базой кода для работы.