$ git reset -- <file_path>
может reset по пути.
Однако $ git reset (--hard|--soft) <file_path>
сообщит об ошибке, как показано ниже:
Cannot do hard|soft reset with paths.
$ git reset -- <file_path>
может reset по пути.
Однако $ git reset (--hard|--soft) <file_path>
сообщит об ошибке, как показано ниже:
Cannot do hard|soft reset with paths.
Потому что нет смысла (другие команды уже предоставляют эту функциональность), и это снижает вероятность ошибочных действий.
A "hard reset" для пути выполняется только с помощью git checkout HEAD -- <path>
(проверка существующей версии файла).
Мягкий reset для пути не имеет смысла.
Смешанный reset для пути - это то, что делает git reset -- <path>
.
Вы можете выполнить то, что вы пытаетесь сделать, используя git checkout HEAD <path>
.
Тем не менее, предоставленное сообщение об ошибке не имеет для меня никакого смысла (поскольку git reset
отлично работает в подкаталогах), и я не вижу причин, почему git reset --hard
не должен делать именно то, что вы просите об этом.
На вопрос, как уже ответили, я объясню почему.
Итак, что делает git reset? В зависимости от указанных параметров он может выполнять две разные функции:
Если вы укажете путь, он заменит соответствующие файлы в индексе на файлы из фиксации (по умолчанию HEAD). Это действие никак не влияет на рабочее дерево и обычно используется как противоположность git add.
Если вы не укажете путь, он перемещает текущий заголовок ветки в указанный коммит и, вместе с этим, дополнительно сбрасывает индекс и рабочее дерево в состояние этого коммита. Это дополнительное поведение контролируется параметром mode:
--soft: не трогайте указатель и рабочее дерево.
--mixed (по умолчанию): сбросить индекс, но не рабочее дерево.
--hard: сбросить индекс и рабочее дерево.
Есть и другие варианты, полный список и некоторые варианты использования см. в документации.
Когда вы не указываете коммит, по умолчанию используется HEAD, поэтому git reset --soft
ничего не будет делать, так как это команда для перевода головы в HEAD (в ее текущее состояние). git reset --hard
, с другой стороны, имеет смысл из-за его побочных эффектов, он говорит, что переместите голову в HEAD и сбросьте индекс и рабочее дерево в HEAD.
Я думаю, к настоящему времени должно быть ясно, почему эта операция не предназначена для определенных файлов по своей природе - она предназначена для перемещения головки ветки в первую очередь, сброса рабочего дерева, а индекс является вторичной функциональностью.
Убедитесь, что вы поставили косую черту между origin или upstream (source) и фактической веткой:
git reset --hard origin/branch
или
git reset --hard upstream/branch'
В руководстве по git reset
перечислены 3 способа вызова:
2 относятся к файлам: они не влияют на рабочее дерево, а работают только с файлами в индексе, указанном в <paths>
:
git reset [-q] [<tree-ish>] [--] <paths>..
git reset (--patch | -p) [<tree-ish>] [--] [<paths>...]
1 является обязательным: работает со всеми файлами в указанном <commit>
и может влиять на рабочее дерево:
git reset [<mode>] [<commit>]
Не существует режима вызова, который работает только с указанными файлами и влияет на рабочее дерево.
Если вы хотите оба:
Вы можете использовать этот псевдоним в своем файле конфигурации git:
[alias]
reco = !"cd \"${GIT_PREFIX:-.}\" && git reset \"[email protected]\" && git checkout \"[email protected]\" && git status --short #" # Avoid: "fatal: Cannot do hard reset with paths."
Затем вы можете сделать одно из:
$ git reco <paths>
$ git reco <branch/commit> <paths>
$ git reco -- <paths>
(Mnenonic для reco
: re
&& c
heck o
ut)
За этим стоит очень важная причина: принципы checkout
и reset
.
В терминах Git оформление заказа означает "внести в текущее рабочее дерево". А с помощью git checkout
мы можем заполнить рабочее дерево данными из любой области, будь то из фиксации в репозитории или отдельных файлов из фиксации или из промежуточной области (которая является даже по умолчанию).
В свою очередь, git reset не имеет этой роли. Как следует из названия, он сбросит текущую ссылку, но всегда будет иметь хранилище в качестве источника, независимо от "досягаемости" (--soft, --mixed или --hard).
Резюме:
Поэтому то, что может немного сбивать с толку, это существование git reset COMMIT -- files
, так как "перезаписывать HEAD" только некоторыми файлами не имеет смысла!
В отсутствие официального объяснения я могу только предположить, что разработчики git обнаружили, что reset
по-прежнему было лучшим названием команды для отмены изменений, внесенных в промежуточную область, и, учитывая, что единственным источником данных был репозиторий, " давайте расширять функциональность "вместо создания новой команды.
Так что как-то git reset -- <files>
уже немного исключительный: он не перезаписывает ГОЛОВУ. ИМХО все такие вариации были бы исключениями. Даже если мы сможем придумать версию --hard
, другие (например, --soft
) не будут иметь смысла.
git reset --soft HEAD ~ 1 имя_файла отменить фиксацию, но изменения остаются в локальном. имя файла может быть - для всех зарегистрированных файлов