git: отменить все рабочие изменения каталога, включая новые файлы


1152

Как удалить все изменения из рабочего каталога, включая новые неотслеживаемые файлы. Я знаю, что это git checkout -fделает, но он не удаляет новые неотслеживаемые файлы, созданные с момента последнего коммита.

У кого-нибудь есть идеи, как это сделать?


1
@Joel & Wayfarer: почему бы тебе не попробовать git help resetиgit help clean
Шернандес

3
Создание псевдонима для этого в вашем git config - хорошая идея;)
anubina

Ответы:


1700
git reset --hard # removes staged and working directory changes

## !! be very careful with these !!
## you may end up deleting what you don't want to
## read comments and manual.
git clean -f -d # remove untracked
git clean -f -x -d # CAUTION: as above but removes ignored files like config.
git clean -fxd :/ # CAUTION: as above, but cleans untracked and ignored files through the entire repo (without :/, the operation affects only the current directory)

Чтобы увидеть, что будет удалено заранее, без фактического удаления, используйте -nфлаг (это в основном тестовый запуск). Когда вы будете готовы фактически удалить, то удалите -nфлаг:

git clean -nfd


16
Примечание: git reset --hard удаляет поэтапные изменения, а также изменения рабочего каталога. Кроме того, git clean -f -d, вероятно, является лучшей противоположностью добавления нового неотслеживаемого файла. От вопроса, спрашивающий может быть вполне доволен своим текущим набором игнорируемых файлов.
CB Bailey

7
Прочитайте следующий ответ и следите за переключателем -x. (Это может также удалить вашу локальную конфигурацию, такую ​​как файлы пароля / db-settings. Например, database.yml)
Борис

9
Этот ключ -x в этом случае не нужен и несколько опасен.
Тим Готье

66
git clean -fxdна самом деле может быть действительно опасно, если вы не знаете, что делаете. Вы можете окончательно удалить некоторые очень важные неотслеживаемые файлы, такие как база данных и т. Д. Будьте осторожны.
Мейсон Стюарт

10
Обратите внимание, что git clean -f -dфайлы также будут удаляться из игнорируемых папок. Так что все ваши локальные журналы и тому подобное исчезнут. Обычно это не большая проблема, но лучше знать.
Cyriel

299

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

git clean -fd

Синтаксическое объяснение на /docs/git-cleanстранице:

  • -f(псевдоним:) --force. Если для переменной конфигурации Git clean.requireForce не задано значение false, git clean откажется от удаления файлов или каталогов, если не указано -f, -n или -i. Git откажется удалять каталоги с подкаталогом или файлом .git, если не указан второй -f.
  • -d, Удалите неотслеживаемые каталоги в дополнение к неотслеживаемым файлам. Если неотслеживаемый каталог управляется другим Git-репозиторием, по умолчанию он не удаляется. Используйте параметр -f дважды, если вы действительно хотите удалить такой каталог.

Как упомянуто в комментариях, может быть предпочтительнее сделать git clean -ndпробный прогон и сообщить, что будет удалено перед его фактическим удалением.

Ссылка на git cleanстраницу документа: https://git-scm.com/docs/git-clean


124
Я всегда git clean -nd .перед тем, как на самом деле удалять файлы, используюgit clean -fd .
tbear

14
Почему? Можете ли вы объяснить детали, пожалуйста.
Грег Б

31
Параметр per git clean -n на самом деле является пробным прогоном, который ничего не удаляет, он просто показывает, что будет сделано.
RNickMcCandless

2
@tbear, Вы всегда можете сделать пробел add -A+ commit -a+ revert headпервый перед тем git clean. Просмотр каждого удаления просто не подходит для основных сценариев. Кроме того, сухой бег - не серебряная пуля: что если вы что-то упустили или допустили ошибку во время обзора?
Пейсер

1
Это удаляет файлы, но не отменяет изменения.
Donquixote

202

Для всех неподготовленных файлов используйте:

git checkout -- .

В .конце важно.

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


7
@Vincent: - позволяет избежать ошибок при вводе, сообщая команде checkout, что параметры больше не указываются. Без них вы могли бы закончить с новой веткой вместо того, чтобы сбросить текущую!
Игорь Родригес

2
Это самый безопасный маршрут, но он не удалит неотслеживаемые файлы (вновь добавленные файлы).
TinkerTenorSoftwareGuy

5
Это не восстанавливает удаленные, но незафиксированные файлы.
Cerin

Просто к вашему сведению. Я пропустил это. Убедитесь, что вы находитесь в каталоге, в котором хотите удалить неустановленные изменения. Например, у меня были изменения в 2 разных файлах в разных местах ветки, src/app/work/filename.jsа именно : и ../app/working/test/filename.js. Просто используя git checkout -- .ветку только удалил первый файл ( без начального ../ ). Поэтому мне пришлось перейти cd ../во второй каталог, чтобы удалить второй файл с помощью этой команды.
Chris22

57

Посмотрите на git cleanкоманду.

git-clean - удаляет неотслеживаемые файлы из рабочего дерева

Очищает рабочее дерево путем рекурсивного удаления файлов, которые не находятся под контролем версий, начиная с текущего каталога.

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


Я попытался git clean -iи выбрал «чистый» из меню - это, наконец, удалил новые файлы.
Сани

43

Следующие работы:

git add -A .
git stash
git stash drop stash@{0}

Обратите внимание, что при этом будут отменены как локальные, так и промежуточные локальные изменения. Таким образом, вы должны зафиксировать все, что хотите сохранить, прежде чем запускать эти команды.

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

Кредиты: https://stackoverflow.com/a/52719/246724


1
Почему вы ссылаетесь на stash @ {0}, а не просто git stash drop?
Майкл

Честно говоря, я не помню :)
donquixote

Этот работал. Как примечание, убедитесь, что вы находитесь в домашнем каталоге ( git add -A .). Я потерял 30 м, потому что не было совпадения файлов. Спасибо!
user9869932

Я использовал этот подход, и он имеет свои достоинства. Тем не менее, с тех пор я нашел, что решения, предложенные jfountain и Heath Dutton, более соответствуют первоначальной проблеме, ИМХО.
HeyZiko

2
git stash drop stash @ {0} удаляет последний тайник, если бы ты делал git stash, он удалял бы все твои тайники
тайники DonatasD

42

Вы можете сделать это в два этапа:

  1. Восстановить измененные файлы: git checkout -f
  2. Удалить неотслеживаемые файлы: git clean -fd

3
+1 потому что просто. Кроме того, поскольку он работает и выполняет именно то, что хочет OP, не отпугивая их с помощью omg, это удалит все.
geekzster

30

Я думал , что это было ( предупреждение: следующий будет уничтожить все )

$ git reset --hard HEAD
$ git clean -fd

resetДля отмены изменений. clean, Чтобы удалить любой неотслеживаемых F Ильз и г irectories.


Это не работает, я все еще получаю предупреждение о конфликте, когда делаю git pullпотом: CONFLICT (content): Merge conflict in...я только решил это с помощьюgit pull --strategy=ours
rubo77


4

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

Смотрите git help cleanдля получения дополнительной информации, включая некоторые другие полезные опции.


4

Если вы хотите отменить все изменения, вы можете использовать любой из допустимых параметров в псевдониме в .gitconfig. Например:

[alias]
    discard = "!f() { git add . && git stash && git stash drop stash@{0}; }; f"

Применение: git discard


1
Этот псевдоним мне очень нравится
флаги

3

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

Вы можете сделать это в текущей ветке, например так:

git add (-A) .
git commit -m"DISCARD: Temporary local changes"
git tag archive/local-changes-2015-08-01  # optional
git revert HEAD
git reset HEAD^^

Или вы можете сделать это на отдельной голове. (при условии, что вы начинаете с ветки BRANCHNAME):

git checkout --detach HEAD
git add (-A) .
git commit -m"DISCARD: Temporary local changes"
git tag archive/local-changes-2015-08-01  # optional
git checkout BRANCHNAME

Однако обычно я делаю коммиты, а затем называю некоторые или все коммиты как «DISCARD: ...». Затем используйте интерактивную перебазировку, чтобы удалить плохие коммиты и сохранить хорошие.

git add -p  # Add changes in chunks.
git commit -m"DISCARD: Some temporary changes for debugging"
git add -p  # Add more stuff.
git commit -m"Docblock improvements"
git tag archive/local-changes-2015-08-01
git rebase -i (commit id)  # rebase on the commit id before the changes.
  # Remove the commits that say "DISCARD".

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

git lolиgit lola ярлыки были очень полезны с этим рабочим процессом.


3

Для конкретной папки я использовал:

git checkout -- FolderToClean/*

3
Это не удаляет неотслеживаемые файлы, как утверждает OP.
vonbrand

0

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

  1. Вызовите контекстное меню для нужной папки и выберите «Восстановить», оно отображает всплывающее окно возврата, в котором вы можете выбрать измененные файлы для восстановления / восстановления.
  2. Если вы также хотите удалить добавленные файлы (которые еще не включены в git), нажмите «Подтвердить» (из того же контекстного меню), откроется всплывающее окно «Подтвердить» и отобразятся добавленные файлы, затем щелкните правой кнопкой мыши каждый из них и выберите «Удалить». Но не нажимайте Commit btn в этом всплывающем окне, так как вы не хотите подтверждать, а видите только добавленные файлы и удаляете их отсюда.
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.