Як видалити лише певні файли?


385

Я приховав свої зміни. Тепер я хочу видалити лише копію файлів із сховища. Як я можу це зробити?


4
Я думаю, що ви повинні застосувати всю скриньку, але тоді ви можете вибірково повторно зберігати.
Річард

4
@AbdouTahiri Що не так зі сховищем?
alex

32
@AbdouTahiri Uhhhh .. git stash - це легітимна функція і надзвичайно корисна. Я використовую його щодня. Скажімо, співробітник потребує того, щоб я щось переглянув, але я перебуваю посеред складного набору змін. Я не збираюся робити купу зламаного коду просто для того, щоб переключити гілки. Я збираюся приховати, переключити гілки, переглянути, переключити назад, видалити. Чи хочете Ви детальніше розібратися, хто або чому приховування гетів нібито "не рекомендується"? Тільки тому, що ваша історія приховування git затуплена і важко читається, не означає, що всі інші. Брудний набір скриньки для git - це лише поганий робочий процес, а не недолік Git.
dudewad

6
@alex Нічого. Нічого поганого з приховуванням git. Продовжуйте використовувати його.
dudewad

Відповіді:


460

Як було зазначено нижче , і детально в розділі " Як я витягнути один файл (або зміни до файлу) з сховища git? ", Ви можете застосувати використання git checkoutабо git showвідновити певний файл.

git checkout stash@{0} -- <filename>

Це перезаписує filename : переконайтеся, що у вас не було місцевих модифікацій, або ви можете замість цього злити збережений файл .

(Як зауважив по Jaime М. , для певної оболонки , як Tcsh , де вам потрібно , щоб уникнути спеціальних символів, синтаксис буде: git checkout 'stash@{0}' -- <filename>)

або зберегти його під іншим іменем файлу:

git show stash@{0}:<full filename>  >  <newfile>

(зауважте, що тут <full filename>повне ім'я файлу щодо верхнього каталогу проекту (думаю: відносно stash@{0})).

Юсер пропонує в коментарях :

Якщо ви хочете вибрати вручну, які зміни потрібно застосувати з цього файлу:

git difftool stash@{0}..HEAD -- <filename>

Vivek додає в коментарях :

Схоже, " git checkout stash@{0} -- <filename>" відновлює версію файлу станом на час виконання скрипту - він НЕ застосовує (лише) сховані зміни для цього файлу.
Щоб зробити останнє:

git diff stash@{0}^1 stash@{0} -- <filename> | git apply

(Як зауважив по peterflynn , що вам може знадобитися | git apply -p1в деяких випадках, видалення одного ( p1) , провідний слеш від традиційних шляхів дифф)


Як коментується: "зніміть" ( git stash pop), тоді:

  • додайте в індекс те, що ви хочете зберегти ( git add)
  • приховайте решту: git stash --keep-index

Останній пункт - це те, що дозволяє зберігати одні файли, зберігаючи інші.
Це проілюстровано у розділі " Як зберігати лише один файл із кількох файлів, що змінилися ".


5
Це не працює, якщо ви не можете git stash popчерез конфлікти файлів. У цьому випадку відповідь Баламуругана А зробила для мене хитрість.
Андрій

1
Якщо ви хочете вибрати вручну, які зміни потрібно застосувати з цього файлу, ви можете використовувати git difftool stash @ {0} .. HEAD - <ім'я файла>
1616

5
Схоже, "git checkout stash @ {0} - <filename>" відновлює версію файлу станом на час виконання скрипту - він НЕ застосовує (просто) сховані зміни для цього файлу. Щоб зробити останнє: "git diff stash @ {0} ^ 1 stash @ {0} - <ім'я файлу> | застосувати git"
Vivek

1
@JaimeM. Дякую. Я включив ваш коментар у відповідь для більшої наочності.
VonC

1
Якщо припустити, що це unstashозначає pop, як мені здається, що це, мабуть, у більшості випадків, це лише частково відповідає на питання. Як потім вийняти вибірково нанесені фрагменти зі сховища, щоб уникнути пізніших конфліктів та / або плутанини під час появи інших змін?
DylanYoung

115
git checkout stash@{N} <File(s)/Folder(s) path> 

Напр. Щоб відновити лише файл ./test.c та папку ./include з останньої скриньки,

git checkout stash@{0} ./test.c ./include

12
Це правильна відповідь! Однорядкова команда застосовувати лише сховані зміни певних файлів, працює як шарм!
4рівні

1
Щоб застосувати (просто) сховані зміни до файлу: "git diff stash @ {N} ^ 1 stash @ {N} - <ім'я файлу> | застосувати git"
Vivek

Це працює і для мене. Просто вибірково перегляньте файли, необхідні для використання із сховища, і ви закінчили. Я застряг в цьому, я використовував -aпрапор під час створення скриньки.
Радєєв Ранджан

1
@ 4levels Я думаю, що "застосувати приховані зміни" - це не те, що відбувається, правда? Я думаю, що "перезапишіть все, що у вас є, з копією зі сховища" - це те, що відбувається.
msouth

35

Я думаю, що відповідь VonC - це, мабуть, те, що ти хочеш, але ось спосіб зробити вибіркове "git apply":

git show stash@{0}:MyFile.txt > MyFile.txt

4
У деяких випадках це може бути те, що ви хочете, але будьте обережні, що ця команда замінить замість будь-яких змін робочого каталогу, а не об'єднається.
Ревінь

Це працює для мене, оскільки я просто хотів скопіювати файл, який існує лише у сховці і нічого не хвилює checkout.
Том Расселл

1
Для Windows PowerShell: git show stash@`{0`}:Path/To/MyFile.txt |sc Path/To/MyFile.txt- backticks необхідний для PS, щоб не інтерпретувати дужки спеціально, і scце необхідно, оскільки >оператор PS за замовчуванням UTF-16 (фактично UCS-2), що, мабуть, не те, що ви хочете. Відповідь @Balamurugan A не страждає від цих питань.
Ян Кемп

19

Спочатку перерахуйте всі стаси

git stash list

stash@{0}: WIP on Produktkonfigurator: 132c06a5 Cursor bei glyphicon plus und close zu zeigende Hand ändern
stash@{1}: WIP on Produktkonfigurator: 132c06a5 Cursor bei glyphicon plus und close zu zeigende Hand ändern
stash@{2}: WIP on master: 7e450c81 Merge branch 'Offlineseite'

Потім покажіть, які файли містяться в сховці (давайте вибрати сховище 1):

git stash show 1 --name-only

//Hint: you can also write
//git stash show stash@{1} --name-only

 ajax/product.php
 ajax/productPrice.php
 errors/Company/js/offlineMain.phtml
 errors/Company/mage.php
 errors/Company/page.phtml
 js/konfigurator/konfigurator.js

Потім застосуйте файл, який вам подобається:

git checkout stash@{1} -- <filename>

або цілу папку:

git checkout stash@{1} /errors

Він також працює без, --але рекомендується використовувати їх. Дивіться цю публікацію.

Також звичайно розпізнавати подвійний дефіс як сигнал для припинення інтерпретації варіантів і трактувати всі наступні аргументи буквально.


1
Це зрозуміліше з цією редакцією. +1
VonC

1
Я перепробував багато способів, і цей спосіб був потрібним мені. Я зіткнувся з проблемою, яка git stash popпризвела до помилки для відслідковуваних файлів. Дякую тобі.
Рамін Фіруз

10

Якщо ви git stash pop(без конфліктів), він видалить сховище після його застосування. Але якщо ви, git stash applyто застосуєте виправлення, не видаляючи його із списку скриньки. Тоді ви можете відновити небажані зміни за допомогоюgit checkout -- files...


2
Щоб уточнити конфлікти в цій публікації, якщо у вас git stash popі там є конфлікти, вам доведеться їх виправити вручну, і приховування НЕ буде видалено.
Томас МакКейб

6

Ще один спосіб:

git diff stash@{N}^! -- path/to/file1 path/to/file2  | git apply -R

2
Це єдина правильна відповідь ІМО. Використовуючи checkoutабо showсліпо перезаписуючи файл, замість того, щоб просто застосовувати зміни. "Ще один спосіб" - заниження.
Камбунбурзький

1
Я не отримую path/to/file2так, як ви хочете відрізнятись від того самого файлу у вашій робочій області. Вийти з другого шляху для мене добре працює. - І я отримую повідомлення про помилку, використовуючи -Rпараметр ("застосувати патч у зворотному порядку", намагаючись проклеїти приховану версію ?!). Так виглядає моя робоча версія git diff stash@{N}^! -- path/to/file | git apply -.
ThomasH

"виправлення не вдалося"? Спробуйте тристороннє злиття. ...| git apply -3 -
Джон Мі

6

Для користувачів Windows: фігурні брекети мають особливе значення в PowerShell. Можна або оточити окремими цитатами, або втекти за допомогою зворотного вибору. Наприклад:

git checkout 'stash@{0}' YourFile

Без цього ви можете отримати помилку:

Unknown switch 'e'


3
Повні оцінки PowerShell за найменш корисне повідомлення користувача, яке я бачив цього місяця.
holdenweb
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.