Как я могу откатить репозиторий GitHub для конкретного коммита?


431

В моем github сейчас 100 коммитов. Мне нужно откатить репозиторий, чтобы зафиксировать 80, и удалить все последующие.

Почему? Предполагается, что это репо для слияния от разных пользователей. Куча слияний произошла как коммиты из-за чрезмерного редактирования. Это было связано с неправильной маркировкой моих удаленных веток, где 3 разработчика были помечены как друг друга. Мне нужно вернуться к этой точке, а затем потянуть вперед.

Я хотел сделать ребаз, как в этом примере: Как я могу удалить коммит на GitHub?

Тем не менее, git хочет, чтобы я занимался управлением конфликтами. Есть ли более простой способ?

Ответы:


883
git reset --hard <old-commit-id>
git push -f <remote-name> <branch-name>

Примечание. Как написано в комментариях ниже, использование этого опасно в среде совместной работы: вы переписываете историю


43
люди, делайте git push -f origin branch. У меня просто было плохое время, потому что я это пропустил.
Сумит М Асок

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

8
Это неправда, вы можете получить старые коммиты, используя git reflog
Jan Schaefer

27
Вы, возможно, должны сделать git push origin HEAD --forceвместо того, чтобы, git push -f origin branchпоскольку это выдавало мне error: src refspec branch does not match any.ошибку
sprocket12

1
Да, спасибо, ребята. Мне удалось сделать то, что я хотел. Сначала я создал отдельную ветку от той, которая была перед коммитом, который я хотел откатить. Клонировали его локально. Затем применил ваши рекомендации к этой копии, таким образом, я не скомпрометировал свою основную ветку ...
Готье Боальо

21

Чтобы отменить самый последний коммит, я делаю это:

Первый:

git log

получить самый последний идентификатор SHA, чтобы отменить.

git revert SHA

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

Это хорошо для немедленного повторения чего-то, что вы только что совершили, что, как мне кажется, чаще всего происходит со мной.

Как заметил Майк, вы также можете сделать это:

git revert HEAD

8
git revert HEADвернет последний коммит без необходимости искать хеш.
Майк Баранчак

Это решение, если вы вообще не хотите удалять коммиты. Тем не менее, в этом случае все коммиты мусора все еще будут там, и клонер сможет сбросить их или извлечь их. Если вы хотите предотвратить это, вам придется принудительно толкать.
cst1992

19

Другой путь:

Извлеките ветку, которую вы хотите вернуть, а затем сбросьте свою локальную рабочую копию обратно на коммит, который вы хотите, чтобы он был последним на удаленном сервере (все после того, как оно пройдет до свидания). Для этого в SourceTree я щелкнул правой кнопкой мыши и выбрал «Сбросить BRANCHNAME для этого коммита».

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

git -c diff.mnemonicprefix=false -c core.quotepath=false push -v -f -- tags REPOSITORY_NAME BRANCHNAME:BRANCHNAME 

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


1
FYI "REPOSITORY_NAME" будет выглядеть примерно так: https: /me@github.com/me/repo_name.git
Тим

3
Было бы более полезно, если бы вы нарушили эту команду и объяснили ее.
cst1992

3

Большинство предложений предполагают, что вам нужно каким-то образом уничтожить последние 20 коммитов, поэтому это означает «переписывание истории», но это не обязательно.

Просто создайте новую ветку из коммита # 80 и продолжайте работу над этой веткой. Остальные 20 коммитов останутся на старой сиротской ветке.

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


Я предполагаю, что это также проблематично портит все локальные версии истории интересующей отрасли.
Рагердл

2

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

Если ваш последний коммит был слиянием, нужна еще немного любви:

git revert -m 1 HEAD


1

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

  1. Не ветка по умолчанию
  2. Нет запросов на открытие опроса.
  3. Ветка не защищена.

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

git checkout -b master 734c2b9b   # replace with your commit point

Затем нажмите местную ветку на удаленный

git push -u origin master

Добавьте обратно ветку по умолчанию и защиту ветки и т. Д.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.