Відповіді:
Тому що немає сенсу (інші команди вже надають цю функціональність), і це зменшує потенціал зробити випадкові випадки.
Щойно робиться "жорстке скидання" шляху git checkout HEAD -- <path>
(перевірка наявної версії файлу).
Помірне скидання шляху не має сенсу.
Змішане скидання шляху - це те, що git reset -- <path>
робить.
git checkout -- <path>
не робить жорсткого скидання; він замінює вміст робочого дерева поетапним вмістом. git checkout HEAD -- <path>
робить жорстке скидання для шляху, замінюючи і індекс, і робоче дерево версією з комісії HEAD.
reset --hard
з доріжкою забезпечив би цей недолік. Git вже настільки потужний, що виправдання "Ми не даємо вам зробити це задля власного захисту" не має жодної води: Є безліч способів зробити неправильну справу "випадково". Нічого з цього не має значення, коли у вас є git reflog
.
git reset --hard -- <path>
. Для цього є законні випадки використання.
Ви можете виконати те, що намагаєтесь робити, використовуючи git checkout HEAD <path>
.
Однак, надане повідомлення про помилку для мене не має сенсу (так як git reset
це добре працює в підкаталогах), і я не бачу причини, чому git reset --hard
б не робити саме те, про що ви просите.
На питання, як уже відповіли , я поясню, чому частина.
Отже, що робить скидання git ? Залежно від вказаних параметрів, він може робити дві різні речі:
Якщо вказати шлях, він замінить відповідні файли в індексі файлами з комітки (HEAD за замовчуванням). Ця дія взагалі не впливає на робоче дерево і зазвичай використовується як протилежне git add.
Якщо не вказати шлях, він переміщує поточну голову гілки до визначеної комірки та разом із цим необов'язково скидає індекс та робоче дерево у стан цього коміту. Ця додаткова поведінка контролюється параметром режиму:
--soft : не торкайтеся індексу та робочого дерева.
--mixed (за замовчуванням): скидання індексу, але не робоче дерево.
--hard : скидання індексу та робочого дерева.
Є й інші варіанти, див. Документацію для повного списку та деякі випадки використання.
Якщо ви не вкажете git reset --soft
команду , вона за замовчуванням відповідає HEAD, тому нічого не зробить, оскільки це команда перемістити голову до HEAD (до її поточного стану). git reset --hard
З іншого боку, це має сенс через його побічних ефектів , він говорить про переміщення голови до HEAD та скидання індексу та робочого дерева на HEAD.
Я думаю, вже зараз повинно бути зрозуміло, чому ця операція за своєю природою не призначена для конкретних файлів - вона призначена в першу чергу для переміщення головки гілки, скидання робочого дерева, а індекс - це вторинна функціональність.
git checkout
команда? І якщо зробити скидання таким же чином, це ще більше бентежить користувачів. Моя відповідь полягала в тому, що --hard
варіант не застосовується до певних файлів, оскільки це режим для скидання гілки, а не скидання індексу. І скидання робочого дерева називається замовленням, як ви можете прочитати в інших відповідях. Все це лише погана конструкція користувальницького інтерфейсу Git, IMHO.
git checkout
: git reset --
встановлює лише індекс, а git checkout --
встановлює лише робоче дерево?
Переконайтеся, що ви поставили косу рису між початковим або вихідним (джерелом) та фактичним гіллям:
git reset --hard origin/branch
або
git reset --hard upstream/branch`
За цим є дуже важлива причина: принципи checkout
таreset
.
У термінах Git замовлення означає "внести в поточне робоче дерево". І git checkout
ми можемо заповнити робоче дерево даними з будь-якої області, будь то з фіксації у сховищі або окремих файлів з комітету чи області постановки (що є рівним за замовчуванням).
У свою чергу, скидання git не має цієї ролі. Як випливає з назви, воно буде скинути поточний ref, але завжди матиме сховище як джерело, незалежно від "досяжності" (--soft, --mixed або --hard).
Резюме:
Тому, що може бути трохи заплутаним, це існування, git reset COMMIT -- files
оскільки "перезапис HEAD" лише з деякими файлами не має сенсу!
За відсутності офіційного пояснення я можу лише припускати, що розробники git виявили, що reset
все ще є найкращим ім'ям команди, щоб відкинути зміни, внесені в область постановки, і, враховуючи, що єдиним джерелом даних було сховище, тоді " давайте продовжимо функціональність "замість створення нової команди.
Тож якимось чином git reset -- <files>
вже є винятковим: воно не перезаписує ГОЛОВУ. IMHO всі такі варіанти були винятками. Навіть якщо ми можемо запустити --hard
версію, інші (наприклад --soft
) не мали б сенсу.
git reset -- <files>
впало так, як його додали, тому що це корисна функція, але ніхто не був впевнений, в яку команду її слід поставити. На щастя, зараз у нас набагато більше розумних git restore
функціональних можливостей git checkout -- <path>
git checkout <commit> -- <path>
і git reset [<commit>] -- <path>
з значно безпечнішими налаштуваннями та ще більше функцій, яких ви раніше не могли зробити (всупереч тому, що прийнято відповідати. Тепер, нарешті, ви можете легко відновити лише робоче дерево, не торкаючись покажчика).
В 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 \"$@\" && git checkout \"$@\" && 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
set && c
heck o
ut)
git checkout -- <path>
повинен бути замінений зgit reset --hard <path>
. Це має набагато більше сенсу ...