Как отменить (откатить) действие git pull?
Подскажите, пожалуйста, решение проблемы: Есть две ветки: sphere и tags . Я находился в ветке sphere и случайно сделал git pull origin tags , потом, заметив, что написал неправильно, и не посмотрев, что мердж прошел с конфликтами, сделал git pull origin sphere , и у меня в ветку влились все новые изменения из sphere . Как мне вернуть код к состоянию до первого pull ?
Отслеживать
33.9k 25 25 золотых знаков 130 130 серебряных знаков 222 222 бронзовых знака
задан 16 сен 2014 в 13:24
7,941 2 2 золотых знака 22 22 серебряных знака 34 34 бронзовых знака
2 ответа 2
Сортировка: Сброс на вариант по умолчанию
git reset --hard git checkout sphere git reflog # Находите хэш коммита, в котором вы находились до первого pull-а. # Будет что-то вроде "8f05e00 HEAD@: checkout: moving from master to sphere" # или "4c31200 HEAD@: commit: Awesome feature implemented." git reset --hard [нужный хэш]
Ну и я бы не рекомендовал использовать «git pull» вообще, потому как эта команда берет на себя слишком много функций и ее поведение неочевидно. Рекомендую разобраться поподробнее, как работает git, и использовать fetch + merge или fetch + rebase. Я лично предпочитаю второе, но это дело вкуса.
2.4 Основы Git — Операции отмены
В любой момент вам может потребоваться что-либо отменить. Здесь мы рассмотрим несколько основных способов отмены сделанных изменений. Будьте осторожны, не все операции отмены в свою очередь можно отменить! Это одна из редких областей Git, где неверными действиями можно необратимо удалить результаты своей работы.
Отмена может потребоваться, если вы сделали коммит слишком рано, например, забыв добавить какие-то файлы или комментарий к коммиту. Если вы хотите переделать коммит — внесите необходимые изменения, добавьте их в индекс и сделайте коммит ещё раз, указав параметр —amend :
$ git commit --amend
Эта команда использует область подготовки (индекс) для внесения правок в коммит. Если вы ничего не меняли с момента последнего коммита (например, команда запущена сразу после предыдущего коммита), то снимок состояния останется в точности таким же, а всё что вы сможете изменить — это ваше сообщение к коммиту.
Запустится тот же редактор, только он уже будет содержать сообщение предыдущего коммита. Вы можете редактировать сообщение как обычно, однако, оно заменит сообщение предыдущего коммита.
Например, если вы сделали коммит и поняли, что забыли проиндексировать изменения в файле, который хотели добавить в коммит, то можно сделать следующее:
$ git commit -m 'Initial commit' $ git add forgotten_file $ git commit --amend
В итоге получится единый коммит — второй коммит заменит результаты первого.
Примечание
Очень важно понимать, что когда вы вносите правки в последний коммит, вы не столько исправляете его, сколько заменяете новым, который полностью его перезаписывает. В результате всё выглядит так, будто первоначальный коммит никогда не существовал, а так же он больше не появится в истории вашего репозитория.
Очевидно, смысл изменения коммитов в добавлении незначительных правок в последние коммиты и, при этом, в избежании засорения истории сообщениями вида «Ой, забыл добавить файл» или «Исправление грамматической ошибки».
Отмена индексации файла
Следующие два раздела демонстрируют как работать с индексом и изменениями в рабочем каталоге. Радует, что команда, которой вы определяете состояние этих областей, также подсказывает вам как отменять изменения в них. Например, вы изменили два файла и хотите добавить их в разные коммиты, но случайно выполнили команду git add * и добавили в индекс оба. Как исключить из индекса один из них? Команда git status напомнит вам:
$ git add * $ git status On branch master Changes to be committed: (use "git reset HEAD . " to unstage) renamed: README.md -> README modified: CONTRIBUTING.md
Прямо под текстом «Changes to be committed» говорится: используйте git reset HEAD … для исключения из индекса. Давайте последуем этому совету и отменим индексирование файла CONTRIBUTING.md :
$ git reset HEAD CONTRIBUTING.md Unstaged changes after reset: M CONTRIBUTING.md $ git status On branch master Changes to be committed: (use "git reset HEAD . " to unstage) renamed: README.md -> README Changes not staged for commit: (use "git add . " to update what will be committed) (use "git checkout -- . " to discard changes in working directory) modified: CONTRIBUTING.md
Команда выглядит несколько странно, но — работает! Файл CONTRIBUTING.md изменен, но больше не добавлен в индекс.
Примечание
Команда git reset может быть опасной если вызвать её с параметром —hard . В приведённом примере файл не был затронут, следовательно команда относительно безопасна.
На текущий момент этот магический вызов — всё, что вам нужно знать о команде git reset . Мы рассмотрим в деталях что именно делает reset и как с её помощью делать действительно интересные вещи в разделе Раскрытие тайн reset главы 7.
Отмена изменений в файле
Что делать, если вы поняли, что не хотите сохранять свои изменения файла CONTRIBUTING.md ? Как можно просто отменить изменения в нём — вернуть к тому состоянию, которое было в последнем коммите (или к начальному после клонирования, или ещё как-то полученному)? Нам повезло, что git status подсказывает и это тоже.
В выводе команды из последнего примера список изменений выглядит примерно так:
Changes not staged for commit: (use "git add . " to update what will be committed) (use "git checkout -- . " to discard changes in working directory) modified: CONTRIBUTING.md
Здесь явно сказано как отменить существующие изменения. Давайте так и сделаем:
$ git checkout -- CONTRIBUTING.md $ git status On branch master Changes to be committed: (use "git reset HEAD . " to unstage) renamed: README.md -> README
Как видите, откат изменений выполнен.
Важно понимать, что git checkout — — опасная команда. Все локальные изменения в файле пропадут — Git просто заменит его версией из последнего коммита. Ни в коем случае не используйте эту команду, если вы не уверены, что изменения в файле вам не нужны.
Если вы хотите сохранить изменения в файле, но прямо сейчас их нужно отменить, то есть способы получше, такие как ветвление и припрятывание — мы рассмотрим их в главе Ветвление в Git.
Помните, всё что попало в коммит почти всегда Git может восстановить. Можно восстановить даже коммиты из веток, которые были удалены, или коммиты, перезаписанные параметром —amend (см. Восстановление данных). Но всё, что не было включено в коммит и потеряно — скорее всего, потеряно навсегда.
Отмена действий с помощью git restore
Git версии 2.23.0 представил новую команду: git restore . По сути, это альтернатива git reset, которую мы только что рассмотрели. Начиная с версии 2.23.0, Git будет использовать git restore вместо git reset для многих операций отмены.
Давайте проследим наши шаги и отменим действия с помощью git restore вместо git reset .
Отмена индексации файла с помощью git restore
В следующих двух разделах показано, как работать с индексом и изменениями рабочей копии с помощью git restore . Приятно то, что команда, которую вы используете для определения состояния этих двух областей, также напоминает вам, как отменить изменения в них. Например, предположим, что вы изменили два файла и хотите зафиксировать их как два отдельных изменения, но случайно набираете git add * и индексируете их оба. Как вы можете убрать из индекса один из двух? Команда git status напоминает вам:
$ git add * $ git status On branch master Changes to be committed: (use "git restore --staged . " to unstage) modified: CONTRIBUTING.md renamed: README.md -> README
Прямо под текстом «Changes to be committed», написано использовать git restore —staged … для отмены индексации файла. Итак, давайте воспользуемся этим советом, чтобы убрать из индекса файл CONTRIBUTING.md :
$ git restore --staged CONTRIBUTING.md $ git status On branch master Changes to be committed: (use "git restore --staged . " to unstage) renamed: README.md -> README Changes not staged for commit: (use "git add . " to update what will be committed) (use "git restore . " to discard changes in working directory) modified: CONTRIBUTING.md
Файл CONTRIBUTING.md изменен, но снова не индексирован.
Откат изменённого файла с помощью git restore
Что, если вы поймете, что не хотите сохранять изменения в файле CONTRIBUTING.md ? Как легко его откатить — вернуть обратно к тому, как он выглядел при последнем коммите (или изначально клонирован, или каким-либо образом помещён в рабочий каталог)? К счастью, git status тоже говорит, как это сделать. В выводе последнего примера, неиндексированная область выглядит следующим образом:
Changes not staged for commit: (use "git add . " to update what will be committed) (use "git restore . " to discard changes in working directory) modified: CONTRIBUTING.md
Он довольно недвусмысленно говорит, как отменить сделанные вами изменения. Давайте сделаем то, что написано:
$ git restore CONTRIBUTING.md $ git status On branch master Changes to be committed: (use "git restore --staged . " to unstage) renamed: README.md -> README
Важно понимать, что git restore — опасная команда. Любые локальные изменения, внесённые в этот файл, исчезнут — Git просто заменит файл последней зафиксированной версией. Никогда не используйте эту команду, если точно не знаете, нужны ли вам эти несохранённые локальные изменения.
Отмена запроса на вытягивание
Вы можете отменить изменения запроса на вытягивание после слияния с вышестоящей ветвью.
Сведения об отмене запроса на вытягивание.
При отмене запроса на вытягивание в GitHub создается новый запрос на вытягивание, содержащий одну операцию отмены фиксации слияния из исходного объединенного запроса на вытягивание. Чтобы отменять запросы на вытягивание, необходимо иметь разрешения на запись в репозиторий.
Отмена запроса на вытягивание
Примечание. Отмена отдельных фиксаций в запросе на вытягивание может потребоваться в любом из следующих случаев.
- Отмена запроса на вытягивание приводит к конфликтам слияния.
- Исходный запрос на вытягивание изначально не был объединен с GitHub. Например, другой пользователь мог выполнить быстрое слияние запроса на вытягивание с помощью командной строки.
Дополнительные сведения об использовании Git для отмены отдельных фиксаций вручную см. в описании команды git revert в документации по Git.
- В поле имени репозитория щелкните

Запросы на вытягивание.

Как это отменить?! Git-команды для исправления своих ошибок
Если вы что-то сделали в Git’е, а потом очень сильно пожалели, не отчаивайтесь: возможно, всё можно исправить. Рассказываем, как это сделать.
Если вы ошиблись в Git’е, разобраться, что происходит и как это исправить, — непростая задача. Документация Git — это кроличья нора, из которой вы вылезете только зная конкретное название команды, которая решит вашу проблему.
Рассказываем о командах, которые помогут вам выбраться из проблемных ситуаций.
Вот блин, я сделал что-то не то… У Git ведь есть машина времени?!
git reflog # Тут вы увидите всё, что вы делали # в Git во всех ветках. # У каждого элемента есть индекс HEAD@. # Найдите тот, после которого всё сломалось. git reset HEAD@ # Машина времени к вашим услугам.
Так вы можете восстановить то, что случайно удалили, и откатить слияние, после которого всё сломалось. reflog используется очень часто — давайте поблагодарим того, кто предложил добавить его в Git.
Введение в Git: от установки до основных команд
Я только что сделал коммит и заметил, что нужно кое-что поправить!
# Внесите изменения git add . # или добавьте файлы по отдельности. git commit --amend --no-edit # Теперь последний коммит содержит ваши изменения. # ВНИМАНИЕ! Никогда не изменяйте опубликованные коммиты.
Обычно эта команда нужна если вы что-то закоммитили, а потом заметили какую-то мелочь, например отсутствующий пробел после знака = . Конечно вы можете внести изменения новым коммитом, а потом объединить коммиты с помощью rebase -i , но это гораздо дольше.
Внимание Никогда не изменяйте коммиты в публичной ветке. Используйте эту команду только для коммитов в локальной ветке, иначе вам конец.
Мне нужно изменить сообщение последнего коммита!
git commit --amend # Открывает редактор сообщений коммита.
Тупые требования к оформлению сообщений…
Я случайно закоммитил что-то в мастер, хотя должен был в новую ветку!
# Эта команда создаст новую ветку из текущего состояния мастера. git branch some-new-branch-name # А эта — удалит последний коммит из мастер-ветки. git reset HEAD~ --hard git checkout some-new-branch-name # Теперь ваш коммит полностью независим :)
Команды не сработают, если вы уже закоммитили в публичную ветку. В таком случае может помочь git reset HEAD@ вместо HEAD~ .
Ну отлично. Я закоммитил не в ту ветку!
# Отменяет последний коммит, но оставляет изменения доступными. git reset HEAD~ --soft git stash # Переключаемся на нужную ветку. git checkout name-of-the-correct-branch git stash pop # Добавьте конкретные файл или не парьтесь и закиньте все сразу. git add . git commit -m «Тут будет ваше сообщение» # Теперь ваши изменения в нужной ветке.
Многие в такой ситуации предлагают использовать cherry-pick , так что можете выбрать, что вам больше по душе.
git checkout name-of-the-correct-branch # Берём последний коммит из мастера. git cherry-pick master # Удаляем его из мастера. git checkout master git reset HEAD~ --hard
Самые типичные ошибки и вопросы, связанные с Git, и удобные способы их решения
Я пытаюсь запустить diff, но ничего не происходит
Если вы знаете, что изменения были внесены, но diff пуст, то возможно вы индексировали изменения (через add ). Поэтому вам нужно использовать специальный флаг.
git diff --staged
Конечно, «это не баг, а фича», но с первого взгляда это чертовски неоднозначно.
Мне нужно каким-то образом отменить коммит, который был сделан 5 коммитов назад
# Найдите коммит, который нужно отменить. git log # Можно использовать стрелочки, чтобы прокручивать список вверх и вниз. # Сохраните хэш нужного коммита. git revert [тот хэш] # Git создаст новый коммит, отменяющий выбранный. # Отредактируйте сообщение коммита или просто сохраните его.
Вам не обязательно откатываться назад и копипастить старые файлы, замещая ими новые. Если вы закоммитили баг, то коммит можно отменить с помощью revert .
Помимо этого, откатить можно не целый коммит, а отдельный файл. Но следуя канону Git’а, это будут уже совсем другие команды…
Мне нужно отменить изменения в файле
# Найдите хэш коммита, до которого нужно откатиться. git log # Сохраните хэш нужного коммита. git checkout [тот хэш] --path/to/file # Теперь в индексе окажется старая версия файла. git commit -m «О май гадбл, вы даже не использовали копипаст»
Именно поэтому checkout — лучший инструмент для отката изменений в файлах.
Давай по новой, Миша, всё х**ня
cd .. sudo rm -r fucking-git-repo-dir git clone https://some.github.url/fucking-git-repo-dir.git cd fucking-git-repo-dir
Если вам нужно полностью откатиться до исходной версии (т. е. отменить все изменения), то можете попробовать сделать так.
Будьте осторожны, эти команды разрушительны и необратимы.
# Получить последнее состояние origin. git fetch origin git checkout master git reset --hard origin/master # Удалить неиндексированные файлы и папки. git clean -d --force # Повторить checkout/reset/clean для каждой испорченной ветки.
Эти команды Git нужны для экстренных ситуаций, но пригодиться могут не только они. Про другие команды с пояснениями писали тут: