Как мне вернуть Git-репозиторий к предыдущему коммиту? - PullRequest
6929 голосов
/ 06 ноября 2010

Как мне вернуться из моего текущего состояния к снимку, сделанному на определенном коммите?

Если я сделаю git log, то получу следующий вывод:

$ git log
commit a867b4af366350be2e7c21b8de9cc6504678a61b`
Author: Me <me@me.com>
Date:   Thu Nov 4 18:59:41 2010 -0400

blah blah blah...

commit 25eee4caef46ae64aa08e8ab3f988bc917ee1ce4
Author: Me <me@me.com>
Date:   Thu Nov 4 05:13:39 2010 -0400

more blah blah blah...

commit 0766c053c0ea2035e90f504928f8df3c9363b8bd
Author: Me <me@me.com>
Date:   Thu Nov 4 00:55:06 2010 -0400

And yet more blah blah...

commit 0d1d7fc32e5a947fbd92ee598033d85bfc445a50
Author: Me <me@me.com>
Date:   Wed Nov 3 23:56:08 2010 -0400

Yep, more blah blah.

Каквернуться к фиксации с 3 ноября, т.е. совершить 0d1d7fc?

Ответы [ 41 ]

58 голосов
/ 10 мая 2016

Предполагая, что вы говорите о мастере и о соответствующей ветке (при этом речь может идти о любой рабочей ветке, которая вас интересует):

# Reset local master branch to November 3rd commit ID
git reset --hard 0d1d7fc32e5a947fbd92ee598033d85bfc445a50

# Reset remote master branch to November 3rd commit ID
git push -f origin 0d1d7fc32e5a947fbd92ee598033d85bfc445a50:master

Я нашел ответ в сообщении в блоге (теперь больше не существует)

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

Лучше использовать возврат (см. Другие ответы), чем сбросить. Если вы команда из одного человека, то это, вероятно, не имеет значения.

57 голосов
/ 14 октября 2011

Скажем, у вас есть следующие коммиты в текстовом файле с именем ~/commits-to-revert.txt (я использовал git log --pretty=oneline для их получения)

fe60adeba6436ed8f4cc5f5c0b20df7ac9d93219
0c27ecfdab3cbb08a448659aa61764ad80533a1b
f85007f35a23a7f29fa14b3b47c8b2ef3803d542
e9ec660ba9c06317888f901e3a5ad833d4963283
6a80768d44ccc2107ce410c4e28c7147b382cd8f
9cf6c21f5adfac3732c76c1194bbe6a330fb83e3
fff2336bf8690fbfb2b4890a96549dc58bf548a5
1f7082f3f52880cb49bc37c40531fc478823b4f5
e9b317d36a9d1db88bd34831a32de327244df36a
f6ea0e7208cf22fba17952fb162a01afb26de806
137a681351037a2204f088a8d8f0db6e1f9179ca

Создайте сценарий оболочки Bash для возврата каждогоиз них:

#!/bin/bash
cd /path/to/working/copy
for i in `cat ~/commits-to-revert.txt`
do
    git revert $i --no-commit
done

Это возвращает все обратно к предыдущему состоянию, включая создание файлов и каталогов, а также удаление, фиксирует его в вашей ветви и сохраняет историю, но у вас она возвращается к той же самойФайловая структура.Почему у Git нет git revert --to <hash> вне меня.

56 голосов
/ 29 июня 2014

Дополнительные альтернативы решениям Jefromi

Решения Jefromi определенно являются лучшими, и вы обязательно должны их использовать.Однако для полноты картины я также хотел показать эти другие альтернативные решения, которые также можно использовать для отмены фиксации (в том смысле, что вы создаете новую фиксацию, которая отменяет изменения в предыдущей фиксации , простокак то, что делает git revert).

Для ясности, эти альтернативы не лучший способ отменить коммиты , Решения Джефроми , но я просто хочу отметить, что вы можете также использовать эти другие методы для достижения того же, что и git revert.

Альтернатива 1: аппаратные и программные сбросы

Это очень немногомодифицированная версия решения Чарльза Бейли для Вернуть к фиксации с помощью хэша SHA в Git? :

# Reset the index to the desired commit
git reset --hard <commit>

# Move the branch pointer back to the previous HEAD
git reset --soft HEAD@{1}

# Commit the changes
git commit -m "Revert to <commit>"

Это в основном работает благодаря использованию факта, что программные сбросы оставят состояниепредыдущий коммит, поставленный в области index / staging, который вы можете затем зафиксировать.

Альтернатива 2: удалить текущее дерево и заменить его новым

Это решение разработано в sviРешение ck для Извлечь старый коммит и сделать его новым коммитом :

git rm -r .
git checkout <commit> .
git commit

Подобно альтернативе # 1, это воспроизводит состояние <commit> в текущей рабочей копии.Сначала нужно сделать git rm, потому что git checkout не удалит файлы, которые были добавлены с <commit>.

51 голосов
/ 29 февраля 2016

Вот гораздо более простой способ вернуться к предыдущему коммиту (и иметь его в незафиксированном состоянии, чтобы делать с ним что угодно):

git reset HEAD~1

Итак, идентификаторы коммитов не нужны:)

34 голосов
/ 05 сентября 2013

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

git push -f ...

И не только git push.

34 голосов
/ 08 августа 2013

Существует команда (не входит в состав ядра Git, но она входит в пакет git-extras ) специально для возврата и постановки старых коммитов:

git back

В соответствии с Справочная страница , также может использоваться как:

# Remove the latest three commits
git back 3
29 голосов
/ 06 апреля 2017

Вы можете выполнить все эти начальные шаги самостоятельно и вернуться к git repo.

  1. Извлечь последнюю версию вашего репозитория из Bitbucket с помощью команды git pull --all.

  2. Запустите команду git log с -n 4 на вашем терминале.Число после -n определяет количество коммитов в журнале, начиная с самого последнего коммита в вашей локальной истории.

    $ git log -n 4

  3. Сбросить заголовокистория вашего репозитория, используя git reset --hard HEAD~N, где N - количество коммитов, которые вы хотите вернуть себе.В следующем примере голова будет возвращена на один коммит к последнему коммиту в истории репозитория:

  4. Нажмите на изменение в git repo, используя git push --force, чтобы принудительно протолкнуть изменение.

Если вы хотите использовать git-репозиторий для предыдущего коммита

git pull --all
git reset --hard HEAD~1
git push --force
27 голосов
/ 26 июля 2016

Возврат к самой последней фиксации и игнорированию всех локальных изменений:

git reset --hard HEAD
26 голосов
/ 26 февраля 2014

Выберите необходимый коммит и проверьте его по

git show HEAD
git show HEAD~1
git show HEAD~2 

, пока не получите нужный коммит.Чтобы ГОЛОВА указала на это, сделайте

git reset --hard HEAD~1

или git reset --hard HEAD~2 или что-то еще.

20 голосов
/ 11 октября 2015

Чтобы полностью очистить каталог кодера от случайных изменений, мы использовали:

git add -A .
git reset --hard HEAD

Просто git reset --hard HEAD избавится от модификаций, но не избавится от «новых» файлов. В их случае они случайно перетащили важную папку куда-то случайно, и все эти файлы были обработаны Git как новые, поэтому reset --hard не исправил это. Запустив git add -A . заранее, он явно отследил их всех с помощью git, чтобы сбросить их при перезагрузке.

...