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

Есть ли способ сбросить все файлы из рабочего каталога, но не из области подготовки?

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

git checkout thefiletoreset.txt

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

git reset --hard

Но есть ли какая-нибудь команда, которая может сбросить весь рабочий каталог, оставляя область подготовки нетронутой?

1 ответ

Решение

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

Как скопировать файлы из рабочей области обратно в рабочее дерево?

за что ответ действительно git checkout, Вы можете дать git checkout различные варианты, но по умолчанию читается текущий индекс / область размещения:

git checkout -- file

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

Как вы видели:

git checkout -- directory

извлекает все файлы, чей путь начинается с directory/, поскольку . называет текущий каталог:

git checkout -- .

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

(The -- здесь необходимо, если имя файла, которое вы хотите, напоминает git checkout вариант или название филиала. Например, если вы хотите файл с именем master или же -b, git checkout master или же git checkout -b будет путать git checkout, но git checkout -- -b master скажет git checkout тот -b а также master имена двух файлов, а не -b master вариант. Хорошо привыкнуть просто использовать -- автоматически здесь.)

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

В Git 2.23 (Q3 2019) да, есть: git restore.

См совершают 97ed685, совершает d16dc42, совершает bcba406 (20 июн 2019), совершает 4e43b7f, совершает 1235875, совершают 80f537f, совершает fc991b4, совершает 75f4c7c, совершают 4df3ec6, совершает 2f0896e, совершает a5e5f39, совершает 3a733ce, совершает e3ddd3b, совершает 183fb44, совершает 4058199, зафиксировать a6cfb9b, зафиксировать be8ed50, зафиксировать c9c935f, зафиксировать 46e91b6 (25 апреля 2019 г.) и commit 328c6cb (29 марта 2019 г.), автор: Nguyễn Thái Ngọc Duy (pclouds).
(Слияние Junio ​​C Hamano -gitster- в коммите f496b06, 09 июл 2019)

checkout: разделить часть на новую команду 'restore'

Ранее переключение филиала бизнеса 'git checkout'становится новой командой'switch'. Это добавляетrestore команда для проверки пути путей.

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

Пара основных отличий от 'git checkout <paths>':

  • 'restore'по умолчанию будет обновлять только рабочее дерево.
    Это имеет большее значение, когда--source указано ('checkout <tree> <paths>'обновляет и рабочее дерево, и индекс).

  • 'restore--staged'можно использовать для восстановления индекса.
    Эта команда перекрывается с 'git reset <paths>'.

  • и рабочее дерево, и индекс могут быть восстановлены одновременно (из дерева), когда оба --staged а также --worktreeуказаны. Это перекрывается с 'git checkout <tree> <paths>'

  • Источником по умолчанию для восстановления рабочего дерева и индекса является индекс и HEAD соответственно. Другой (древовидный) источник может быть указан как с--source (*).

  • когда восстанавливаются и индекс, и рабочее дерево, --source необходимо указать, поскольку источники по умолчанию для этих двух отдельных целей различны (**)

  • --no-overlay по умолчанию включен, если запись отсутствует в источнике, восстановление означает удаление записи

(*) Изначально я использовал --from вместо того --source.
я еще думаю--fromэто лучшее имя. Короткий вариант-f однако уже занято force. И я считаю, что неплохо иметь короткий вариант, например, написать-s@ или -s@^ вместо того --source=HEAD.

(**) Если вы сядете и подумаете об этом, перемещение источника рабочего дерева из индекса в HEAD имеет смысл, но на самом деле никто не думает об этом, когда набирает команды.


До Git 2.24 (третий квартал 2019 г.) "git checkout" а также "git restore"может повторно заполнить индекс из дерева (обычно HEAD), но не работал правильно для пути, который был удален, а затем добавлен снова с намерением добавить (ita или i-t-a) бит, когда соответствующий файл рабочего дерева был пуст.
Это было исправлено.

См. Commit 620c09e (1 августа 2019 г.) и commit ecd7204 (2 августа 2019 г.) Варун Наик (varunnaik).
Помощник: Джефф Кинг (peff).
(Слияние Junio ​​C Hamano -gitster- в коммите 072735e, 22 августа 2019 г.)

checkout.c: unstage пустые удаленные файлы ita

Можно удалить зафиксированный файл из индекса, а затем добавить его в качестве намеренного добавления.
Послеgit checkout HEAD <pathspec>, файл должен быть идентичен по индексу и HEAD. Команда уже работает правильно, если файл имеет содержимое в HEAD. Этот патч обеспечивает желаемое поведение, даже если файл в HEAD пуст.

git checkout HEAD <pathspec> звонки tree.c:read_tree_1(), где fn указывает на checkout.c:update_some().
update_some()создает новую запись кэша, но отбрасывает ее, когда ее режим и oid совпадают с таковыми из старой записи. Запись кэша для файла ita и запись кэша для пустого файла имеют одинаковый идентификатор. Следовательно, пустой удаленный файл ita ранее прошел обе эти проверки, а новая запись была отброшена, поэтому файл остался в индексе без изменений.
После этого исправления, если файл помечен как ita в кеше, мы избегаем отбрасывания новой записи и вместо этого добавляем новую запись в кеш.


С Git 2.25 (первый квартал 2020 г.), git restore более надежный анализ его параметров.

См. Commit 169bed7 (12 ноября 2019 г.) Рене Шарфе (``).
(Слияние Junio ​​C Hamano -gitster- в коммите 406ca29, 01 декабря 2019 г.)

parse-options: избегать арифметических действий с указателем, который потенциально равен NULL

Подписано: Рене Шарфе

parse_options_dup() подсчитывает количество элементов в данном массиве без маркера конца, выделяет достаточно памяти для хранения всех из них плюс маркер конца, затем копирует их и завершает новый массив.

Счетная часть выполняется путем продвижения указателя по массиву, и исходный указатель восстанавливается с использованием вычитания указателя перед операцией копирования.

Функция также подготовлена ​​для обработки NULLк нему передан указатель. В настоящее время ни один из вызывающих абонентов этого не делает, но эта функция использовалась 46e91b663b ("checkout: разделить часть на новую команду 'restore'", 2019-04-25, Git v2.23.0-rc0 - слияние указано в пакете №4); кажется, стоит сохранить.

В конце концов, он выполняет арифметические операции над этим NULL однако указатель, который не определен в стандарте C, когда он пытается вычислить "NULL - 0".

Лучше этого не делать, запоминая изначально заданное значение указателя.

Но есть еще одна проблема.

memcpy(3) не поддерживается NULL указатели даже для пустых массивов.

Использовать COPY_ARRAY вместо этого, который поддерживает такие пустые массивы.

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

Кокчинель и contrib/coccinelle/array.cocci не предлагал использовать COPY_ARRAYиз-за вычитания указателя и из-за того, что источник является константным, семантический патч осторожно учитывает только указатели и ссылки на массивы одного и того же типа..


С Git 2.25.1 (февраль 2020 г.) "git restore--staged"некорректно обновлял структуру дерева кэша, что приводило к последующему написанию ложных деревьев, что было исправлено.

См. Обсуждение

См. Commit e701bab (8 января 2020 г.) Джефф Кинг (peff).
(Слияние Junio ​​C Hamano -gitster- в коммите 09e393d, 22 января 2020 г.)

restore: сделать недействительным дерево кэша при удалении записей с --staged

Автор отчета: Торстен Кра.
Подпись: Джефф Кинг.

Когда " git restore--staged "удаляет путь из индекса, он отмечает запись CE_REMOVE,но мы не делаем ничего, чтобы сделать дерево кэша недействительным.
В неэтапном случае мы попадаем вcheckout_worktree(), который вызывает remove_marked_cache_entries(). Это фактически удаляет записи из индекса, а также делает недействительным дерево кэша и неотслеживаемый кеш.

Но с --stagedмы никогда не звоним checkout_worktree(), а CE_REMOVEзаписи остаются. Интересно, что они отбрасываются, когда мы записываем индекс, но это означает, что результирующий индекс несовместим: его дерево кэша не будет соответствовать фактическим записям и выполняется "git commit"сразу после этого создаст неправильное дерево.

Мы можем решить эту проблему, позвонив remove_marked_cache_entries()перед тем, как написать индекс. Обратите внимание, что мы не можем просто поднять его изcheckout_worktree(); эта функция должна перебиратьCE_REMOVE записей (чтобы удалить соответствующие файлы рабочего дерева) перед их удалением.

Одно любопытство по поводу теста: без этого патча он фактически запускает BUG() при запуске git-restore:

BUG: cache-tree.c:810: new1 with flags 0x4420000 should not be in cache-tree

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


С Git 2.26 (первый квартал 2020 г.), parse_option_dup (использован git restore) убирается.

См. Commit 7a9f8ca, commit c840785, commit f904f90, commit a277d0a (09 февраля 2020 г.) Рене Шарфе (rscharfe).
(Слияние Junio ​​C Hamano -gitster- в коммите cbecc16, 17 февраля 2020 г.)

parse-options: упрощать parse_options_dup()

Подписано: Рене Шарфе

Упрощать parse_options_dup() превратив его в банальную обертку parse_options_concat() за счет использования того факта, что последний также дублирует свой ввод и что добавление пустого набора не является операцией.

Другие вопросы по тегам