Отменить мерзавец, как привести репо в старое состояние

1006

Есть ли способ отменить или отменить git pull, чтобы мои исходные / репозитории пришли в старое состояние, которое было до выполнения git pull? Я хочу сделать это, потому что он объединяет некоторые файлы, которые я не хотел делать, а объединяет только остальные файлы. Итак, я хочу вернуть эти файлы, это возможно?

РЕДАКТИРОВАТЬ: Я хочу отменить мерзавец слияния для уточнения. Увидев некоторые ответы, я сделал это

git reflog
bb3139b... HEAD@{0}: pull : Fast forward
01b34fa... HEAD@{1}: clone: from ...name...

Что мне теперь делать? Делать git reset --hard нормально? Я не хочу ввернуть это снова, поэтому просите подробные шаги?

seg.server.fault
источник
23
Похоже, в вашей истории есть только две вещи: клон и выборка. Просто выполните сброс клону: git reset --hard 01b34faв этом случае вы могли бы выполнить git reset --hard HEAD^сброс до одного коммита до HEAD.
JKP
2
--hard необходимо, если вы хотите изменить файлы в вашей рабочей
директории
3
@ seg.server.fault: если это сработало, вы всегда можете принять ответ;)
jkp
7
git reset --hard HEAD ^
funroll
7
git reflogпокажет все, что было сделано с git. Существует проблема, git reset --hard [sha1 of something from reflog]которая вернет все, что показано reflog, что иногда не является целью, например. Вы хотите отменить слияние в основной ветке, извлеченной из источника с неверными данными (происходит), и после этого слияния вы работали с другими ветвями. reflogпокажет каждую шейгу на других ветках. Но git checkout masterи git reset --hard [SH1 of commit on master branch just before merge]сбросит только текущую главную ветку, удалив вытащенное слияние из источника.
Владимир Вуканац

Ответы:

1428

Бег git pullвыполняет следующие задачи по порядку:

  1. git fetch
  2. git merge

Шаг слияния объединяет ветви, которые были настроены для слияния в вашей конфигурации. Вы хотите отменить шаг слияния , но, вероятно, не извлечение (не имеет большого смысла и не должно быть необходимым).

Чтобы отменить слияние , используйте git reset --hardдля сброса локального хранилища в предыдущее состояние; используйте git-reflog, чтобы найти SHA-1 предыдущего состояния и затем сбросить его.

Предупреждение

Команды, перечисленные в этом разделе, удаляют все незафиксированные изменения, что может привести к потере работы:

git reset --hard

В качестве альтернативы, сброс на определенный момент времени, например:

git reset --hard master@{"10 minutes ago"}
JKP
источник
325
Отличный способ , чтобы выбрать предыдущее состояние, вместо того чтобы использовать ГИТ-reflog и копирования хешей, является использование ярлыка , как master@{1}, что предыдущее положение master, master@{"5 minutes ago"}или master@{14:30}. Полную информацию об указании ревизий таким способом можно найти man git-rev-parseв разделе «Задание ревизий».
Каскабель
38
В этом случае ORIG_HEAD также должен работать («git reset --hard ORIG_HEAD»)
Якуб Наребски
@Jelfromi: спасибо за этот совет, я не знал, что вы можете быть настолько многословны в отношении изменений. Я знал о выборе ревизий относительно HEAD, но когда был задан вопрос, я не знал, как далеко назад он хотел пойти.
JKP
Когда я вытащил, это говорит Updating d2c90a3..035ac4d. Здесь вы также можете использовать d2c90a3в качестве параметра для сброса.
Тайский
Вам не нужно вводить хэши, когда вы используете reflog. Вы также можете использовать HEAD @ {1} или любой предыдущий номер, как определено в reflog.
Simon The Cat
338

То же, что и ответ jkp, но вот полная команда:

git reset --hard a0d3fe6

где a0d3fe6 находится путем

git reflog

и глядя на точку, в которой вы хотите отменить.

Джеффри Сан
источник
Почему я не могу просто сделать git reset HEAD --hard, например?
Сон Чо
9
@MikeC Этот подход позволяет вам вернуться, например, на несколько
попыток
2
Я не мог использовать идентификаторы левой стороны, но git reset --hard HEAD@{n}работал
Е. Сундин
1
Вы должны были предложить изменить ответ jkp вместо того, чтобы почти повторить его здесь после стольких лет.
Абхишек Ананд
Если у меня есть это на git reflog: dab04ec HEAD @ {0}, aaaaaaa HEAD @ {1} и bbbbbbb HEAD @ {2}. Если я сделаю, git reset --hard bbbbbbbя потеряю ГОЛОВУ 0 и 1?
pmiranda
115

Более современный способ отменить слияние:

git merge --abort

И немного более старый способ:

git reset --merge

Старый способ, описанный в предыдущих ответах (предупреждение: отменит все ваши локальные изменения):

git reset --hard

Но на самом деле, стоит заметить, что git merge --abortэто эквивалентно только тому, git reset --mergeчто MERGE_HEADприсутствует. Это можно прочитать в справке git для команды слияния.

git merge --abort is equivalent to git reset --merge when MERGE_HEAD is present.

После неудачного слияния, когда его нет MERGE_HEAD, неудачное слияние можно отменить, git reset --mergeно не обязательно с помощью git merge --abort, поэтому они не только имеют старый и новый синтаксис для одной и той же вещи . Вот почему я нахожу git reset --mergeгораздо более полезным в повседневной работе.

Мартин Г
источник
20
git merge --abortработает во время слияния, а не после того, git pullкак закончено. Так что этот ответ кажется несоответствующим вопросу.
Абхишек Ананд
1
git reset --mergeудаляет все изменения, не подготовленные для фиксации. Выяснил это трудным путем.
Theadriangreen
62

это работает первое использование: git reflog

найдите свой SHA своего прежнего состояния и сделайте (например, HEAD @ {1})

git reset --hard HEAD@{1}
Иезекииль Гарсия
источник
40

Если у вас есть gitk (попробуйте запустить «gitk --all из командной строки git»), это просто. Просто запустите его, выберите коммит, на который вы хотите откатиться (щелкните правой кнопкой мыши), и выберите «Сбросить основную ветвь сюда». Если у вас нет незафиксированных изменений, выберите «жесткий» вариант.

Самуэль Каррихо
источник
8
Это стоит бежать, если вы еще не видели. Появляется сумасшедший графический интерфейс.
Эван Моран
35

Предположим, это $COMMITбыл последний идентификатор коммита до того, как вы его выполнили git pull. Что вам нужно, чтобы отменить последнее нажатие

git reset --hard $COMMIT

,

Бонус:

Говоря о тяге, я хотел бы поделиться интересным трюком,

git pull --rebase

Эта команда является самой полезной в моей жизни Git, которая сэкономила много времени.

Перед отправкой вашего нового коммита на сервер, попробуйте эту команду, и она автоматически синхронизирует последние изменения сервера (с помощью fetch + merge) и поместит ваш коммит наверху в git log. Не нужно беспокоиться о ручном вытягивании / слиянии.

Найти подробности на: http://gitolite.com/git-pull--rebase

Саззад Хисейн Хан
источник
17

Это самый простой способ отменить изменения.

** Warning **

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

git reset --hard 9573e3e0

Где 9573e3e0ваш {Commit id}

Маниш Госвами
источник
этот ответ очень полезен, потому что если мы сделаем ветку git pull origin, мы получим что-то вроде этого Updating ffce65bd..e929e884, то сделайтеgit reset --hard ffce65bd
Ernesto Alfonso
15

ты можешь сделать git reset --hard ORIG_HEAD

поскольку "pull" или "merge" устанавливают ORIG_HEAD в текущее состояние перед выполнением этих действий.

Орландо
источник
5

Git Pull сделать ниже операции.

я. git fetch

II. git merge

Чтобы отменить тянуть, выполните любую операцию:

я. git reset --hard --- все свои локальные изменения отменить

или

II. git reset --hard master@{5.days.ago} (как 10.minutes.ago, 1.hours.ago, 1.days.ago..) , чтобы получить локальные изменения.

или

III. git reset --hard commitid

Улучшение:

В следующий раз используйте git pull --rebaseвместо git pull... его сервер синхронизации, изменив (fetch & merge).

ГоламМазид Саджиб
источник
4

В случае неудачного слияния, которое является наиболее распространенной причиной желания отменить a git pull, выполнение git reset --mergeделает именно то, что и следовало ожидать: сохранить извлеченные файлы, но отменить слияние, которое git pullпопыталось слить. Тогда можно решить, что делать без беспорядка, который git mergeиногда порождает. И для этого не нужен точный идентификатор фиксации, который --hardуказан в каждом другом ответе.

Davide
источник