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

1374

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

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

git reset --hard HEAD
Теги:
revert
git-checkout

12 ответов

2482
Лучший ответ

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

git checkout .

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

git reset

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

git revert <commit 1> <commit 2>

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

git clean -f

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

git clean -fd
  • 118
    после такого долгого времени, git checkout path/to/file вернет только локальные изменения к path/to/file
  • 26
    +1 в ответах ниже и упоминание git clean -f (для удаления неотслеживаемых изменений) и -fd (для удаления неотслеживаемых каталогов)
Показать ещё 18 комментариев
309

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

git clean -fd

а

git reset --hard

не удалит ненужные файлы, где git -clean удалит любые файлы из отслеживаемого корневого каталога, которые не находятся под git отслеживанием. ПРЕДУПРЕЖДЕНИЕ - ОСТОРОЖНО! Полезно запускать сухой пробег с помощью git -clean сначала, чтобы увидеть, что он будет удалять.

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

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

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

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

  • 12
    Команда очистки файла - "git clean -f". Неотслеживаемые каталоги удаляются с помощью "git clean -d"
  • 35
    git clean -fd (для -d требуется сила)
Показать ещё 2 комментария
44

Посмотрите на 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
  • 0
    спасибо огромное Уильям, за мерзавец рефлог. Я сбрасываю свое дерево на старую версию и не знаю, как вернуться к последней. ваш мерзавец reflog спас меня. Еще раз спасибо.
  • 1
    спас меня тоже! В моем случае мое приключение с git rebase -i пошло не так (в итоге я потерял некоторые коммиты из-за ошибки редактирования). Благодаря этому совету я снова в хорошем состоянии!
Показать ещё 2 комментария
39

Если вы хотите вернуть все изменения и обновиться с текущим удаленным мастером (например, вы обнаружите, что ведущий 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.
31

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

Здесь мой текущий bash script для этого, который работает все время.

#!/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.
  • 1
    Это сработало для меня, когда я вынул «-». git checkout HEAD
Показать ещё 2 комментария
30

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

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

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

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

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

21

просто скажите

git stash

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

git stash apply 
  • 2
    использование git stash pop автоматически удалит самое верхнее скрытое изменение для вас
  • 5
    git stash drop для удаления последнего сохраненного состояния без применения к рабочей копии.
12

Re-клон

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

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

Очистить и reset

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

Clean

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

Reset

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 выше, но вы можете отменить его
  • 0
    Извините за кражу сверху ответов. Я использую эту ссылку постоянно, размещая в основном для меня.
  • 0
    Я почти уверен, что первый вариант ( Re-clone ) действительно «удаляет локальные, не выдвинутые коммиты» :)
Показать ещё 5 комментариев
3

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

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

Имейте в виду, что вам будет очень осторожно относиться к этой команде, поскольку она предназначена для удаления файлов из вашего локального рабочего каталога, которые НЕ ОТПУСКАЮТСЯ. если вы с ума сошли с ума после выполнения этой команды, нет возврата к просмотру содержимого удаленных файлов. Альтернативой, которая является более безопасной, является выполнение

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` 
2

Я искал аналогичную проблему,

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

  • клонировал репозиторий (git clone)
  • переключается на ветвь dev (git checkout dev)
  • сделал несколько коммитов (git commit -m "commit 1" )
  • но решил выбросить эти локальные коммиты, чтобы вернуться к удаленному (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
    спасибо приятель, это исправило мою проблему
2

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

$ 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

Ещё вопросы

Сообщество Overcoder
Наверх
Меню