Как мне вернуться из моего текущего состояния к снимку, сделанному при определенной фиксации?
Если я это сделаю 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
?
git
git-checkout
git-reset
git-revert
Сумасшедший серб
источник
источник
Ответы:
Это во многом зависит от того, что вы подразумеваете под «возвратом».
Временно переключиться на другой коммит
Если вы хотите временно вернуться к нему, дурачиться, а затем вернуться туда, где вы находитесь, все, что вам нужно сделать, это проверить желаемый коммит:
Или, если вы хотите делать коммиты, пока вы там, идите и создайте новую ветку, пока вы там:
Чтобы вернуться туда, где вы были, просто проверьте ветку, на которой вы были снова. (Если вы внесли изменения, как всегда при переключении веток, вам придется обращаться с ними соответствующим образом. Вы можете сбросить их, чтобы выбросить; вы можете спрятать, оформить заказ, спрятать всплывающее окно, чтобы взять их с собой; вы можете зафиксировать их там на ветку, если там нужна ветка.)
Трудно удалить неопубликованные коммиты
Если, с другой стороны, вы хотите действительно избавиться от всего, что вы сделали с тех пор, есть две возможности. Во-первых, если вы не опубликовали ни одного из этих коммитов, просто выполните сброс:
Если вы запутались, вы уже выбросили свои локальные изменения, но вы можете, по крайней мере, вернуться туда, где вы были раньше, сбросив заново.
Отменить опубликованные коммиты с новыми коммитами
С другой стороны, если вы опубликовали работу, вы, вероятно, не хотите сбрасывать ветку, поскольку это фактически переписывает историю. В этом случае вы действительно можете отменить коммиты. В Git возврат имеет очень специфическое значение: создайте коммит с обратным патчем, чтобы отменить его. Таким образом, вы не переписываете историю.
На самом деле
git-revert
man-страница охватывает многое из этого в своем описании. Еще одна полезная ссылка - это раздел git-scm.com, где обсуждается git-revert .Если вы решили, что не хотите отменять все-таки, вы можете отменить возврат (как описано здесь) или сбросить его до возврата (см. Предыдущий раздел).
Вы также можете найти этот ответ полезным в этом случае:
Как переместить HEAD обратно в предыдущее место? (Отдельная голова)
источник
git revert HEAD~3
как лучший ват , чтобы вернуться3
фиксациями является важным утром условности.git reset --hard 0d1d7fc32e5a947fbd92ee598033d85bfc445a50
git revert --no-commit hash1 hash2 ...
и после этого просто фиксировать каждыйgit commit -m "Message"
Здесь много сложных и опасных ответов, но на самом деле это просто:
Это вернет все из HEAD обратно в хеш коммита, что означает, что он будет воссоздавать это состояние коммита в рабочем дереве, как если бы каждый коммит с тех пор был возвращен. Затем вы можете зафиксировать текущее дерево, и оно создаст совершенно новый коммит, по существу эквивалентный коммиту, к которому вы «вернулись».
(
--no-commit
Флаг позволяет git отменять все коммиты одновременно, иначе вам будет предложено сообщение для каждого коммита в диапазоне, засоряя вашу историю ненужными новыми коммитами.)Это безопасный и простой способ возврата к предыдущему состоянию . История не уничтожается, поэтому ее можно использовать для коммитов, которые уже были обнародованы.
источник
--no-edit
вместо--no-commit
, чтобы вам не приходилось редактировать сообщение о коммите для каждой реверсии.git diff --cached
.$ git revert --no-commit 53742ae..HEAD
возвращаетсяfatal: empty commit set passed
81bcc9e HEAD{0}; e475924 HEAD{1}, ...
(отgit reflog
), и я хотел отменить то, что я сделал81bcc9e
, затем я должен был это сделатьgit revert e475924..HEAD
Мошенник кодер?
Работаете самостоятельно и просто хотите, чтобы это работало? Следуйте приведенным ниже инструкциям, они надежно работали для меня и многих других на протяжении многих лет.
Работаете с другими? Git это сложно. Прочитайте комментарии ниже этого ответа, прежде чем делать что-то необдуманное.
Возврат рабочей копии в самый последний коммит
Чтобы вернуться к предыдущей фиксации, игнорируя любые изменения:
где HEAD - последний коммит в вашей текущей ветке
Возврат рабочей копии в более старый коммит
Чтобы вернуться к коммиту, который старше самого последнего коммита:
Кредиты переходят к аналогичному вопросу переполнения стека. Вернуть ли к фиксации хэш SHA в Git? ,
источник
git reset --hard 56e05fc; git reset --soft HEAD@{1}; git commit
.Лучший вариант для меня и, вероятно, для других - это опция сброса Git:
Это был лучший вариант для меня! Это просто, быстро и эффективно!
Также из комментариев, если вы хотите менее «баллистический» метод, вы можете использовать
источник
git push -f
флаг .. Но будьте осторожны, он переопределит удаленный .. Убедитесь, что вы знаете, что вы хотите сделать.Прежде чем ответить, давайте добавим некоторую предысторию, объясняя, что это
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 reflog
Вы всегда можете использовать
reflog
также.git reflog
будет отображаться любое изменение, которое обновило,HEAD
и проверка желаемой записи reflogHEAD
вернет этот коммит.Каждый раз, когда ГОЛОВКА изменяется, в
reflog
Это вернет вас к желаемой фиксации
git reset HEAD --hard <commit_id>
«Переместите» свою голову назад к желаемому коммиту.
git rebase --no-autostash
.Эта схема иллюстрирует, какая команда что делает. Как вы можете видеть там,
reset && checkout
изменитеHEAD
.источник
git reflog
, это именно то, что мне было нужноgit reset HEAD^
--hard`Если вы хотите «отменить», стереть последнее сообщение о коммите и вернуть измененные файлы в промежуточный режим, вы должны использовать команду:
--soft
указывает, что незафиксированные файлы должны быть сохранены как рабочие файлы, в отличие от--hard
которых они будут отброшены.HEAD~1
последний коммит Если вы хотите откатить 3 коммита, вы можете использоватьHEAD~3
. Если вы хотите выполнить откат до определенного номера ревизии, вы также можете сделать это, используя его хэш SHA.Это чрезвычайно полезная команда в ситуациях, когда вы совершили неправильную вещь и хотите отменить последний коммит.
Источник: http://nakkaya.com/2009/09/24/git-delete-last-commit/
источник
Вы можете сделать это с помощью следующих двух команд:
Это удалит ваш предыдущий коммит Git.
Если вы хотите сохранить свои изменения, вы также можете использовать:
Тогда это сохранит ваши изменения.
источник
Я перепробовал множество способов вернуть локальные изменения в Git, и кажется, что это работает лучше всего, если вы просто хотите вернуться к последнему состоянию фиксации.
Краткое описание:
git revert
делает.git checkout <commithashcode>
делает.Я нашел гораздо более удобный и простой способ для достижения результатов выше:
где HEAD указывает на последний коммит в текущей ветке.
Это тот же код, что и предложенный boulder_ruby, но я добавил
git add .
ранее,git reset --hard HEAD
чтобы стереть все новые файлы, созданные со времени последнего коммита, так как большинство людей ожидают, что я вернусь к последнему коммиту.источник
Хорошо, вернуться к предыдущему коммиту в Git довольно просто ...
Вернуть обратно без сохранения изменений:
Вернитесь назад с сохранением изменений:
Пояснение: с помощью
git reset
можно сбросить до определенного состояния. Обычно вы используете это с хэшем коммита, как вы видели выше.Но, как вы видите, различие заключается в использовании двух флагов
--soft
и--hard
, по умолчанию,git reset
использовании--soft
флага, но всегда полезно использовать флаг, я объясняю каждый флаг:--мягкий
Флаг по умолчанию, как объяснено, не требует его предоставления, не изменяет рабочее дерево, но добавляет все измененные файлы, готовые к фиксации, поэтому вы возвращаетесь к состоянию фиксации, при котором изменения файлов становятся неизмененными.
--жесткий
Будьте осторожны с этим флагом. Он сбрасывает рабочее дерево и все изменения в отслеживаемых файлах и все пропадет!
Я также создал изображение ниже, которое может случиться в реальной жизни, работая с Git:
источник
git reset
этоgit reset --mixed
не такgit reset --soft
. Пожалуйста, проверьте, в чем разница между git reset --mixed, --soft и --hard? и на простом английском языке, что делает «git reset»?Предполагая, что вы говорите о master и о соответствующей ветке (при этом речь может идти о любой рабочей ветке, которая вас интересует):
Я нашел ответ от в сообщении в блоге (теперь больше не существует)
Обратите внимание, что это Сброс и Принудительное изменение на пульте, так что, если другие члены вашей команды уже сделали git, у вас возникнут проблемы. Вы уничтожаете историю изменений, что является важной причиной, по которой люди используют git.
Лучше использовать возврат (см. Другие ответы), чем сброс. Если вы команда из одного человека, то это, вероятно, не имеет значения.
источник
Скажем, у вас есть следующие коммиты в текстовом файле с именем
~/commits-to-revert.txt
(яgit log --pretty=oneline
их получал)Создайте сценарий оболочки Bash, чтобы вернуть каждый из них:
Это вернет все обратно к предыдущему состоянию, включая создание файлов и каталогов, а также удаление, зафиксирует его в вашей ветви, и вы сохраните историю, но вы вернетесь к той же файловой структуре. Почему Git не имеет,
git revert --to <hash>
вне меня.источник
git revert HEAD~3
чтобы удалить последние 3 коммитовgit revert -n master~3..master~1
работать? (Как видно из kernel.org/pub/software/scm/git/docs/git-revert.html )git revert --no-commit <start>..<end>
, потому чтоgit revert
принимает фиксации диапазона в новом (или все?) Версии Git. Обратите внимание, что начало диапазона не входит в обратный.Дополнительные альтернативы решениям Jefromi
Решения Jefromi, безусловно, самые лучшие, и вам обязательно стоит их использовать. Однако для полноты картины я также хотел показать эти другие альтернативные решения, которые также можно использовать для отмены фиксации (в том смысле, что вы создаете новую фиксацию, которая отменяет изменения в предыдущей фиксации , точно так же, как и то, что
git revert
происходит).Чтобы быть ясным, эти альтернативы не лучший способ отменить коммиты , как решения Jefromi , но я просто хочу отметить, что вы можете также использовать эти другие методы для достижения того же, что и
git revert
.Альтернатива 1: жесткий и мягкий сброс
Это очень немного измененная версия решения Чарльза Бейли « Вернуть коммит с помощью хэша SHA в Git»? :
Это в основном работает с использованием того факта, что программный сброс оставит состояние предыдущего коммитирования в индексной / промежуточной области, которое вы можете затем зафиксировать.
Альтернатива 2: удалить текущее дерево и заменить новым
Это решение взято из решения svick Checkout old commit и делает его новым коммитом :
Подобно альтернативе № 1, он воспроизводит состояние
<commit>
текущей рабочей копии. Это необходимо сделатьgit rm
сначала, потомуgit checkout
что не удалит файлы, которые были добавлены с тех пор<commit>
.источник
git revert HEAD~2..HEAD
связанного решения @ Cascabel (@ Jefromi's). Я не вижу проблемы.Вот гораздо более простой способ вернуться к предыдущему коммиту (и иметь его в незафиксированном состоянии, чтобы делать с ним что угодно):
Таким образом, нет необходимости в фиксации идентификаторов и так далее :)
источник
Существует команда (не входящая в состав ядра Git, но она входит в пакет git-extras ) специально для возврата и постановки старых коммитов:
Для справочной страницы , он также может быть использован как таковой:
источник
Лучший способ это:
Это сбросит ветку на конкретный коммит, а затем загрузит на удаленный сервер те же коммиты, что и на локальном (это полностью исключит команды после этого конкретного коммита)
Будьте осторожны, когда
--force
флаг удаляет все последующие коммиты после выбранного коммита без возможности их восстановления.источник
После всех изменений, когда вы нажимаете все эти команды, вам, возможно, придется использовать:
И не только
git push
.источник
Вы можете выполнить все эти начальные шаги самостоятельно и вернуться в репозиторий Git.
Извлеките последнюю версию вашего хранилища из Bitbucket с помощью
git pull --all
команды.Запустите команду Git log с
-n 4
вашего терминала. Число после-n
определяет количество подтверждений в журнале, начиная с самого последнего принятия в вашей локальной истории.Сбросьте заголовок истории вашего репозитория, используя
git reset --hard HEAD~N
где N - количество коммитов, которые вы хотите вернуть назад. В следующем примере заголовок будет возвращен на один коммит до последнего коммита в истории репозитория:Нажмите изменения в репозитории Git,
git push --force
чтобы принудительно нажать изменения.Если вы хотите, чтобы Git-репозиторий был предыдущим коммитом:
источник
Возврат к самой последней фиксации и игнорирование всех локальных изменений:
источник
Выберите необходимый коммит и проверьте его с помощью
пока вы не получите необходимый коммит. Чтобы ГОЛОВА указала на это, сделайте
или
git reset --hard HEAD~2
или что угодно.источник
git show HEAD
эквивалентно просто использоватьgit log HEAD -1
.Если ситуация срочная , и вы просто хотите сделать то, что спросил спрашивающий, быстрым и грязным способом, предполагая, что ваш проект находится в каталоге, называемом, например, «мой проект»:
Быстрый и неаккуратный : в зависимости от обстоятельств, быстро и грязно на самом деле может быть очень хорошим. Что мое решение здесь делает, так это НЕ необратимо заменяет файлы, которые у вас есть в вашем рабочем каталоге, на файлы, извлеченные / извлеченные из глубины репозитория git, скрывающиеся под вашим каталогом .git /, используя чертовски умные и дьявольски мощные команды git, из которых есть многие. ВЫ НЕ ДОЛЖНЫ ДЕЛАТЬ ТАКОЕ ГЛУБОКОЕ ДЕЙСТВИЕ, ЧТОБЫ ВОССТАНОВИТЬ то, что может показаться катастрофической ситуацией, и попытка сделать это без достаточного опыта может оказаться фатальной .
Скопируйте весь каталог и назовите его как-нибудь еще, например, «мой проект - копия». Предполагая, что ваши файлы репозитория git ("repo") находятся в каталоге "мой проект" (место по умолчанию для них, в каталоге с именем ".git"), вы теперь скопируете свои рабочие файлы и файлы репо.
Сделайте это в каталоге "мой проект":
Это вернет состояние репо в «моем проекте» к тому, что было, когда вы сделали этот коммит («коммит» означает снимок ваших рабочих файлов). Все коммиты с тех пор будут навсегда потеряны в «моем проекте», НО ... они все равно будут присутствовать в репозитории в разделе «мой проект - копия», поскольку вы скопировали все эти файлы, в том числе и те, которые находятся в ... /. Git /.
Затем у вас есть две версии в вашей системе ... вы можете просматривать, копировать или изменять файлы, представляющие интерес, или что-то еще из предыдущего коммита. Вы можете полностью отбросить файлы в разделе «Мой проект - копия», если вы решили, что новая работа, так как восстановленный коммит никуда не денется ...
Очевидная вещь, если вы хотите продолжить состояние проекта, не отказываясь от работы, поскольку этот извлеченный коммит снова переименует ваш каталог: удалите проект, содержащий извлеченный коммит (или дайте ему временное имя), и переименуйте свой " мой проект - скопируйте "каталог" обратно в "мой проект". Тогда, возможно, попытайтесь понять некоторые другие ответы здесь, и, вероятно, сделайте еще один коммит довольно скоро.
Git - блестящее творение, но абсолютно никто не может просто «поднять его на лету»: также люди, которые слишком часто пытаются объяснить это, предполагают, что они уже знакомы с другими VCS [системами контроля версий] и слишком глубоко вникают слишком рано, и совершать другие преступления, такие как использование взаимозаменяемых терминов для «проверки» - способами, которые иногда кажутся почти рассчитанными, чтобы запутать новичка.
Чтобы избавить себя от стресса, учитесь на моих шрамах. Вы должны в значительной степени прочитать книгу по Git - я бы порекомендовал «Контроль версий с помощью Git» . Сделай это раньше, чем позже. Если вы это сделаете, имейте в виду, что большая часть сложности Git связана с ветвлением, а затем с повторным объединением: вы можете пропустить эти части в любой книге. Из твоего вопроса нет причин, почему люди должны ослеплять тебя наукой .
Особенно, если, например, это отчаянная ситуация, и вы новичок в Git!
PS: Еще одна мысль: (сейчас) на самом деле довольно просто хранить репозиторий Git в каталоге, отличном от каталога с рабочими файлами. Это означает, что вам не нужно будет копировать весь репозиторий Git, используя вышеуказанное быстрое и грязное решение. Смотрите ответ Фрайера, используя
--separate-git-dir
здесь . Тем не менее, будьте осторожны : если у вас есть репозиторий «отдельный каталог», который вы не копируете, и вы выполняете полный сброс, все версии, следующие за фиксацией сброса, будут потеряны навсегда, если у вас нет, как вы абсолютно должны, регулярно создавайте резервные копии вашего хранилища, желательно в облаке (например, Google Drive ) среди других мест.В этой теме «резервного копирования в облако» следующим шагом является открытие учетной записи (конечно же, бесплатной) с помощью GitHub или (на мой взгляд, лучше) GitLab . Затем вы можете регулярно выполнять
git push
команду, чтобы сделать ваше облачное хранилище обновленным «должным образом». Но, опять же, говорить об этом слишком рано.источник
Это еще один способ прямого сброса на недавний коммит
Он напрямую удаляет все изменения, которые вы внесли с момента последнего коммита.
PS: у него есть небольшая проблема; он также удаляет все недавно сохраненные вами тайники. Что, я думаю, в большинстве случаев не имеет значения.
источник
Чтобы полностью очистить каталог кодера от случайных изменений, мы использовали:
Просто
git reset --hard HEAD
избавится от модификаций, но не избавится от «новых» файлов. В их случае они случайно перетащили важную папку куда-то случайно, и все эти файлы были обработаны Git как новые, так чтоreset --hard
не удалось это исправить. Запустивgit add -A .
предварительно, он явно отслеживал их всех с помощью git, чтобы сбросить их при перезагрузке.источник
Чтобы сохранить изменения предыдущего коммита в HEAD и перейти к предыдущему коммиту, выполните:
Если изменения не требуются от предыдущего коммита в HEAD и просто отменить все изменения, выполните:
источник
Я полагаю, что некоторые люди могут прийти к этому вопросу, желая знать, как откатить совершенные изменения, которые они сделали в своем мастере - то есть выбросить все и вернуться к origin / master, и в этом случае сделать это:
/superuser/273172/how-to-reset-master-to-origin-master
источник
Revert - команда для отката коммитов.
Образец:
git revert 2h3h23233
Он способен принимать дальность от головы, как показано ниже. Здесь 1 говорит «отменить последний коммит».
git revert HEAD~1..HEAD
а затем сделать
git push
источник
Попробуйте сбросить до желаемого коммита -
git reset <COMMIT_ID>
(чтобы проверить использование COMMIT_ID
git log
)Это вернет все измененные файлы в состояние без добавления.
Теперь вы можете
checkout
все файлы, не добавленныеgit checkout .
Проверьте,
git log
чтобы проверить ваши изменения.ОБНОВИТЬ
Если у вас есть один-единственный коммит в репо, попробуйте
git update-ref -d HEAD
источник
Поскольку ваши коммиты передаются удаленно, вам нужно их удалить. Позвольте мне предположить, что ваша ветвь развивается, и она отталкивается от происхождения .
Сначала вам нужно удалить развернутый объект из источника :
Затем вам нужно довести до нужного вам состояния, позвольте мне предположить, что хеш коммита - EFGHIJK:
Наконец, нажмите развиваться снова:
источник
У меня была похожая проблема, и я хотел вернуться к предыдущей фиксации. В моем случае я не был заинтересован в сохранении нового коммита, поэтому я использовал
Hard
.Вот как я это сделал:
Это вернется в локальный репозиторий, а здесь после использования
git push -f
обновит удаленный репозиторий.источник
В GitKraken вы можете сделать это:
Щелкните правой кнопкой мыши на коммите, который вы хотите сбросить, выберите: Reset to this commit / Hard :
Снова щелкните правой кнопкой мыши на коммите, выберите: Текущее имя ветви / Push :
Нажмите на Force Push :
Обсервованный : Вы должны быть осторожны, потому что вся история коммитов после аппаратного сброса потеряна, и это действие необратимо. Вы должны быть уверены, что вы делаете.
источник
Если вы хотите исправить какую-то ошибку в последнем коммите, хорошей альтернативой будет использование команды git commit --amend . Если последняя фиксация не указана какой-либо ссылкой, это сделает свое дело, так как создаст фиксацию с тем же родителем, что и последняя фиксация. Если нет ссылки на последний коммит, он просто будет отброшен, и этот коммит будет последним коммитом. Это хороший способ исправления коммитов без возврата коммитов. Однако у него есть свои ограничения.
источник