Видалення декількох файлів із репоту Git, які вже були видалені з диска


1311

У мене є репортаж Git, що я видалив чотири файли за допомогою rm( не git rm ), і мій стан Git виглядає приблизно так:

#    deleted:    file1.txt
#    deleted:    file2.txt
#    deleted:    file3.txt
#    deleted:    file4.txt

Як видалити ці файли з Git без необхідності вручну проходити та додавати кожен такий файл:

git rm file1 file2 file3 file4

В ідеалі я шукаю те, що працює так само, як git add .і, якщо це можливо.



10
@seth, це не завжди зручно у використанні git rm, видалення могло бути з окремого інструменту, IDE або файлового менеджера. Visual Studio для одного може бути болем при видаленні / перейменуванні файлів.
Бретт Райан

67
Фу, запитати, чому хтось не використовує git rm, трохи схоже на запитання, чому він не використовує git vimабо git cd. Дурно робити, і git повинен мати вбудовану команду чи псевдонім для видалення видалених файлів з інсценізації, і вам не слід шукати це на SO та не читати сторінки чоловіка на вашій перерві на обід.
WCWedin

7
Відповідь Варіндера - це не гарний спосіб. Розгляньте git add -u, як запропонував Коді, і це також відповідь на це питання: stackoverflow.com/questions/1402776/…
Роланд

Відповіді:


2300

Для Git 1.x

$ git add -u

Це повідомляє git про автоматичне встановлення відстежуваних файлів, включаючи видалення раніше відслідкованих файлів.

Для Git 2.0

Постановіть все робоче дерево:

$ git add -u :/

Щоб прокласти лише поточний шлях:

$ git add -u .

133
Зауважте, що це додасть усі змінені, відслідковані файли - видалені та оновлені.
Ян Хантер

19
@beanland, вам потрібно лише вказати шлях до певного файлу, який ви хочете змінити, якщо ви не хочете, щоб він їх усіх отримав. наприклад, git add -u [шлях]
Paul Prewett

27
також git add -u folder/запустити цю операцію в папці
c ..

2
FYI: ця відповідь злиті з stackoverflow.com/questions/1402776 / ...
Shog9

1
Це може бути питання, яке люди задають, коли вони приїхали на цю сторінку, і це може бути те, що ОП насправді мав намір задати, але це не відповідає точного запитання.
Випускний

1362
git ls-files --deleted -z | xargs -0 git rm 

може бути те, що ви шукаєте .. це працює для мене ..


5
для Windows спробуйте додати наступний псевдонім у ваш конфігурацію без лапок, як зазначено вище Еваном Мораном 'remove =! git ls-files --deleted -z | xargs -0 git rm '
CLS

21
будьте обережні до файлів із пробілами в їх імені
maazza

44
@DaveEverittgit ls-files --deleted -z | xargs -0 git rm
Макс Нанасі

15
git add -u, як запропонував Коді, є набагато простішим та безпечнішим способом, без ризику випадкового видалення файлів.
Роланд

4
Відмовляючись від цього, оскільки це неправильна відповідь, навіть якщо це може працювати для деяких файлів. використовувати "git add -u" нижче. Ось для чого це.
n13

733

Можна використовувати

git add -u

Щоб додати видалені файли до області постановки, потім скопіюйте їх

git commit -m "Deleted files manually"

100
Зауважте, користувач Google: Він додає також змінені відслідковувані файли до області постановки.
еренон

4
Виконайте цю команду лише в тому випадку, якщо ви тільки що видалили файли і хочете їх негайно встановити.
Арьо

1
я не в змозі видалити файл з репортажу bitbucket]
srinivas gowda

356

Якщо ви просто запустіть:

git add -u

git оновить свій індекс, щоб знати, що видалені файли насправді повинні бути частиною наступного комітету. Тоді ви можете запустити "git commit", щоб перевірити цю зміну.

Або якщо ви запускаєте:

git commit -a

Він автоматично прийме ці зміни (та будь-які інші) та здійснить їх.

Оновлення . Якщо ви хочете додати лише видалені файли, спробуйте:

git ls-files --deleted -z | xargs -0 git rm
git commit

1
Правильно, git commit -aбуду робити те, що я хочу, за винятком випадків, коли у мене є файли, які я не хочу вводити, тому я хочу підготувати фіксацію вручну.
Ігор Зевака

2
фіксувати -а по суті робить спочатку "add -u"; він буде оновлювати індекс з будь-якими змінами у відомих файлах (будь то видалення чи прості зміни). Звичайно, ви можете бути більш конкретними та додавати / rm лише ті файли, які ви хочете. git.or.cz/gitwiki/… може бути корисним.
Еміль Сит

2
Набір команд під "Оновлення: .." працював як шарм. Дякую!
Джей Тейлор

10
Дякую тобі за 'git ls-файли --deleted | xargs git rm '!
mit

18
"git ls-files --deleted | xargs git rm" - правильна відповідь! Дякую!
рето

166

Ви, мабуть, шукаєте -A:

git add -A

це схоже на git add -u, але також додає нові файли. Це приблизно еквівалент команди hg addremove(хоча виявлення переміщення є автоматичним).


8
На швидкій сторонній примітці, використання -u обмежує додавання до відстежуваних файлів, а -a також буде включати не відстежені файли. Просто думав, що зазначу різницю.
spaaarky21

На цьому етапі ви також можете додати все за допомогою прапор-виконувати.
Zac Grierson

94

Для постановки лише видалених файлів:

for x in $(git status | grep deleted | awk '{print $2}'); do git rm $x; done

Або (шлях xargs):

git status | awk '/deleted/ {print $2}' | xargs git rm

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


2
@Saeb Зрозумійте про чергу, але xargsпотрібно 15 хвилин, щоб освоїти.
Ерік Вілсон

11
git status | awk '/deleted/ {print $3}' | xargs git rmбув би коротший спосіб зробити це. grep | awk... Просто скажи ні.
Марк Рід

58
git rm $(git ls-files --deleted)це не зручніше (скопійовано з цього ).
Hotschke

1
xargs або вищезазначена $ () підміна, якщо ви знаєте, що список не величезний. Якщо список є величезним: git ls-files --deleted | while read f; do git rm $f; done
Andrew

2
@Andrew xargs, мабуть, більш ефективний, ніж цикл часу для величезного списку, оскільки він передає більше одного аргументу щоразу, коли виконує git rm. Щоб обмежити кількість аргументів, переданих git rmщоразу, коли воно виконується, скористайтеся -nопцією:git ls-files --deleted | xargs -n 15 git rm
Ajedi32

61
git rm test.txt

До або після того, як ви видалили фактичний файл.


7
Незважаючи на те, що це буде працювати, я часто виявляю, що видаляю безліч файлів, rmі потім шкодую про це.
Карл

4
Чому це гірше, ніж робити git add -u? Здається, було б безпечніше додати певні файли, які були видалені до комісії, а не додавати ВСІ зміни.
Ян Данн

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

2
@Ramsharan ні, тому що це зовсім не робиться. При цьому видаляється один файл; ОП СПЕЦИФІЧНО запитував "всі" видалені файли.
Адам

1
@Ramsharan ні, це справа - майже у всіх випадках ви НЕ МОЖЕТЕ просто використовувати підстановку (не існує жодної підстановки, яка б відповідала). Ось чому головна відповідь набагато складніше.
Адам

49

Використовуючи git-add з опціями '--all' або '- update', ви можете отримати більше, ніж хотіли. Нові та / або модифіковані файли також будуть додані до індексу. У мене є настройка псевдоніму bash, коли я хочу видалити видалені файли з git, не торкаючись інших файлів:

alias grma='git ls-files --deleted -z | xargs -0 git rm'

Усі файли, вилучені з файлової системи, додаються до індексу як видалені.


39

Не те, що це насправді має значення, але я не згоден із обраною відповіддю:

git add -u 

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

git rm $(git ls-files --deleted)

... з іншого боку, будуть лише rm видалені файли, які відслідковуються.

Тож останній, на мій погляд, є кращим варіантом.


29

Якщо це єдині зміни, ви можете просто зробити

git commit -a

здійснити всі зміни. Це буде включати видалені файли.


3
Не впевнений, чому я зголосився; git робить хорошу роботу з виявлення видалених файлів, навіть якщо ви прямо не сказали про це за допомогою git rm.
SpoonMeiser

Ви проголосували, оскільки "-a" не є прийнятним перемикачем, це "-A". Редагування вашої відповіді.
Шехаряр

10
Ні, "-a" є прийнятним перемикачем, тому що команда фіксується . "-A" - це перемикач на додавання, але не фіксацію . Я бачу, що запропоновану вам редакцію вже відхилено.
SpoonMeiser

Якщо єдине, що ви робите, - це видалений файл, додайте перемикач --allow-empty
billrichards

Помилка, насправді - пустим-порожнім потрібно лише в тому випадку, якщо ви зробили git rm --cached
billrichards

20
git ls-files --deleted | xargs git rm 

найкращий варіант для додавання лише видалених файлів.

Ось деякі інші варіанти.

git add .  => Add all (tracked and modified)/new files in the working tree.

git add -u => Add all modified/removed files which are tracked.

git add -A => Add all (tracked and modified)/(tracked and removed)/new files in the working tree.

git commit -a -m "commit message" - Add and commit modified/removed files which are tracked.

16

git add -u

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

Якщо не вказано, за замовчуванням встановлено "."; Іншими словами, оновіть усі відслідковані файли в поточному каталозі та його підкаталогах.


Відповідь, що голосує вище, вже говорить про використання git add -u. Звідки беруться всі інші речі у вашій відповіді, документація? Ви маєте посилання на документацію та блокувати її цитатами, якщо вона є.
TheWarriorNamedFoo

14

Це просте рішення добре працює для мене:

git rm $(git ls-files --deleted)

Я думаю, що ви завжди повинні використовувати git shell у вашій поточній робочій
справі

2
Це добре і просто, але не працює з рекурсивними папками.
ДрБ

@BehnazChangizi Я думаю, що це так, stackoverflow.com/questions/1054044/…
Houssem Badri

@PvdL не прийнято пробілів у шляху - це специфічна проблема
Houssem Badri

11

Якщо ви хочете додати його до свого, .gitconfigзробіть це:

[alias]
  rma = !git ls-files --deleted -z | xargs -0 git rm

Тоді все, що вам потрібно зробити, це запустити:

git rma

1
та з cmd linegit config --global alias.rmd '!git ls-files --deleted -z | xargs -0 git rm'
Кейсі

9
git ls-files --deleted -z | xargs -0 git rm --cached

Це видалить усі видалені файли, які попередньо відслідковувалися git, а також оброблятиме справу, у якій у ваших іменах є пробіли.

Залежно від варіанта POSIX, можливо, вам знадобиться використовувати xargs -0 -r: це призведе xargsдо витонченого виходу, коли трубопровідний контент є нульовим.

EDIT: --cachedі --deletedпрапори використовуються в тандемі для захисту від випадкового видалення файлів, які ще не були видалені.


7

Скажіть команді автоматично ставити файли, які були змінені та видалені, але нові файли, про які Git не повідомив, не впливають:

-a
--all

git add . && git commit -m -a "Your commit"

або

git add --all && git commit -m "Your commit"

1
git add --all && git commit -m "Ваша фіксація" Це працювало для мене в Windows-7, використовуючи командну оболонку Git bash.
kmarabet

1
Наступна команда працювала для мене в windows-7, використовуючи командну команду Git bash: $ git add --all && git commit -m "видалити файли властивостей" [master 58c41ac] видалити файли властивостей. 1 файл змінено, 9 видалень (-). .. Потім для запуску цих допущених змін до віддаленого сховища запущено: $ git push origin .. Підрахунок об'єктів: 10, зроблено.
kmarabet

6

Далі працює, навіть якщо у вас є багато файлів для обробки:

git ls-files --deleted | xargs git rm

Ви, ймовірно, також захочете покласти коментар.

Докладніше див: Корисні сценарії Git


6

Будь ласка, використовуйте -t щоб побачити, яка команда виконується насправді

Я просто змінив відповідь Virender, щоб зробити те саме:

git ls-files --deleted -z | xargs -t -0 git rm

5

Жоден з прапорів git-add не буде лише знімати файли; якщо все, що ви змінили, - це видалені файли, то ви добре, але в іншому випадку вам потрібно запустити git-статус і проаналізувати вихід.

Оцінюючи відповідь Джеремі, ось що я отримав:

git status |  sed -s "s/^.*deleted: //" | grep "\(\#\|commit\)" -v | xargs git rm
  1. Отримайте статус файлів.
  2. Для видалених файлів виділіть ім’я файлу.
  3. Видаліть усі рядки, що починаються з #s, а також рядок статусу, у якому слово "видалено"; Я точно не пам’ятаю, що це було саме так, і його вже немає, тому, можливо, доведеться змінювати це для різних ситуацій. Я думаю, що групування виразів може бути специфічною для GNU, тому якщо ви не використовуєте gnutils, можливо, вам доведеться додати кількаgrep -v рядків.
  4. Передайте файли в git rm.

Вставляючи це в псевдонімі оболонки зараз ...


5

Як вже згадувалось

git add -u

етапи видалення файлів для видалення, АЛЕ ТАКОЖ змінені файли для оновлення.

Для видалення змінених файлів ви можете зробити

git reset HEAD <path>

якщо ви хочете організовувати та чистити свої зобов’язання.
ПРИМІТКА. Це також може видалити видалені файли, тому будьте обережні з тими символами.


4
git commit -m 'commit msg' $(git ls-files --deleted)

Це працювало для мене після того, як я вже видалив файли.


3

Мені потрібно було те саме і я використовував кнопку git gui "етап змінився". він також додає все.

І після того, як "етап змінився", я змусив "здійснити" ...

тож мій робочий каталог знову чистий.


Добре використовувати гу - це ВИБУТИ, хаха! Але швидше у тих випадках, коли дизайнер GUI відповідав вашим потребам. Добре знати, як повозитися з «що знаходиться під кришкою».
Денніс

1
FYI: ця відповідь злиті з stackoverflow.com/questions/1402776 / ...
Shog9

3
git rm $(git ls-files -d)

Видаляє всі файли, перелічені git ls-filesкомандою (-d показує лише видалені файли). Не працює для файлів із пробілами у назві файлу чи шляху, але просто запам'ятовується


2

Можна використовувати git add -u <filenames> для постановки лише видалені файли.

Наприклад, якщо ви видалили файли templates/*.tpl, тоді використовуйтеgit add -u templates/*.tpl .

-uПотрібно для того , щоб посилатися на файли , які не існують в сховище , але в робочому каталозі більше не існує. В іншому випадку за замовчуванням git addпотрібно шукати файли в робочому каталозі, і якщо ви вкажете файли, які ви видалили, вони не знайдуть їх.


2

Додавання системного псевдоніму для постановки видалених файлів як команди rm-all

UNIX alias rm-all='git rm $(git ls-files --deleted)'

ВІКНИ doskey rm-all=bash -c "git rm $(git ls-files --deleted)"

Примітка

Windows має бути bashвстановлено.


2

(Ще одна варіація)

Я хотів видалити всі вже видалені з файлів диска, але з однієї конкретної папки, залишивши інші папки недоторканими. Для мене працювало наступне:

git ls-files --deleted  | grep <folder-name> | xargs git rm


1

Для візуального студійного проекту

'git ls-files --deleted | sed 's/(.*)/"\1"/'| xargs git rm' 

що корисно, коли у шляху до видаленого файлу є пробіл


-1

Найбільш гнучке рішення, яке я знайшов на сьогоднішній день, - це

git cola

І виберіть усі видалені файли, які я хочу поставити.

(Зауважте, я зазвичай виконую все командний рядок у git, але git обробляє видалені файли трохи незручно).


Уайлдкард не працював для мене, git add -u path/to/my/deleted-files-pattern-*.ymlтому це була найкраща відповідь для мене (не хотіла виставляти всі видалені файли, але 50 із пари сотень).
mlncn
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.