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

1914

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

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

git reset --hard HEAD
Жак Рене Месрин
источник

Ответы:

3390

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

git checkout .

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

git reset

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

git revert <commit 1> <commit 2>

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

git clean -f

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

git clean -fd
1800 ИНФОРМАЦИЯ
источник
133
fwiw после такого долгого времени, git checkout path/to/fileбудет только отменить локальные измененияpath/to/file
Matijs
29
+1 в ответах ниже, также упомянув git clean -f (чтобы удалить неотслеживаемые изменения) и -fd (чтобы также удалить неотслеживаемые каталоги)
ptdev
3
и если вы также хотите очистить неотслеживаемые файлы, прочитайте это stackoverflow.com/questions/61212/…
Surasin Tancharoen
9
git checkout .и git reset [--hard HEAD]не работал, я должен был сделать, git clean -fdчтобы отменить мои изменения.
BrainSlugs83
7
git resetне сбрасывает ваши изменения, git reset --hardделает это.
Церин
388

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

git clean -fd

в виде

git reset --hard

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

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

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

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

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

Энтони Стаббс
источник
13
Команда очистки файла - "git clean -f". Неотслеживаемые каталоги удаляются с помощью «git clean -d»
Джонатан Митчелл
35
git clean -fd (для -d требуется сила)
electblake
14
-n или --dry-run - флаги для пробного запуска.
Стивенбез
2
git clean -ffd, если у вас есть другой git-репозиторий в вашем git-репозитории. Без двойного f это не было бы удалено.
Трисмегистос
149

Re-клон

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

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

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

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

чистый

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

Сброс

git reset --hard
  • Local Удаляет локальные не выдвинутые коммиты
  • Changes Отменяет сделанные вами изменения в отслеживаемых файлах
  • Tra восстанавливает отслеженные файлы, которые вы удалили
  • ❌ Удаляет файлы / каталоги, указанные в .gitignore(например, файлы сборки)
  • Files Удаляет файлы / каталоги, которые не отслеживаются и не находятся в .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выше, но вы можете отменить это
Уильям Энтрикен
источник
Извините за кражу сверху ответов. Я использую эту ссылку постоянно, размещая в основном для меня.
Уильям Энтрикен
1
Я почти уверен, что первый вариант ( Re-clone ) на самом деле «удаляет локальные
невыдвинутые
1
@styfle ✅ это то, что он делает, ❌ это то, что он не делает
Уильям Энтрикен
3
@FullDecent Это немного сбивает с толку читать. Msgstr "delete НЕ удаляет локальные невыдвинутые коммиты". Это означает, что он не удаляет. Двойной отрицательный означает, что он удаляет?
Styfle
1
О флаге -x в git clean -f -d -x: если указана опция -x, игнорируемые файлы также удаляются. Это может быть полезно, например, для удаления всех продуктов сборки. - Из документов GIT
Alex
83

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

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.
Майкл Даррант
источник
Кажется важным указать originв git reset --hard origin/master(который работает) - без него (то есть git reset --hard), кажется, ничего не изменилось.
Джейк
У меня были некоторые локальные изменения, и я не смог от них избавиться ни одной командой. Я сделал git reset --hard origin / master, и он также смог получить изменения мастера
abhishek ringsia
50

Посмотри в 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
Уильям Перселл
источник
спасибо огромное Уильям, за мерзавец reflog. Я сбрасываю свое дерево на старую версию и не знаю, как вернуться к последней. ваш мерзавец reflog спас меня. Еще раз спасибо.
Паланираджа
1
спас меня тоже! В моем случае мое приключение с git rebase -iошибкой пошло не так (в итоге я потерял некоторые коммиты из-за ошибки редактирования). Благодаря этому совету я снова в хорошем состоянии!
paneer_tikka
Что вы подразумеваете под 30 дней по умолчанию!?
Мохэ TheDreamy
@ MoheTheDreamy Я имею в виду, что есть ограничение по времени. В конце концов сборщик мусора удалит недоступные ссылки, когда их возраст превысит этот предел. Значение по умолчанию было (и, возможно, все еще) 30 дней. Поэтому старые ссылки могут быть недоступны.
Уильям Перселл
36

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

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

git clean -f -d
Тобиас Гассманн
источник
13
Чтобы спасти кого-либо от боли, которую я только что прошел: это также удалит файлы .gitignore-d!
Landons
извините, если я доставил вам неприятности Тогда я просто пытался восстановить и удалить все в этой папке. Я не помню точных обстоятельств, но «-d» был единственным, что работало на меня. Надеюсь, я не причинил вам слишком много боли :-)
Тобиас Гассманн
1
без вреда. У меня были резервные копии, но это, вероятно, требует отказа от ответственности;)
landons
35

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

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

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

Запустить из рабочей копии корневую директорию.

Скотт Дэйви
источник
10
Последняя команда дает мнеerror: pathspec 'HEAD' did not match any file(s) known to git.
0xC0000022L
1
Это сработало для меня, когда я вынул «-». git checkout HEAD
Шут
4
git reset --hardвозвращает отслеживаемые файлы ( git clean -f -dпомеченные или нет), удаляет неотслеживаемые файлы, git checkout -- HEADзачем нам это тогда?
В.Шашенко
Нам не нужен двойной дефис. Должно быть опечатка.
Фаракс
35

просто выполнить -

git stash

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

git stash apply 
piyushmandovra
источник
3
Использование git stash popавтоматически уберет самое верхнее скрытое для вас изменение
Arrow Cen
8
git stash dropудалить последнее сохраненное состояние без применения к рабочей копии.
Дирчао
git stash apply не будет добавлять вновь созданные файлы
Ravistm
27

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

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

Патрик
источник
16

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

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

  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 выше.

Манохар Редди Поредди
источник
1
спасибо, это единственное, что сработало для меня - "git reset --hard origin"
Nisim Naim
рад, что это помогло.
Манохар Редди Поредди
7

Возможно, вам не обязательно захочется / нужно хранить ваши работы / файлы в рабочем каталоге, а просто избавиться от них полностью. Команда git cleanсделает это за вас.

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

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

git stash --all

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

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

git clean -f -d

Это удалит все файлы, а также любые подкаталоги, в которых нет элементов в результате выполнения команды. Умная вещь, которую нужно сделать перед выполнением git clean -f -dкоманды, это запустить

git clean -f -d -n

который покажет вам предварительный просмотр того, что будет удалено после выполнения git clean -f -d

Итак, вот краткое изложение ваших вариантов от самых агрессивных до наименее агрессивных


Вариант 1 : удалить все файлы локально (наиболее агрессивно)

git clean -f -d

Вариант 2 : Предварительный просмотр вышеупомянутого воздействия (Предварительный просмотр наиболее агрессивный)

git clean -f -d -n

Вариант 3 : спрятать все файлы (наименее агрессивные)

`git stash --all` 
jbooker
источник
6

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

$ git reset --hard HEAD

Но если вы видите такую ​​ошибку:

fatal: Unable to create '/directory/for/your/project/.git/index.lock': File exists.

Вы можете перейти в папку «.git», а затем удалить файл index.lock:

$ cd /directory/for/your/project/.git/
$ rm index.lock

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

$ git reset --hard HEAD
Джандерсон Сильва
источник
0

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

https://stackoverflow.com/a/60890371/2338477

Ответы на вопросы:

  • Как отменить индивидуальные изменения с сохранением или без изменений в истории git

  • Как вернуться к старой версии, чтобы перезапустить из того же состояния

TarmoPikaro
источник