41 Вопрос: Как мне вернуть Git-репозиторий к предыдущему коммиту?

вопрос создан в Mon, Jun 10, 2019 12:00 AM

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

Если я сделаю 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?

    
6891
  1. Связанные Как отменить последний коммит Git? .
    2014-05-23 17: 57: 12Z
  2. Вот очень четкое и подробное сообщение об удалении вещей в git, прямо из Github.
    2015-06-08 19: 41: 52Z
  3. Связанный: Откат к старой фиксации Git в публичном репо . Обратите внимание, что этот вопрос добавляет ограничение на публичность репо.
    2015-10-19 09: 51: 42Z
  4. Я люблю git, но тот факт, что есть 35 ответов на что-то, что должно быть невероятно простым, обнажает огромную проблему с git. Или это документы?
    2018-01-03 22: 26: 59Z
  5. Они могут добавить функциональность кнопки для этого, как SVN в истории
    2018-12-13 18: 29: 31Z
  6. 30 ответов                              30                         

    Это во многом зависит от того, что вы подразумеваете под "возвратом".

    Временно переключитесь на другой коммит

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

    # This will detach your HEAD, that is, leave you with no branch checked out:
    git checkout 0d1d7fc32
    

    Или, если вы хотите делать коммиты, пока вы там, продолжайте и создайте новую ветку, пока вы там:

    git checkout -b old-state 0d1d7fc32
    

    Чтобы вернуться туда, где вы были, просто проверьте ветку, в которой вы были снова. (Если вы внесли изменения, как всегда при переключении веток, вам придется обращаться с ними соответствующим образом. Вы можете сбросить их, чтобы выбросить; вы можете спрятать, оформить заказ, спрятать всплывающее окно, чтобы взять их с собой; вы можете зафиксировать их там ветка, если вы хотите там ветку.)

    Жесткое удаление неопубликованных коммитов

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

    # This will destroy any local modifications.
    # Don't do it if you have uncommitted work you want to keep.
    git reset --hard 0d1d7fc32
    
    # Alternatively, if there's work to keep:
    git stash
    git reset --hard 0d1d7fc32
    git stash pop
    # This saves the modifications, then reapplies that patch after resetting.
    # You could get merge conflicts, if you've modified things which were
    # changed since the commit you reset to.
    

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

    Отменить опубликованные коммиты с новыми коммитами

    С другой стороны, если вы опубликовали работу, вы, вероятно, не хотите сбрасывать ветку, поскольку это фактически переписывает историю. В этом случае вы действительно можете отменить коммиты. В Git возврат имеет очень специфическое значение: создайте коммит с обратным патчем, чтобы отменить его. Таким образом, вы не переписываете историю.

    # This will create three separate revert commits:
    git revert a867b4af 25eee4ca 0766c053
    
    # It also takes ranges. This will revert the last two commits:
    git revert HEAD~2..HEAD
    
    #Similarly, you can revert a range of commits using commit hashes:
    git revert a867b4af..0766c053 
    
    # Reverting a merge commit
    git revert -m 1 <merge_commit_sha>
    
    # To get just one, you could use `rebase -i` to squash them afterwards
    # Or, you could do it manually (be sure to do this at top level of the repo)
    # get your index and work tree into the desired state, without changing HEAD:
    git checkout 0d1d7fc32 .
    
    # Then commit. Be sure and write a good message describing what you just did
    git commit
    

    git-revert manpage фактически охватывает многое из этого в своем описании. Еще одна полезная ссылка - этот раздел git-scm.com, посвященный обсуждению git -revert . р>

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

    Вы также можете найти этот ответ полезным в этом случае:
    Как переместить HEAD обратно в предыдущее место? (Отстраненная голова)

        
    8799
    2018-04-04 17: 54: 07Z
    1. @ Комментарий Рода о git revert HEAD~3 как о лучшем вате для возврата назад коммитов 3 является важным соглашением.
      2012-08-22 15: 16: 45Z
    2. Не могли бы вы написать целое число? как: git reset --hard 0d1d7fc32e5a947fbd92ee598033d85bfc445a50
      2012-12-04 13: 58: 13Z
    3. @ MathiasMadsenStav Да, вы, конечно, можете указать коммиты по полному SHA1. Я использовал сокращенные хэши, чтобы сделать ответ более читабельным, и вы также склонны использовать их, если вы печатаете. Если вы копируете и вставляете, обязательно используйте полный хеш. См. Указание версий в man git rev- Разбор для полного описания того, как вы можете назвать коммиты.
      2012-12-04 16: 55: 52Z
    4. Чтобы вернуться к текущему состоянию, команда 'git checkout master'
      2013-01-18 00: 33: 26Z
    5. Вы можете использовать git revert --no-commit hash1 hash2 ... и после этого просто фиксировать каждый отдельный возврат за один коммит git commit -m "Message"
      2013-09-24 12: 12: 16Z

    Разбойник?

    Работаете самостоятельно и просто хотите, чтобы это работало? Следуйте приведенным ниже инструкциям, они надежно работали для меня и многих других в течение многих лет.

    Работаете с другими? Git это сложно. Прочитайте комментарии ниже этого ответа, прежде чем делать что-то опрометчивое.

    Возврат рабочей копии к самой последней фиксации

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

    git reset --hard HEAD
    

    где HEAD - последний коммит в вашей текущей ветке

    Возврат рабочей копии в более старый коммит

    Чтобы вернуться к коммиту, который старше самого последнего коммита:

    # Resets index to former commit; replace '56e05fced' with your commit code
    git reset 56e05fced 
    
    # Moves pointer back to previous HEAD
    git reset --soft HEAD@{1}
    
    git commit -m "Revert to 56e05fced"
    
    # Updates working copy to reflect the new commit
    git reset --hard
    

    Кредиты переходят на аналогичный вопрос переполнения стека, Восстановить сделать коммит SHA в Git? .

        
    1465
    2019-06-13 02: 36: 39Z
    1. Я сделал это, но потом я не смог зафиксировать и отправить в удаленный репозиторий. Я хочу, чтобы конкретный коммит стал HEAD ...
      2012-09-24 18: 17: 28Z
    2. Это означает, что вы уже выдвинули коммиты, которые хотите вернуть. Это может создать много проблем людям, которые проверили ваш код и работают над ним. Так как они не могут применить ваш коммит плавно к своим. В таком случае лучше сделать git revert. Если вы единственный, кто использует репо. Сделайте git push -f (но подумайте дважды, прежде чем делать это)
      2012-12-05 04: 51: 51Z
    3. Обязательное предупреждение: не выполняйте полный сброс , если вы делитесь своей веткой с другими людьми, у которых есть копии старых коммитов, потому что вы используете такой жесткий сброс заставит их заново синхронизировать свою работу с новой веткой сброса. Программный сброс безопасен, как и последние решения в этом ответе .
      2014-06-28 20: 06: 00Z
    4. Я просто хочу отметить, что в качестве альтернативы для решения с мягким сбросом вместо смешанного сброса вначале и полного сброса в последнюю очередь, вы можете сделать сложный сначала выполните сброс, как показано ниже: git reset --hard 56e05fc; git reset --soft HEAD@{1}; git commit.
      2014-06-29 00: 20: 29Z
    5. @ nuton linus, управляющий собой,создатель git, раскритиковал его за то, что он слишком сложен. Он официально заявил, что он был "в шоке", мерзавец стал настолько популярным, учитывая его сложность
      2015-05-18 23: 56: 00Z

      Здесь много сложных и опасных ответов, но на самом деле это просто:

      git revert --no-commit 0766c053..HEAD
      git commit
      

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

      (Флаг --no-commit позволяет git отменить все коммиты одновременно, в противном случае вам будет предложено ввести сообщение для каждого коммита в диапазоне, засоряя вашу историю ненужными новыми коммитами.)

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

          
      1458
      2014-06-28 20: 12: 34Z
      1. Если вы действительно хотите иметь отдельные коммиты (вместо того, чтобы возвращать все с помощью одного большого коммита), то вы можете передать --no-edit вместо --no-commit, чтобы вы этого не делали необходимо редактировать сообщение коммита для каждой реверсии.
        2014-06-28 20: 11: 40Z
      2. Если один из коммитов между 0766c053..HEAD является слиянием, то возникнет ошибка (не указывать -m). Это может помочь тем, кто сталкивается с этим: stackoverflow.com/questions/5970889/…
        2014-11-21 11: 55: 43Z
      3. Чтобы просмотреть различия перед фиксацией, используйте git diff --cached.
        2015-11-06 18: 35: 20Z
      4. $ git revert --no-commit 53742ae..HEAD возвращает fatal: empty commit set passed
        2016-08-01 20: 30: 18Z
      5. @ AlexG, потому что вам нужно ввести хеш перед тем, к которому вы хотите вернуться. В моем случае хэши были такими: 81bcc9e HEAD{0}; e475924 HEAD{1}, ... (от git reflog), и я хотел отменить то, что сделал в 81bcc9e, тогда мне пришлось сделать git revert e475924..HEAD
        2017-04-16 14: 22: 51Z

      Лучший вариант для меня и, вероятно, для других - это опция сброса Git:

      git reset --hard <commidId> && git clean -f
      

      Это был лучший вариант для меня! Это просто, быстро и эффективно!

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

      Также из комментариев, если вы хотите использовать менее «баллистический» метод, вы можете использовать

      git clean -i

          
      184
      2015-07-16 15: 31: 10Z
      1. Обязательное предупреждение: не делайте этого , если вы делитесь своей веткой с другими людьми, у которых есть копии старых коммитов, потому что вы используете такой жесткий сброс заставит их заново синхронизировать свою работу с новой веткой сброса. Для решения, которое подробно объясняет, как безопасно вернуть коммиты без потери работы с аппаратным сбросом, см. этот ответ .
        2014-06-28 20: 03: 54Z
      2. Я второе предупреждение @ Cupcake ... быть очень осведомленным о последствияхNCES. Тем не менее, обратите внимание, что если вам действительно нужно, чтобы эти коммиты исчезли из истории навсегда, этот метод reset + clean сделает это, и вам потребуется force отодвинуть ваши измененные ветки обратно к любому и все пульты.
        2014-10-29 14: 46: 25Z
      3. git clean -f ОПАСНОСТЬ ОПАСНОСТЬ
        2015-07-16 14: 59: 20Z
      4. Это устанавливает заголовок моей локальной копии на желаемый коммит. Но тогда я не могу выдвинуть какие-либо изменения, потому что это позади пульта. И если я вытащу из удаленного узла, он снова окажется там, где он был при последнем коммите в удаленной ветви. Как полностью уничтожить (отовсюду) несколько подтверждений в моей локальной копии, которые были отправлены?
        2017-10-22 11: 47: 32Z
      5. @ Ade .. Вы можете использовать флаг git push -f .. Но будьте осторожны, он переопределит удаленный .. Убедитесь, что вы знаете, что хотите сделать ...
        2017-10-23 09: 02: 57Z

      Прежде чем ответить, давайте добавим некоторый фон, объяснив, что это за HEAD.

      First of all what is HEAD?

      HEAD - это просто ссылка на текущий коммит (последний) в текущей ветке. В любой момент времени может быть только один HEAD (исключая git worktree).

      Содержимое HEAD хранится внутри .git/HEAD и содержит 40 байтов SHA-1 текущего коммита.

      detached HEAD

      Если вы не используете последний коммит - это означает, что HEAD указывает на предыдущий коммит в истории, он называется detached HEAD .

       Введите описание изображения здесь

      В командной строке это будет выглядеть так: SHA-1 вместо имени ветви, поскольку HEAD не указывает на кончик текущей ветви:

       Введите описание изображения здесь

      Несколько вариантов восстановления после отсоединения HEAD:

      git checkout

      git checkout <commit_id>
      git checkout -b <new branch> <commit_id>
      git checkout HEAD~X // x is the number of commits t go back
      

      Это извлечет новую ветку, указывающую на желаемый коммит. Эта команда вернется к данному коммиту.

      На данный момент вы можете создать ветку и начать работать с этого момента:

      # Checkout a given commit.
      # Doing so will result in a `detached HEAD` which mean that the `HEAD`
      # is not pointing to the latest so you will need to checkout branch
      # in order to be able to update the code.
      git checkout <commit-id>
      
      # Create a new branch forked to the given commit
      git checkout -b <branch name>
      

      git reflog

      Вы также всегда можете использовать reflog. git reflog будет отображать любые изменения, которые обновили HEAD, и проверка требуемой записи reflog вернет HEAD к этой фиксации.

      Каждый раз, когда изменяется заголовок, в reflog появляется новая запись

      git reflog
      git checkout HEAD@{...}
      

      Это вернет вас к желаемой фиксации

       Введите описание изображения здесь

      git reset HEAD --hard <commit_id>

      «Переместите» свою голову назад к желаемому коммиту.

      # This will destroy any local modifications.
      # Don't do it if you have uncommitted work you want to keep.
      git reset --hard 0d1d7fc32
      
      # Alternatively, if there's work to keep:
      git stash
      git reset --hard 0d1d7fc32
      git stash pop
      # This saves the modifications, then reapplies that patch after resetting.
      # You could get merge conflicts, if you've modified things which were
      # changed since the commit you reset to.
      

      Эта схема иллюстрирует, какая команда что делает. Как вы можете видеть, reset && checkout модифицирует HEAD.

       Введите описание изображения здесь

          
      143
      2018-07-04 19: 25: 17Z
      1. Отличная подсказка для git reflog, это именно то, что мне нужно
        2016-03-13 21: 25: 01Z
      2. Ой! Все это кажется очень сложным ... разве нет простой команды, которая просто делает шаг назад в процессе? Как перейти с версии 1.1 в вашем проекте обратно на версию 1.0? Я ожидаю что-то вроде: git stepback_one_commit или что-то ....
        2016-03-20 14: 35: 15Z
      3. есть: git reset HEAD^ --hard`
        2016-03-20 14: 38: 43Z
      4. @ Kokodoko Да, это ужасно сложно ... и прекрасный пример того, как мало внимания уделяют эксперты, только начинающие. Пожалуйста, обратитесь к моему ответу здесь, а также к книге, которую я рекомендую в ней. Git - это НЕ то, что вы можете подобрать интуитивно. И я могу быть абсолютно уверен, что CodeWizard этого не сделал.
        2016-08-29 17: 17: 51Z

      Если вы хотите «отменить передачу», стереть последнее сообщение о коммите и вернуть измененные файлы обратно в стадию, вы должны использовать команду:

      git reset --soft HEAD~1
      
      • --soft указывает, что незафиксированные файлы должны быть сохранены как рабочие файлы, а не --hard, которые их отбрасывают.
      • HEAD~1 - последний коммит. Если вы хотите откатить 3 коммита, вы можете использовать HEAD~3. Если вы хотите откатиться до определенного номера ревизии, вы также можете сделать это, используя его хэш SHA.

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

      Источник: http://nakkaya.com/2009/09/24/git- удалить-последней фиксации /

          
      125
      2014-03-04 17: 25: 52Z
      1. Это мягко и аккуратно: без риска, если вы не продвинули свою работу
        2017-01-18 10: 04: 18Z

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

      git add . && git checkout master -f
      

      Краткое описание:

      • Он НЕ будет создавать коммиты, как git revert.
      • Он НЕ отсоединит вашу ГОЛОВУ, как git checkout <commithashcode>.
      • Он отменяет все ваши локальные изменения и удаляет все добавленные файлы с момента последнего коммита в ветке.
      • Он работает только с именами веток, поэтому таким образом вы можете вернуться только к последней фиксации в ветке.

      Я нашел гораздо более удобный и простой способ достижения вышеуказанных результатов:

      git add . && git reset --hard HEAD
      

      где HEAD указывает на последний коммит в текущей ветке.

      Это тот же код, что и предложенный boulder_ruby, но я добавил git add . до git reset --hard HEAD, чтобы стереть все новые файлы, созданные со времени последнего коммита, так как большинство людей ожидают, что я вернусь при возврате к последнему коммиту.

          
      105
      2014-06-24 20: 08: 20Z

      Это можно сделать с помощью следующих двух команд:

      git reset --hard [previous Commit SHA id here]
      git push origin [branch Name] -f
      

      Он удалит ваш предыдущий коммит Git.

      Если вы хотите сохранить изменения, вы также можете использовать:

      git reset --soft [previous Commit SHA id here]
      

      Тогда он сохранит ваши изменения.

          
      99
      2016-07-03 06: 30: 27Z
      1. Я попробовал полдюжины ответов вэтот пост, пока я не дошел до этого .. все эти другие, мой конфиг git продолжал давать мне ошибку при попытке нажать. Этот ответ сработал. Спасибо!
        2016-09-16 19: 47: 15Z
      2. Одна из деталей для меня заключалась в том, что я потерял diffs ..., которые я хотел сохранить, чтобы увидеть, что я сделал в коммите, который не работал. Поэтому в следующий раз я просто сохраню эти данные перед выполнением команды сброса
        2016-09-16 19: 49: 36Z
      3. Для меня это был единственный способ отменить неудачное слияние, в этом случае возврат не сработал. Спасибо!
        2017-01-19 20: 07: 19Z

      ОК, вернуться к предыдущей фиксации в git довольно просто ...

      Вернуть назад, не сохраняя изменения:

      git reset --hard <commit>
      

      Верните обратно, сохранив изменения:

      git reset --soft <commit>
      

      Объясните: используя git reset, вы можете сбросить его до определенного состояния, обычно это используется с хэшем коммита, как вы видели выше.

      Но, как вы видите, разница заключается в использовании двух флагов --soft и --hard, по умолчанию git reset с использованием флага --soft, но рекомендуется всегда использовать этот флаг, я объясняю каждый флаг:

      - мягкий

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

      - жесткий

      Будьте осторожны с этим флагом, он сбрасывает рабочее дерево и все изменения в отслеживаемых файлах, и все исчезнет!

      Я также создал изображение ниже, которое может случиться в реальной жизни при работе с git:

       git reset to commit

          
      65
      2019-02-05 13: 24: 37Z

      Ничто здесь не сработало для меня, кроме этой точной комбинации:

      git reset --hard <commit_hash>
      git push origin <branch_name> --force
      

      Ключ здесь - принудительное нажатие, никаких дополнительных сообщений о коммите /коммите и т. д.

          
      59
      2018-04-23 01: 47: 59Z
      1. Это сработало для меня, но вы должны быть осторожны, потому что вся история коммитов после аппаратного сброса потеряна и это действие необратимо. Вы должны быть уверены, что вы делаете.
        2018-04-19 19: 34: 15Z

      Скажем, у вас есть следующие коммиты в текстовом файле с именем ~/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> - вне меня.

          
      57
      2014-06-29 00: 13: 03Z
      1. Вы можете сделать git revert HEAD~3, чтобы удалить последние 3 коммита
        2012-02-19 18: 59: 22Z
      2. @ Rod - Нет, это не так. Эта команда вернет коммит, являющийся третьим прародителем HEAD (не последние три коммита).
        2012-09-11 22: 13: 05Z
      3. @ kflorence Хорошо, спасибо за информацию. Будет ли git revert -n master~3..master~1 работать? (Как видно из kernel.org/pub/software/SCM /мерзавец /документы /ГИТ-revert.html )
        2012-09-12 01: 59: 58Z
      4. @ Rod - Звучит правильно, конечно, уродливый синтаксис, хотя и не так? Я всегда находил проверку коммита, в который я хочу «вернуться», и фиксацию более интуитивным.
        2012-10-01 01: 12: 03Z
      5. Существует гораздо более простой способ сделать это сейчас, чем с помощью такого скрипта, просто используйте git revert --no-commit <start>..<end>, потому что git revert принимает диапазон фиксации в новом (или все?) версии Git. Обратите внимание, что начало диапазона не входит в обратный.
        2014-06-28 20: 02: 39Z

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

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

      Чтобы было ясно, эти альтернативы не являются лучшим способом возврата коммитов , Решения Jefromi - , но я просто хочу отметить, что вы можете также использовать эти другие методы для достижения того же, что и 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-area, которое затем можно зафиксировать.

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

      Это решение взято из решения svick для Извлечь старый коммит и сделать его новым .

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

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

          
      56
      2017-05-23 11: 47: 32Z
      1. Об альтернативе 1, один быстрый вопрос: тем самым мы не проигрываем между коммитами, верно?
        2014-12-02 10: 14: 33Z
      2. в альтернативе 2 точки означают что в этих командах?
        2014-12-02 10: 21: 40Z
      3. @ Bogac - точки указывают путь к файлу, в данном случае текущий каталог, поэтому предполагается, что вы запускаете его из корня рабочей копии.
        2014-12-02 19: 06: 38Z
      4. Предупреждение повторяется несколько раз в ответе, но кто-то может добавить, что почему это не лучший способ - по сравнению с чем-то вроде git revert HEAD~2..HEAD из связанного решения @ Cascabel's (@ Jefromi's). Я не вижу проблемы.
        2018-12-28 02: 16: 08Z

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

      # 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.

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

          
      56
      2019-04-28 19: 59: 43Z
      1. Чем этот ответ отличается от множества других?
        2016-05-10 17: 46: 51Z
      2. Ссылка не работает.
        2016-07-03 10: 59: 27Z
      3. Это неудачно. Я написал блогеру по электронной почте - надеюсь, у него все еще есть!
        2016-07-04 19: 29: 37Z
      4. 2016-09-01 17: 51: 49Z
      5. Синтаксис push отсутствует в большинстве других предложений о том, как это исправить. Работал отлично.
        2017-03-24 16: 20: 56Z

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

      git reset HEAD~1
      

      Так что нет необходимости в идентификаторах коммитов и т. д.)

          
      51
      2016-07-03 10: 56: 38Z
      1. не сработал, после этого вытащил git: error: Ваши локальные изменения в следующих файлах будут перезаписаны слиянием:
        2016-11-05 00: 21: 33Z
      2. @ malhal Это потому, что у вас были незафиксированные изменения. Спрятать /сбросить их, и тогда это будет работать без этой ошибки.
        2017-01-22 13: 37: 38Z

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

      git push -f ...
      

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

          
      34
      2013-09-28 19: 07: 07Z
      1. Обязательное предупреждение: не делайте этого , если вы делитесь своей веткой с другими людьми, у которых есть копии старых коммитов, потому что вы используете такой толчок заставит их пересинхронизировать свою работу. Для решения, которое подробно объясняет, как безопасно вернуть коммиты без потери работы с принудительным нажатием, см. этот ответ .
        2014-06-28 20: 00: 19Z
      2. Иногда это то, что вы хотите. Пример: совершил и передал несколько коммитов в неправильную ветвь (ветвь А). После выбора вишни для ветви B я хочу, чтобы эти коммиты были удалены из ветви A. Я бы не хотел возвращаться, так как обратный процесс позже будет применен, когда ветви A и B будут объединены вместе. Выполнение сброса --hard < commitId > в ветви A с последующим принудительным нажатием удаляет эти коммиты из ветви, сохраняя их в ветви B. Я могупокончим с этим, потому что я знаю, что никто не разрабатывает на ветви A.
        2014-10-22 20: 44: 19Z
      3. Спасибо! Я не мог понять, как заставить удаленную ветвь соответствовать моей локальной ветке, просто нужно было принудительно нажать
        .
        2017-02-06 12: 49: 58Z

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

      git back
      

      На странице man его также можно использовать как таковое:

      # Remove the latest three commits
      git back 3
      
          
      34
      2014-06-28 20: 19: 45Z

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

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

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

        $ git log -n 4 р>

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

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

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

      git pull --all
      git reset --hard HEAD~1
      git push --force
      
          
      29
      2018-07-05 20: 56: 59Z

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

      git reset --hard HEAD
      
          
      27
      2018-07-04 19: 28: 44Z

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

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

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

      git reset --hard HEAD~1
      

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

          
      26
      2014-06-28 19: 51: 32Z
      1. Обязательное предупреждение: не делайте этого , если вы делитесь своей веткой с другими людьми, у которых есть копии старых коммитов, потому что вы используете такой жесткий сброс заставит их заново синхронизировать свою работу с новой веткой сброса. Для решения, которое подробно объясняет, как безопасно вернуть коммиты без потери работы с аппаратным сбросом, см. этот ответ .
        2014-06-28 19: 57: 00Z
      2. Кроме того, чтобы быть понятным, git show HEAD эквивалентен просто использованию git log HEAD -1.
        2014-06-28 19: 58: 54Z

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

      git reset <SHA>
      

      Если изменения не требуются от предыдущего коммита в HEAD и просто отменяются все изменения, выполните:

      git reset --hard <SHA>
      
          
      20
      2016-07-03 10: 21: 53Z

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

      git add -A .
      git reset --hard HEAD
      

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

          
      20
      2016-07-03 10: 55: 25Z

      Это еще один способ прямого сброса на недавний коммит

      git stash
      git stash clear
      

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

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

          
      20
      2016-07-03 10: 57: 18Z
      1. ПРИМЕЧАНИЕ. Новые файлы, не добавленные в индекс, не сохраняются. Вы тоже добавили их или удалили вручную.
        2016-12-08 14: 08: 46Z
      2. Почему очистка тайника? Помимо того, что это не решение проблемы, это на самом деле вредно. Чтение самого первого предложения вопроса немедленно лишает законной силы решение для тайника (что может быть полезно ТОЛЬКО для сброса в последний коммит).
        2019-03-07 07: 35: 51Z

      Я полагаю, что некоторые люди могут прийти к этому вопросу, желая знать, как откатить совершенные изменения, которые они сделали в своем мастере, - т.е. выбросить все и вернуться к origin /master, в этом случае сделать это:

      git reset --hard origin/master
      

      https://superuser.com/questions/273172/how-to -reset-мастер-к-происхождения-мастер р>     

      19
      2017-03-20 10: 18: 20Z

      Revert - команда для отката коммитов.

      git revert <commit1> <commit2> 
      

      Пример:

      git revert 2h3h23233 р>

      Он может принимать диапазон от ГОЛОВКИ, как показано ниже. Здесь 1 говорит: «Вернуть последний коммит».

      git revert HEAD~1..HEAD р>

      а затем сделайте git push

          
      16
      2016-05-27 06: 05: 57Z

      Вернуть самый последний коммит:

      git reset --hard HEAD
      

      HEAD - это просто ссылка на текущий коммит (последний) в текущей ветке. В любой момент времени может быть только один HEAD.

      Возврат к старой фиксации: Самый быстрый способ восстановить старую версию - использовать команду reset:

      # Resets index to former commit
      git reset 56e05fced 
      
      # Moves pointer back to previous HEAD
      git reset --soft HEAD@{1}
      
      # Updates working copy to reflect the new commit
      git reset --hard
      

      Это перемотает вашу ветку HEAD до указанной версии. Все коммиты, которые пришли после этой версии, фактически отменены; Ваш проект точно такой, каким он был в тот момент.

      Команда сброса поставляется с несколькими параметрами, одним из наиболее интересных из которых является флаг --soft. Если вы используете его вместо --hard, Git сохранит все изменения в этих «отмененных» фиксациях как локальные изменения.

      Восстановление редакции в Новой локальной ветке

      Как уже было сказано, использование команды сброса в вашей ветви HEAD является довольно радикальным действием: оно удалит все коммиты (в этой ветке), которые пришли после указанной ревизии. Если вы уверены, что это то, что вы хотите, каждыйЯ в порядке.

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

      git checkout -b old-project-state 0ad5a7a6
      

      Обычно команда checkout используется только для переключения веток. Однако, предоставив параметр -b, вы также можете позволить ему создать новую ветвь (в этом примере с именем old-project-state ). Если вы не хотите, чтобы он начинался с текущей ревизии HEAD, вам также нужно предоставить хеш коммита - старую ревизию проекта, которую мы хотим восстановить.

      Теперь у вас есть новая ветка с именем old-project-state , отражающая старую версию вашего проекта - без касания или даже удаления каких-либо других коммитов или веток.

          
      16
      2018-08-31 11: 08: 13Z

      Если ситуация срочная , и вы просто хотите выполнить то, что спросил спрашивающий, быстро и грязно , если ваш проект находится в каталоге "my проект ":

      1. Скопируйте весь каталог и назовите его как-нибудь еще, например, "мой проект - копировать"

      2. делать:

        git reset --hard [first-4-letters&numbers-of-commit's-SHA]
        

      Затем у вас есть две версии в вашей системе ... вы можете просматривать, копировать или изменять файлы, представляющие интерес, или что-то еще из предыдущего коммита. Вы можете полностью удалить файлы в разделе «Мой проект - копия», если решили, что новая работа никуда не денется ...

      Очевидная вещь, если вы хотите продолжить работу с состоянием проекта без фактического сброса работы, поскольку этот извлеченный коммит состоит в том, чтобы снова переименовать каталог: удалить проект, содержащий извлеченный коммит (или дать ему временное имя), и переименуйте свой каталог «мой проект - копия» обратно в «мой проект». Тогда, вероятно, сделайте еще один коммит довольно скоро.

      Git - блестящее творение, но вы не можете просто «поднять его на лету»: также люди, которые пытаются объяснить это слишком часто , предполагают предварительное знание других VCS [Системы контроля версий] ] и вникать слишком глубоко, слишком рано, и совершать другие преступления, например, использовать взаимозаменяемые термины для «проверки» - способами, которые иногда кажутся почти рассчитанными, чтобы запутать новичка.

      Чтобы избавить себя от стресса, вам нужно в значительной степени прочитать книгу о Git - я бы порекомендовал " Контроль версий с помощью Git ". И если вы можете доверять мне (или, скорее, моим шрамам), когда я говорю «должен», из этого следует, что вы могли бы сделать это СЕЙЧАС . Большая часть сложности Git происходит от ветвления и последующего повторного использования. Но из твоего вопроса нет причины, по которой люди должны ослеплять тебя наукой .

      Особенно, если, например, это отчаянная ситуация, и вы новичок в Git!

      PS: Еще одна мысль: (сейчас) на самом деле довольно просто хранить Git-репозиторий («repo») в каталоге, отличном от каталога с рабочими файлами. Это означает, что вам не нужно будет копировать весь репозиторий Git, используя приведенный выше быстрый & грязный раствор. Смотрите ответ Фрайера с помощью --separate-git-dir . Будьте предупреждены , однако: если у вас есть репозиторий «отдельный каталог», который вы не копируете и выполняете полный сброс, все версии, следующие за фиксацией сброса, будут потеряны навсегда, если вы регулярно создавайте резервные копии своего хранилища, желательно в облаке (например, Google Диск ). ) среди других мест.

          
      13
      2017-05-23 11: 55: 13Z

      Попробуйте сбросить до желаемого коммита -

      git reset <COMMIT_ID> р>

      (для проверки COMMIT_ID используйте git log)

      Это вернет все измененные файлы в состояние без добавления.

      Теперь вы можете checkout всех не добавленных файлов

      git checkout . р>

      Проверьте git log, чтобы подтвердить изменения.

      UPDATE

      Если в вашем репо есть один-единственный коммит, попробуйте

      git update-ref -d HEAD р>     

      13
      2018-04-17 10: 02: 40Z

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

      Сначала вы должны удалить Develop из происхождения:

      git push origin :develop (note the colon)
      

      Тогда вам нужно довести разработку до нужного вам состояния, позвольте мне предположить, что хеш коммита равен EFGHIJK:

      git reset --hard EFGHIJK
      

      Наконец, нажмите кнопку развернуть снова:

      git push origin develop
      
          
      11
      2017-04-19 07: 18: 34Z
        

      Осторожно! Эта команда может привести к потере истории коммитов, если пользователь ошибочно добавил неверный коммит. Всегда имейте дополнительную резервную копию вашего мерзавца   где еще на всякий случай, если вы делаете ошибки, чем вы немного безопаснее.   :)

      У меня была похожая проблема, и я хотел вернуться к предыдущей фиксации. В моем случае я не был заинтересован в сохранении нового коммита, поэтому использовал Hard.

      Вот как я это сделал:

      git reset --hard CommitId && git clean -f
      

      Это вернется в локальный репозиторий, здесь после использования git push -f будет обновляться удаленный репозиторий.

      git push -f
      
          
      11
      2018-02-02 13: 51: 57Z

      Если вы хотите исправить ошибку во время последнего коммита, хорошей альтернативой будет использование команды git commit --amend . Если последняя фиксация не указана какой-либо ссылкой, это сделает свое дело, так как создаст фиксацию с тем же родителем, что и последняя фиксация. Если нет ссылки на последний коммит, он просто будет отброшен, и этот коммит будет последним коммитом. Это хороший способ исправления коммитов без возврата коммитов. Однако у него есть свои ограничения.

          
      10
      2015-07-01 11: 35: 54Z
источник размещен Вот