Как вернуть все локальные изменения в проекте, управляемом Git, в предыдущее состояние? - PullRequest
1745 голосов
/ 18 июля 2009

У меня есть проект, в котором я запустил git init. После нескольких коммитов я сделал git status, который сказал мне, что все было в курсе и не было никаких локальных изменений

Затем я сделал несколько последовательных изменений и понял, что хочу все выбросить и вернуться в исходное состояние. Эта команда сделает это для меня?

git reset --hard HEAD

Ответы [ 12 ]

3121 голосов
/ 18 июля 2009

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

git checkout .

Если вы хотите отменить изменения, внесенные в индекс (т. Е. Добавленные вами), сделайте это. Предупреждение: это сбросит все ваши невыдвинутые коммиты на master! :

git reset

Если вы хотите отменить внесенные вами изменения, сделайте следующее:

git revert <commit 1> <commit 2>

Если вы хотите удалить неотслеживаемые файлы (например, новые файлы, созданные файлы):

git clean -f

Или неотслеживаемые каталоги (например, новые или автоматически созданные каталоги):

git clean -fd
365 голосов
/ 20 июля 2009

Примечание: вы также можете запустить

git clean -fd

в

git reset --hard

будет не удалять неотслеживаемые файлы, где git-clean удалит все файлы из корневого каталога отслеживания, которые не находятся под отслеживанием git. ВНИМАНИЕ - будьте осторожны с этим! Полезно сначала запустить пробный запуск с помощью git-clean, чтобы посмотреть, что он удалит.

Это также особенно полезно, когда вы получаете сообщение об ошибке

~"performing this command will cause an un-tracked file to be overwritten"

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

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

99 голосов
/ 20 марта 2017

Re-клон

GIT=$(git rev-parse --show-toplevel)
cd $GIT/..
rm -rf $GIT
git clone ...
  • ✅ Удаляет локальные не выдвинутые коммиты
  • ✅ Отменяет сделанные вами изменения в отслеживаемых файлах
  • ✅ Восстанавливает отслеженные файлы, которые вы удалили
  • ✅ Удаляет файлы / каталоги, перечисленные в .gitignore (например, файлы сборки)
  • ✅ Удаляет файлы / каталоги, которые не отслеживаются и не находятся в .gitignore
  • ? Вы не забудете этот подход
  • band Пропускная способность отходов

Ниже приведены другие команды, которые я ежедневно забываю.

Очистить и сбросить

git clean -f -d -x
git reset --hard
  • ❌ Удаляет локальные не выдвинутые коммиты
  • ✅ Отменяет сделанные вами изменения в отслеживаемых файлах
  • ✅ Восстанавливает отслеженные файлы, которые вы удалили
  • ✅ Удаляет файлы / каталоги, перечисленные в .gitignore (например, файлы сборки)
  • ✅ Удаляет файлы / каталоги, которые не отслеживаются и не находятся в .gitignore

Clean

git clean -f -d -x
  • ❌ Удаляет локальные не выдвинутые коммиты
  • ❌ Отменяет сделанные вами изменения в отслеживаемых файлах
  • ❌ Восстанавливает отслеженные файлы, которые вы удалили
  • ✅ Удаляет файлы / каталоги, перечисленные в .gitignore (например, файлы сборки)
  • ✅ Удаляет файлы / каталоги, которые не отслеживаются и не находятся в .gitignore

Сброс

git reset --hard
  • ❌ Удаляет локальные не выдвинутые коммиты
  • ✅ Отменяет сделанные вами изменения в отслеживаемых файлах
  • ✅ Восстанавливает отслеженные файлы, которые вы удалили
  • ❌ Удаляет файлы / каталоги, перечисленные в .gitignore (например, файлы сборки)
  • ❌ Удаляет файлы / каталоги, которые не отслеживаются и не находятся в .gitignore

Примечания

Контрольный пример для подтверждения всего вышеперечисленного (используйте bash или sh):

mkdir project
cd project
git init
echo '*.built' > .gitignore
echo 'CODE' > a.sourceCode
mkdir b
echo 'CODE' > b/b.sourceCode
cp -r b c
git add .
git commit -m 'Initial checkin'
echo 'NEW FEATURE' >> a.sourceCode
cp a.sourceCode a.built
rm -rf c
echo 'CODE' > 'd.sourceCode'

См. Также

  • git revert для создания новых коммитов, которые отменяют предыдущие коммиты
  • git checkout для возврата во времени к предыдущим коммитам (может потребоваться выполнение выше указанных команд)
  • git stash аналогично git reset выше, но вы можете отменить его
73 голосов
/ 22 апреля 2015

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

git fetch  # will fetch the latest changes on the remote
git reset --hard origin/master # will set your local branch to match the representation of the remote just pulled down.
48 голосов
/ 19 июля 2009

Загляните в git-reflog. В нем будут перечислены все состояния, которые он помнит (по умолчанию 30 дней), и вы можете просто оформить заказ на тот, который вам нужен. Например:

$ git init > /dev/null
$ touch a
$ git add .
$ git commit -m"Add file a" > /dev/null
$ echo 'foo' >> a
$ git commit -a -m"Append foo to a" > /dev/null
$ for i in b c d e; do echo $i >>a; git commit -a -m"Append $i to a" ;done > /dev/null
$ git reset --hard HEAD^^ > /dev/null
$ cat a
foo
b
c
$ git reflog
145c322 HEAD@{0}: HEAD^^: updating HEAD
ae7c2b3 HEAD@{1}: commit: Append e to a
fdf2c5e HEAD@{2}: commit: Append d to a
145c322 HEAD@{3}: commit: Append c to a
363e22a HEAD@{4}: commit: Append b to a
fa26c43 HEAD@{5}: commit: Append foo to a
0a392a5 HEAD@{6}: commit (initial): Add file a
$ git reset --hard HEAD@{2}
HEAD is now at fdf2c5e Append d to a
$ cat a
foo
b
c
d
34 голосов
/ 04 июня 2014

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

Вот мой текущий скрипт bash для этого, который работает постоянно.

#!/bin/sh
git reset --hard
git clean -f -d
git checkout -- HEAD

Запуск из рабочей копии корневого каталога.

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

ОПАСНОСТЬ ВПЕРЕД: (пожалуйста, прочтите комментарии. Выполнение команды, предложенной в моем ответе, может удалить больше, чем вы хотите)

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

git clean -f -d
31 голосов
/ 24 апреля 2015

просто скажи

git stash

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

git stash apply 
26 голосов
/ 28 августа 2013

Я встретил похожую проблему. Решение состоит в том, чтобы использовать git log для поиска, какая версия локального коммита отличается от удаленной. (Например, версия 3c74a11530697214cbcc4b7b98bf7a65952a34ec).

Затем используйте git reset --hard 3c74a11530697214cbcc4b7b98bf7a65952a34ec, чтобы отменить изменение.

11 голосов
/ 25 февраля 2017

Я искал похожую проблему,

Хотел выбросить локальные коммиты:

  1. клонировал хранилище (git clone)
  2. переключен на ветку dev (git checkout dev)
  3. сделал несколько коммитов (git commit -m "commit 1")
  4. но решил выбросить эти локальные коммиты, чтобы вернуться к удаленному (origin / dev)

То же самое сделали и ниже:

git reset --hard origin/dev

Проверка:

git status  

        On branch dev  
        Your branch is up-to-date with 'origin/dev'.  
        nothing to commit, working tree clean  

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

...