Відповіді:
Тому що немає сенсу (інші команди вже надають цю функціональність), і це зменшує потенціал зробити випадкові випадки.
Щойно робиться "жорстке скидання" шляху 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: reset && check out)
git checkout -- <path>повинен бути замінений зgit reset --hard <path>. Це має набагато більше сенсу ...