Я случайно добавил много временных файлов, используя git add -A
Мне удалось разархивировать файлы с помощью следующих команд и удалить грязный индекс.
git ls-files -z | xargs -0 rm -f
git diff --name-only --diff-filter=D -z | xargs -0 git rm --cached
Вышеуказанные команды перечислены в git help rm
. Но, к сожалению, мои файлы также были удалены при исполнении, хотя я и выбрал опцию кэширования. Как я могу очистить индекс без потери контента?
Также было бы полезно, если бы кто-то мог объяснить, как работает эта конвейерная операция.
git
version-control
Сарат
источник
источник
rm -f
не является командой git и не имеет--cached
опции. Ваши локальные файлы были удалены до того, как вы их выполнили,git rm
поэтому я не думаю, что вы можете на законных основаниях обвинятьgit rm
что-либо.git reset --hard
он не является правильным и фактически удалит содержимое. Это запутает пользователей - как и меня.Ответы:
git reset
Если все, что вам нужно, это отменить слишком усердный «git add»:
Ваши изменения будут без изменений и готовы для повторного добавления по вашему усмотрению.
НЕ ПРОПУСТИТЕ
git reset --hard
.Он не только удалит добавленные вами файлы, но и отменит все изменения, внесенные в ваш рабочий каталог. Если вы создали какие-либо новые файлы в рабочем каталоге, они не будут удалены.
источник
git checkout -- *
, аЕсли у вас нетронутый репо (или HEAD не установлен) [1], вы можете просто
Конечно, это потребует от вас повторно добавить файлы , которые вы же хотите добавить.
[1] Обратите внимание (как поясняется в комментариях), это обычно происходит только в том случае, если репо является новым («нетронутым») или если не было совершено никаких коммитов. С технической точки зрения, когда нет проверки или рабочего дерева.
Просто делая это более понятным :)
источник
Используйте
git reset HEAD
для сброса индекса без удаления файлов. (Если вы хотите сбросить только определенный файл в индексе, вы можете использоватьgit reset HEAD -- /path/to/file
для этого.)Трубный оператор в оболочке принимает
stdout
процесс слева и передает егоstdin
процессу справа. По сути это эквивалент:но вместо этого
$ proc1 | proc2
второй процесс может начать получать данные до того, как первый завершит их вывод, и в действительности не будет задействовано никакого файла.источник
git reset HEAD
без указания чего-либо еще, и он сбросит весь индекс. Затем вы можете просто повторно добавить только те файлы, которые вы хотите.$ git reset HEAD fatal: ambiguous argument 'HEAD': unknown revision or path not in the working tree. Use '--' to separate paths from revisions
git reset
тогда, безHEAD
.$ git reset fatal: Failed to resolve 'HEAD' as a valid ref.
источник
Если HEAD не установлен (т.е. у вас еще нет коммитов, но вы не хотите просто сдуть,
.git
потому что вы уже настроили другую конфигурацию репо, которую хотите сохранить), вы также можете сделатьрасстегнуть все По сути, это то же самое, что и решение Sehe, но позволяет избежать взлома внутренних компонентов Git.
источник
.git
потому что вы настроили другую конфигурацию репо, которую вы хочу сохранить. Я редактировал, чтобы уточнить это.Предупреждение: не используйте следующую команду, если вы не хотите потерять незафиксированную работу!
Использование
git reset
было объяснено, но вы также запросили объяснение переданных команд, так что вот так:Команда
git ls-files
выводит список всех файлов, о которых знает git. Опция-z
накладывает на них определенный формат, ожидаемый форматxargs -0
, который затем вызываетrm -f
их, что означает удаление их без проверки вашего одобрения.Другими словами, «перечислите все файлы, которые знает git и удалите вашу локальную копию».
Затем мы
git diff
переходим к тому , что показывает изменения между различными версиями элементов, о которых знает git. Это могут быть изменения между разными деревьями, различия между локальными и удаленными копиями и т. Д.Как здесь используется, он показывает неустановленные изменения; файлы, которые вы изменили, но еще не зафиксировали. Опция
--name-only
означает, что вам нужны только (полные) имена файлов, и--diff-filter=D
означает, что вы заинтересованы только в удаленных файлах. (Эй, разве мы не просто удалили кучу вещей?) Затем они попадают в каналxargs -0
, который мы видели ранее, что вызываетgit rm --cached
их, то есть они удаляются из кэша, в то время как рабочее дерево должно быть оставлено в покое - за исключением того, что Вы только что удалили все файлы из вашего рабочего дерева. Теперь они также удалены из вашего индекса.Другими словами, все изменения, поэтапные или неустановленные, пропали, и ваше рабочее дерево пусто. Плачите, проверяйте свои файлы, свежие из источника или удаленного, и переделайте свою работу. Прокляни садиста, который написал эти адские строки; Я понятия не имею, почему кто-то хотел бы сделать это.
TL; DR: вы только что все надули; начать заново и использовать
git reset
с этого момента.источник
Боюсь, что первая из этих командных строк безоговорочно удалила из рабочей копии все файлы, находящиеся в промежуточной области git. Второй unstaged все файлы, которые были отслежены, но теперь были удалены. К сожалению, это означает, что вы потеряете все незафиксированные изменения этих файлов.
Если вы хотите получить свою рабочую копию и вернуться к индексу, как было при последнем коммите , вы можете ( осторожно ) использовать следующую команду:
Я говорю «осторожно», так
git reset --hard
как уничтожит незафиксированные изменения в вашей рабочей копии и индексе. Однако в этой ситуации это звучит так, как будто вы просто хотите вернуться к состоянию при последнем коммите, и незафиксированные изменения все равно будут потеряны.Обновление: из ваших комментариев к ответу Амбер звучит, что вы еще не создали никаких коммитов (поскольку HEAD не может быть решена), так что, боюсь, это не поможет.
Что касается того, как работают эти каналы:
git ls-files -z
иgit diff --name-only --diff-filter=D -z
оба выводят список имен файлов, разделенных байтом0
. (Это полезно, поскольку, в отличие от новых строк,0
байты гарантированно не встречаются в именах файлов в Unix-подобных системах.) Программа поxargs
существу строит командные строки из своего стандартного ввода, по умолчанию беря строки из стандартного ввода и добавляя их в конец командной строки.-0
Вариант говорит ожидать стандартный ввод пути разделенных0
байт.xargs
может вызвать команду несколько раз, чтобы использовать все параметры из стандартного ввода, убедившись, что командная строка никогда не становится слишком длинной.В качестве простого примера, если у вас есть файл с именем
test.txt
, со следующим содержанием:... тогда команда
xargs echo whatever < test.txt
вызовет команду:источник
Если вы хотите отменить все изменения, используйте команду ниже,
В случае, если вы хотите отменить изменения и вернуть их из рабочего каталога,
источник