Як змусити Git "забути" про файл, який відслідковувався, але зараз він знаходиться у .gitignore?


5394

Є файл, який відслідковувався git, але тепер файл знаходиться у .gitignoreсписку.

Однак цей файл відображається git statusпісля редагування. Як ви змушуєте gitповністю забути про це?


16
git clean -Xзвучить схоже, але це не застосовується в цій ситуації (коли файли все ще відслідковуються Git). Я пишу це для тих, хто шукає рішення не слідувати неправильному маршруту.
imz - Іван Захарящев

35
Єдина реальна відповідь на це - нижче, див git update-index --assume-unchanged. Це рішення 1) зберігає файл на сервері (індекс), 2) дозволяє вільно змінювати його локально.
Qwerty

8
Вам потрібно скористатися --skip-worktree, дивіться: stackoverflow.com/questions/13630849/…
Doppelganger

77
Важливе питання: чи повинен файл зберігатись у сховищі чи ні? Наприклад, якщо хтось новий клонує репо, чи повинен він отримати файл чи ні? Якщо ТАК , то git update-index --assume-unchanged <file>це правильно , і файл буде залишатися в сховище і зміни не будуть додані з git add. Якщо НІ (наприклад, це був якийсь кеш-файл, згенерований файл тощо), тоді git rm --cached <file>вилучіть його з сховища.
Мартін

9
@Martin @Qwerty Кожен повинен зупинитися, щоб порадити, --assume-unchangedщо стосується продуктивності, щоб перешкодити git перевіряти стан великих відстежуваних файлів, але вважати за краще --skip-worktreeмодифіковані відстежувані файли, які користувач більше не хоче робити. Дивіться stackoverflow.com/questions/13630849/…
Філіп

Відповіді:


5693

.gitignoreне дозволить додавати незавершені файли (без ан add -f) до набору файлів, які відслідковуються git, проте git продовжує відстежувати файли, які вже відстежуються.

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

git rm --cached <file>

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

git rm -r --cached <folder>

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

ПОПЕРЕДЖЕННЯ. Хоча цей фізичний файл не видалить з вашого локального, він видалить файли з інших машин розробників далі git pull.


55
процес, який працював для мене: 1. спершу виконувати очікувані зміни 2. git rm --cached <file> і знову зробити 3. додати файл до .gitignore, перевірити стан git та знову зробити
mataal

117
Дуже важливе додавання. Якщо файл, який ігнорується, буде змінено (але, незважаючи на це, він не повинен виконуватись), після зміни та виконання git add .він буде доданий до індексу. І наступна фіксація взяла б її в сховище. Щоб уникнути цього виконання відразу після того, що mataal сказав ще одну команду:git update-index --assume-unchanged <path&filename>
Дао

32
Метод @AkiraYamamoto добре працював і для мене. У моєму випадку я придушив вихід, оскільки в моєму сховищі було тисячі файлів:git rm -r -q --cached .
Аарон Бленкуш

85
Цей файл буде видалено, git pullхоча.
Петро Пеллер

22
git rm --cached <file> просто видаліть файл із сховища, git update-index --assume-unchanged <file> не відображається у файлі в незмінених змінах і не вносить нових змін. Але я хочу, щоб GIT ПЕРЕГЛЯДУВАТИ ЗМІСТ ФАЙЛОВОГО ПЛАНУВАННЯ
Ігор Семін

2609

Низка наведених нижче команд видалить усі елементи з індексу Git (не з робочого каталогу чи локального репо), а потім оновить індекс Git, дотримуючись ігнорування git. PS. Індекс = Кеш

Спочатку:

git rm -r --cached . 
git add .

Тоді:

git commit -am "Remove ignored files"

Або однолінійний:

git rm -r --cached . && git add . && git commit -am "Remove ignored files"

197
Щоб виділити різницю між цією відповіддю та прийнятою: Використовуючи ці команди, вам не потрібно насправді знати файли, на які впливає. (Уявіть собі тимчасовий редактор з великою кількістю випадкових файлів, які слід очистити від індексу).
Людвіг

53
Те саме, що прийнята відповідь. Файли буде видалено git pull.
Петро Пеллер

73
Було б непогано мати це як стандартна команда git. Щось подібне git rmignored.
Берік

12
@gudthing -r означає "рекурсивний"
Марк

14
З цим ви можете додати інші непотрібні файли, які зараз не знаходяться .gitignore. Що може бути важко дізнатись, якщо залежно від того, наскільки шум git statusбуде після цієї команди. Краще буде команда, яка видаляє лише щойно проігноровані файли. Тому я віддаю перевагу відповіді
thSoft

1122

git update-index робить роботу для мене:

git update-index --assume-unchanged <file>

Примітка. Це рішення фактично не залежить, .gitignoreоскільки gitignore призначений лише для файлів, що не відслідковуються.

редагувати: Оскільки ця відповідь була розміщена, створено новий варіант, якому слід віддати перевагу. Вам слід скористатись --skip-worktreeмодифікованими відслідковуваними файлами, які користувач більше не хоче здійснювати, і підтримувати --assume-unchangedпродуктивність, щоб запобігти git перевіряти стан великих відстежуваних файлів. Дивіться https://stackoverflow.com/a/13631525/717372 для більш детальної інформації ...

git update-index --skip-worktree <file>

173
Це IS реальний відповідь. Дивовижно насправді, дуже просто, не забруднює git statusі насправді дуже інтуїтивно зрозуміло. Дякую.
Пабло Олмос де Агілера C.

4
Я пішов на досить хороше rm [...] .рішення, як, принаймні, міг збагнути, як це працює. Я не знайшов великий документації про те , що update-indexі --assume-unchangedробити. Хтось може додати, як це порівнюється з іншими, тим, що я хотів би видалити всі файли, які були б проігноровані? (Або посилання на чітке пояснення?)
Брейді Тренер

25
git update-index --assume-unchanged <path> …призведе до того, що git ігнорує зміни у вказаних шляхах, незалежно від .gitignore. Якщо ви витягнете з пульта, і цей віддалений змінив цей шлях, git не зможе злитися з конфліктом, і вам потрібно буде злитися вручну. git rm --cached <path> …Git припинить відстежувати цей шлях. Якщо ви не додасте шлях, .gitignoreви побачите шлях у майбутньому git status. Перший варіант має менший шум в історії введення файлів git і дозволяє в майбутньому поширювати зміни в "ігнорованому" файлі.
ManicDee

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

11
Ця відповідь була б набагато кориснішою, якби вона точно пояснила, що робить дана команда, наприклад, чим вона відрізняється від інших запропонованих рішень.
LarsH

283
git ls-files --ignored --exclude-standard -z | xargs -0 git rm --cached
git commit -am "Remove ignored files"

Це бере список ігнорованих файлів і видаляє їх з індексу, а потім здійснює зміни.


7
Якщо вам також потрібно видалити їх із робочого каталогу, просто запустіть git ls-files --ignored --exclude-standard | xargs git rm . Я вважаю, що ця відповідь найкраща! Тому що це дуже зрозуміло, Unix-спосіб, і робить потрібну річ прямо, без складання побічних ефектів інших, більш складних команд.
imz - Іван Захарящев

6
Чудова відповідь; однак команда не вдасться, якщо у вас є шляхи з пробілами посередині, наприклад: "Мій dir / my_ignored_file.txt"
Девід Ернандес

8
git ls-files --ignored --exclude-стандарт | sed 's /.*/"&"/' | xargs git rm --cached
Девід Ернандес

3
git rmпоскаржиться, якщо ls-filesнічого не відповідав. Використовуйте, xargs -r git rm ...щоб сказати xargsне запускати, git rmякщо жоден файл не збігається.
Вольфганг

10
Було б краще використовувати \ 0 як роздільник:git ls-files --ignored --exclude-standard -z|xargs -0 git rm --cached
Nils-o-mat

83

Я завжди використовую цю команду, щоб видалити ці неактивні файли. Однорядковий, чистий вихід у Unix-стилі:

git ls-files --ignored --exclude-standard | sed 's/.*/"&"/' | xargs git rm -r --cached

У ньому перераховані всі ваші ігноровані файли, замініть кожен вихідний рядок цитованим рядком замість того, щоб обробляти шляхи з пробілами всередині, і передайте все, git rm -r --cachedщоб видалити шляхи / файли / dirs з індексу.


3
Чудове рішення! Працював на відмінно і відчуває себе більш правильним, як видалити всі файли, а потім додати їх знову.
Джон Кетмулл

5
Я теж вважав це "найчистішим". Це може бути очевидним, але тільки запустивши першу частину, git ls-files --ignored --exclude-standardви самі зможете спершу зрозуміти / перевірити, які файли .gitignoreбуде виключено / видалено вашими новими файлами , перш ніж продовжувати та виконувати остаточну git rm.
JonBrave

Будьте в курсі, помилки у назви файлів з певними "неприємними" символами, наприклад \n. Я опублікував своє рішення щодо задоволення цього питання.
JonBrave

3
Ще одне застереження: натягнути це призведе до того, що файл буде видалено в інших робочих каталогах, правда?
LarsH

спробував, але не працював для мене: sed: 1: "s/.*/": unterminated substitute in regular expressionу команді фільтр-гілка на репо з пробілами. (Схоже, він працює поза фільтром гілки). Я використовував git ls-files -z --ignored --exclude-standard | xargs -0 git rm -r --cachedвід @ JonBrave в відповідь замість цього.
goofology

70

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


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

Саме це я і зробив. Просто перемістіть файли у папку поза git, потім виконайте "git add.", "Git commit". (Це видалило файли), потім додайте gitignore, посилаючись на файли / папки, знову покладіть на додавання файлу gitignore до git, потім скопіюйте / перемістіть назад у папках, і їх слід ігнорувати. Зверніть увагу: здається, що файли були видалені з GIT, тому, ймовірно, видаляйте їх з інших замовлень / витяг, як згадувалося у вищезазначених рішеннях, але оскільки ви створюєте їх копії спочатку, це не є великою частиною проблеми IMHO. просто дайте знати решті команди ...
Дель

Це найпростіший спосіб позбутися від неправильно скоєних папок.
Martlark

1
Здається, це єдиний спосіб, який я бачу. Це величезна помилка (не 'особливість') в git, що, як тільки ви додаєте файл / папку до .gitignore, він не просто ігнорує цей файл з цього моменту - назавжди - скрізь.
JosephK

Це спрацювало після того, як я їх додав, а потім після факту додав їх до .gitignore
hanzolo

66

Якщо ви не git rmможете відслідковувати файл, оскільки це може знадобитися іншим людям (попередження, навіть якщо ви git rm --cached , коли хтось інший отримає цю зміну, їх файли будуть видалені у їхній файловій системі). Це часто робиться через скасування конфігураційних файлів, облікових даних аутентифікації тощо. Погляньте на сторінку https://gist.github.com/1423106, щоб дізнатися, як люди вирішили проблему.

Узагальнити:

  • Запропонуйте вашій програмі шукати ігнорований файл config-overide.ini і скористайтеся цим файлом у файлі config.ini (або по черзі шукайте ~ / .config / myapp.ini або $ MYCONFIGFILE)
  • Введіть файл config-sample.ini і ігноруйте файл config.ini, майте сценарій або скопіюйте файл, якщо потрібно.
  • Спробуйте використовувати gitattributes clean / maguding magic, щоб застосувати та видалити зміни, наприклад, розмазати конфігураційний файл як замовлення з іншої гілки та очистити конфігураційний файл як замовлення від HEAD. Це складні речі, я не рекомендую цього для початківця користувача.
  • Зберігайте конфігураційний файл у відведеній для нього гілці розгортання, яка ніколи не об'єднується в основний. Коли ви хочете розгорнути / компілювати / протестувати, ви з’єднаєтесь із цією гілкою та отримаєте цей файл. Це, по суті, підхід до розмивання / чистого, за винятком використання політик злиття людини та модулів extra-git.
  • Антирекомендація: не використовуйте припущення без змін, воно закінчиться лише сльозами (адже мана на брехні себе спричинить погані речі, як-от ваша зміна втрачена назавжди).

7
git не видалить файл, якби він був брудним під час видалення. І якщо це не брудно, витягнення файлу було б таким же простим, як git checkout <oldref> -- <filename>- але тоді його перевіряли б і ігнорували.
амент

Щодо вашої останньої замітки (про --assume-unchanged): або це культовий культ, і його слід відхилити, або ви можете пояснити, чому (в чому я переконаний) і це стає корисним.
RomainValeri

57

Використовуйте це, коли:

1. Ви хочете зняти багато файлів, або

2. Ви оновили файл gitignore

Джерело посилання: http://www.codeblocq.com/2016/01/Untrack-files-already-added-to-git-repository-based-on-gitignore/

Скажімо, ви вже додали / ввели деякі файли у свій сховище git, а потім додасте їх у свій .gitignore; ці файли все ще будуть присутні у вашому індексі сховища. У цій статті ми побачимо, як від них позбутися.

Крок 1: Введіть усі зміни

Перш ніж продовжувати, переконайтеся, що всі ваші зміни здійснені, включаючи файл .gitignore.

Крок 2: Видаліть усе з сховища

Щоб очистити репо, скористайтеся:

git rm -r --cached .
  • rm - команда видалення
  • -r дозволить рекурсивно видалити
  • –Кешований буде видаляти лише файли з індексу. Ваші файли все ще будуть там.

rmКоманда може бути невблаганною. Якщо ви бажаєте спробувати заздалегідь, додайте -nабо --dry-runпрапор, щоб перевірити речі.

Крок 3: Повторно додайте все

git add .

Крок 4: Здійснити

git commit -m ".gitignore fix"

Ваш сховище чисте :)

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


1
Це не видалить файли з віддаленого сховища? Що робити, якщо я хочу зберігати файли як у локальній, так і у віддаленій репо, але змушу git "забути" про них?
Avishay28

AFAIK це не видалить файли з історії, тому що ми не використовуємо жодних команд для зміни історії (виправте мене, якщо я помиляюся). Це лише додає нову фіксацію, видаливши з git файли, проігноровані в gitignore. Ці файли будуть там у історичні зобов’язання
Dheeraj Bhaskar

49

Я досяг цього, використовуючи фільтр-гіт git . Точна команда, яку я використав, взята зі сторінки man:

УВАГА : це видалить файл із усієї вашої історії

git filter-branch --index-filter 'git rm --cached --ignore-unmatch filename' HEAD

Ця команда відтворить всю історію комісій, виконуючи git rmперед кожним фіксацією, і таким чином позбудеться вказаного файлу. Не забудьте створити резервну копію перед виконанням команди, оскільки вона буде втрачена.


9
Це змінить усі ідентифікатори комісій, тим самим порушивши злиття з гілок поза вашою копією сховища.
bdonlan

19
УВАГА: це видалить файл із усієї вашої історії. Це те, що я шукав, хоча, щоб видалити абсолютно непотрібний і негабаритний файл (вихід, який ніколи не мав би бути здійснений), який був зроблений давно в історії версій.
zebediah49

48

Що не працювало для мене

(Під Linux), я хотів використати публікації, що пропонують тут ls-files --ignored --exclude-standard | xargs git rm -r --cachedпідхід. Однак (деякі) файли, які потрібно видалити, мали вбудований новий рядок / LF / \nу свої імена. Жодне з рішень:

git ls-files --ignored --exclude-standard | xargs -d"\n" git rm --cached
git ls-files --ignored --exclude-standard | sed 's/.*/"&"/' | xargs git rm -r --cached

впоратися з цією ситуацією (отримати помилки щодо файлів не знайдено).

Тож пропоную

git ls-files -z --ignored --exclude-standard | xargs -0 git rm -r --cached
git commit -am "Remove ignored files"

Для цього використовується -zаргумент ls-файлів та -0аргумент xargs, щоб безпечно / правильно обслуговувати "неприємні" символи у назви файлів.

На сторінці керівництва git-ls-files (1) зазначено:

Якщо параметр -z не використовується, символи TAB, LF та зворотної косої риси в іменах шляхів подаються відповідно \ t, \ n та \\.

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


1
Для мене це найкраще рішення. Він має набагато кращі показники, ніж a git add .. Він також містить найкращі вдосконалення з деяких коментарів вище.
Nils-o-mat

Чи можете ви потім додати відповідь thSoft git commit -am "Remove ignored files"до своєї відповіді? Ваші відповіді у поєднанні
перейняли

Я не розумію мети git commit -a. Для мене git rm --cachedвпливає саме на індекс, тому немає необхідності встановлювати файли після ...
Жан Пол

23
  1. Оновіть свій .gitignoreфайл - наприклад, додайте папку, до якої ви не хочете відстежувати .gitignore.

  2. git rm -r --cached .- Видаліть усі відслідковувані файли, включаючи шукані та небажані. Ваш код буде безпечним до тих пір, поки ви збережете локально.

  3. git add .- Усі файли будуть додані назад, крім тих, що в .gitignore.


Наконечник капелюха до @AkiraYamamoto, щоб вказати нам у правильному напрямку.


1
Як щодо недозволеного через те, що він насправді не працюватиме, оскільки вам потрібен -r для запуску rm рекурсивно в будь-якому випадку :) (Хтось не копіював правильно)
Aran Mulholland

1
Попередження: Ця методика насправді не спричиняє git ігнорувати файл, натомість він фактично спричинює видалення файлу git. Це означає, що якщо ви користуєтеся цим рішенням, будь-коли хто-небудь інший зробить git, файл буде видалений. Тож насправді це не ігнорується. Дивіться рішення, яке пропонує git update-index --assume-unchanged, а не вирішення оригінального питання.
orrd

16

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

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

Але в Git кожен раз, коли ви здійснюєте або зберігаєте стан свого проекту, він в основному створює зображення того, як виглядають усі ваші файли в той момент, і зберігає посилання на цей знімок. Отже, якщо ви додали файл один раз, він завжди буде присутній у цьому знімку.

Ці 2 статті були для мене корисними:

git припустимо-незмінним vs skip-worktree та Як ігнорувати зміни в відстежуваних файлах за допомогою Git

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

git update-index --skip-worktree <file>

З цього моменту всі локальні зміни у цьому файлі будуть ігноруватись та не перейдуть у віддалений. Якщо файл буде змінено на віддалений, конфлікт виникне, коли git pull. Стек не працюватиме. Щоб вирішити цю проблему, скопіюйте вміст файлу в безпечне місце та виконайте наступні дії:

git update-index --no-skip-worktree <file>
git stash
git pull 

Вміст файлів буде замінено на віддалений вміст. Вставте зміни з безпечного місця в файл і виконайте знову:

git update-index --skip-worktree <file>

Якщо всі, хто працює з проектом, будуть виступати git update-index --skip-worktree <file>, проблеми з ним pullповинні бути відсутніми. Це рішення добре для файлів конфігурацій, коли кожен розробник має власну конфігурацію проекту.

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


16

Виконайте наступні дії послідовно, вам буде добре.

1. видаліть помилково додані файли з каталогу / сховища . Ви можете використовувати команду "rm -r" (для Linux) або видалити їх, переглянувши каталоги. Або перемістіть їх в інше місце на вашому ПК [Можливо, вам потрібно буде закрити IDE, якщо ви працюєте для переміщення / видалення ]

2.додайте файли / каталоги до gitignoreфайлу зараз і збережіть їх.

3. тепер видаліть їх з кеш-пам'яті git за допомогою цих команд (якщо є декілька каталогів, видаліть їх по черзі, повторно видаючи цю команду)

git rm -r --cached path-to-those-files

4.Now зробити фіксації і натиск , використовувати ці команди. Це видалить ці файли з віддаленого git та змусить Git зупинити відстеження цих файлів.

git add .
git commit -m "removed unnecessary files from git"
git push origin

13

Відповідь копіювання / вставка є git rm --cached -r .; git add .; git status

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


9

Відповідь від Matt Fear була найефективнішою IMHO. Далі наведено лише сценарій PowerShell для тих, хто у Windows, видаляє лише файли зі свого git repo, що відповідає їх списку виключень.

# Get files matching exclusionsfrom .gitignore
# Excluding comments and empty lines
$ignoreFiles =  gc .gitignore | ?{$_ -notmatch  "#"} |  ?{$_ -match  "\S"} | % {
                    $ignore = "*" + $_ + "*"
                    (gci -r -i $ignore).FullName
                }
$ignoreFiles = $ignoreFiles| ?{$_ -match  "\S"}

# Remove each of these file from Git 
$ignoreFiles | % { git rm $_}

git add .

У якій ситуації цей список файлів не буде рівним рекурсивно - кешованому?
Іван Заброський

8

Перемістіть або скопіюйте файл у безпечне місце, щоб не втратити його. Потім git rm файл і зробити. Файл все одно з’явиться, якщо ви повернетесь до одного з попередніх комісій або до іншої гілки, де він не був видалений. Однак у всіх майбутніх зобов'язаннях файл ви більше не побачите. Якщо файл знаходиться в ігноруванні git, ви можете перемістити його назад у папку, і git не побачить його.


34
git rm --cachedвидалить файл з індексу, не видаляючи його з диска, тому не потрібно його переміщувати / копіювати
bdonlan

7

Використання git rm --cachedкоманди не дає відповіді на початкове запитання:

Як ви змушуєте gitповністю забути про [файл]?

Фактично, це рішення призведе до видалення файлу в будь-якому іншому екземплярі сховища при виконанні git pull!

Правильний шлях сили мерзотника забути про фото документується GitHub тут .

Я рекомендую прочитати документацію, але в основному:

git fetch --all
git filter-branch --force --index-filter 'git rm --cached --ignore-unmatch full/path/to/file' --prune-empty --tag-name-filter cat -- --all
git push origin --force --all
git push origin --force --tags
git for-each-ref --format='delete %(refname)' refs/original | git update-ref --stdin
git reflog expire --expire=now --all
git gc --prune=now

просто замініть full/path/to/fileповний шлях до файлу. Переконайтеся, що ви додали файл до свого .gitignore.

Вам також потрібно (тимчасово) дозволити нешвидкісне пересування вперед до вашого сховища , оскільки ви змінюєте свою історію git.


5

BFG спеціально розроблена для видалення небажаних даних , таких як великі файли або паролі з Git РЕПО, так що має простий прапор , який буде видаляти будь-який великий історичний (НЕ-в-ваш-ток фіксації) файлів: «--strip-blobs- більше, ніж'

$ java -jar bfg.jar --strip-blobs-bigger-than 100M

Якщо ви хочете вказати файли за іменем, ви також можете це зробити:

$ java -jar bfg.jar --delete-files *.mp4

BFG на 10-1000x швидше, ніж фільтр git filter, і, як правило, набагато простіше у використанні - перегляньте повні інструкції та приклади використання для отримання детальної інформації.

Джерело: https://confluence.atlassian.com/bitbucket/reduce-repository-size-321848262.html


5

Якщо ви не хочете використовувати CLI і працюєте в Windows, дуже простим рішенням є використання TortoiseGit , у меню є дія "Видалити (зберігати локальну)", яка працює чудово.


5

Мені сподобалась відповідь JonBrave, але у мене досить безладні робочі каталоги, які займаються, - мене трохи лякає, тож ось що я зробив:

git config --global alias.exclude-ignored '! git ls-files -z --ignored --exclude-стандарт | xargs -0 git rm -r - кешований && git ls-файли -z --ignored --exclude-стандарт | xargs -0 git stage && git stage .gitignore && git commit -m "нова gitignore та видалення проігнорованих файлів з індексу" '

розбивши його:

git ls-files -z --ignored --exclude-standard | xargs -0 git rm -r --cached 
git ls-files -z --ignored --exclude-standard | xargs -0 git stage 
git stage .gitignore 
git commit -m "new gitignore and remove ignored files from index"
  • видалити проігноровані файли з індексу
  • етап .gitignore та файли, які ви тільки що видалили
  • вчинити

4

Це вже не проблема в останньому git (v2.17.1 на момент написання).

.gitignoreНарешті ігнорує відслідковуються, але віддалені файли. Ви можете перевірити це на собі, запустивши наступний сценарій. Заключна git statusзаява повинна повідомляти про "нічого робити".

# Create empty repo
mkdir gitignore-test
cd gitignore-test
git init

# Create a file and commit it
echo "hello" > file
git add file
git commit -m initial

# Add the file to gitignore and commit
echo "file" > .gitignore
git add .gitignore
git commit -m gitignore

# Remove the file and commit
git rm file
git commit -m "removed file"

# Reintroduce the file and check status.
# .gitignore is now respected - status reports "nothing to commit".
echo "hello" > file
git status

Я радий, що Git зараз робить це. Однак ОП просили не відстежувати модифікації у файлах, присутніх у .gitignore, а не видалених файлах, які все ще мають статус.
mrturtle

2

У разі вже скоєного DS_Store:

find . -name .DS_Store -print0 | xargs -0 git rm --ignore-unmatch

Ігноруйте їх:

echo ".DS_Store" >> ~/.gitignore_global
echo "._.DS_Store" >> ~/.gitignore_global
echo "**/.DS_Store" >> ~/.gitignore_global
echo "**/._.DS_Store" >> ~/.gitignore_global
git config --global core.excludesfile ~/.gitignore_global

Нарешті, візьміть на себе зобов’язання!


2

Спеціально для файлів на основі IDE я використовую це:

Наприклад, slnx.sqlite, я просто позбувся його повністю, як наступне:

git rm {PATH_OF_THE_FILE}/slnx.sqlite -f
git commit -m "remove slnx.sqlite"

Пам’ятайте лише про те, що деякі з цих файлів зберігають локальні налаштування користувача та налаштування проектів (наприклад, які файли ви відкрили). Отже, кожного разу, коли ви переходите чи вносите якісь зміни в IDE, цей файл змінюється, і тому він перевіряє його і показує, як є незапущені зміни.


2

Прийнята відповідь не "змушує Git " забути " про файл ..." (історично). Це лише змушує git ігнорувати файл у теперішньому / майбутньому.

Цей метод змушує git повністю забути проігноровані файли ( минуле / теперішнє / майбутнє), але нічого не видаляє з робочого каталогу (навіть при повторному витягуванні з віддаленого).

Цей метод вимагає використання /.git/info/exclude(переважно) або вже існуючий .gitignore в усіх коммітов , які мають файли , які будуть ігноруватися / забуто. 1

Усі методи примусового ігнорування поведінки після фактично переписують історію і, таким чином, мають значні наслідки для будь-яких публічних / спільних / спільних / репортажів, які можуть бути витягнуті після цього процесу. 2

Загальна порада: почніть з чистого репо-репортажу - все, що зроблено, нічого не очікує на робочий каталог чи індекс, і зробіть резервну копію !

Крім того , коментарі / історія змін з цієї відповіді ( і історії змін по цьому питанню ) , може бути корисною / просвіщаючи.

#commit up-to-date .gitignore (if not already existing)
#this command must be run on each branch

git add .gitignore
git commit -m "Create .gitignore"

#apply standard git ignore behavior only to current index, not working directory (--cached)
#if this command returns nothing, ensure /.git/info/exclude AND/OR .gitignore exist
#this command must be run on each branch

git ls-files -z --ignored --exclude-standard | xargs -0 git rm --cached

#Commit to prevent working directory data loss!
#this commit will be automatically deleted by the --prune-empty flag in the following command
#this command must be run on each branch

git commit -m "ignored index"

#Apply standard git ignore behavior RETROACTIVELY to all commits from all branches (--all)
#This step WILL delete ignored files from working directory UNLESS they have been dereferenced from the index by the commit above
#This step will also delete any "empty" commits.  If deliberate "empty" commits should be kept, remove --prune-empty and instead run git reset HEAD^ immediately after this command

git filter-branch --tree-filter 'git ls-files -z --ignored --exclude-standard | xargs -0 git rm -f --ignore-unmatch' --prune-empty --tag-name-filter cat -- --all

#List all still-existing files that are now ignored properly
#if this command returns nothing, it's time to restore from backup and start over
#this command must be run on each branch

git ls-files --other --ignored --exclude-standard

Нарешті, дотримуйтесь решти цього посібника GitHub (починаючи з кроку 6), який включає важливі попередження / інформацію про команди нижче .

git push origin --force --all
git push origin --force --tags
git for-each-ref --format="delete %(refname)" refs/original | git update-ref --stdin
git reflog expire --expire=now --all
git gc --prune=now

Інші розробники, які витягуються з тепер модифікованого віддаленого репо, повинні зробити резервну копію, а потім:

#fetch modified remote

git fetch --all

#"Pull" changes WITHOUT deleting newly-ignored files from working directory
#This will overwrite local tracked files with remote - ensure any local modifications are backed-up/stashed

git reset FETCH_HEAD

Виноски

1 Оскільки /.git/info/excludeможе застосовуватися до всіх історичних комісій за допомогою наведених вище вказівок, можливо, деталі щодо введення .gitignoreфайлу в історичні комісії, які потребують цього, виходять за межі цієї відповіді. Я хотів, щоб це було належним .gitignoreчином у корені, так, ніби це було перше, що я зробив. Іншим може бути байдуже, оскільки вони /.git/info/excludeможуть здійснити те саме, незалежно від того, де .gitignoreіснує історія вчинення, і, очевидно, переписування історії є дуже чутливою темою, навіть коли знають про наслідки .

FWIW, потенційні методи можуть включати git rebaseабо git filter-branchкопіювати зовнішнє .gitignore у кожен комітет, як відповіді на це питання

2 Посилення поведінки ігнорування git після факту шляхом виконання результатів автономної git rm --cachedкоманди може призвести до видалення знову ігнорованого файлу у майбутніх витягах із пульта дистанційного керування. --prune-emptyПрапор в наступній git filter-branchкоманді дозволяє уникнути цієї проблеми шляхом автоматичного видалення попереднього «видалити всі ігноровані файли» індекс тільки зробити. Перезапис історії git також змінює хеши, які спричинять шкоду на майбутніх репортажах з громадських / спільних / спільних / репортажів. Будь ласка, розумійте наслідки, перш ніж робити це до такого репо. Цей посібник GitHub визначає наступне:

Повідомте своїм співробітникам перезавантажувати , а не об’єднувати будь-які гілки, які вони створили з вашої старої (зіпсованої) історії сховища. Одне об'єднання злиття може знову ввести частину чи всю зіпсовану історію, яку ви просто вирішили очистити.

Альтернативні рішення, які не впливають на віддалений репо, є git update-index --assume-unchanged </path/file>або git update-index --skip-worktree <file>, приклади яких можна знайти тут .


0

Якщо у когось важко перебувати в Windows, і ви хочете ігнорувати всю папку, 'cd' шукайте «папку» і робіть «Git Bash Here».

git ls-files -z | xargs -0 git update-index --assume-unchanged

0

У моєму випадку тут у мене було кілька файлів .lock у кількох каталогах, які мені потрібно було видалити. Я запустив наступне, і це спрацювало, не виходячи з кожного каталогу, щоб видалити їх:

git rm -r --cached **/*.lock

Це увійшло до кожної папки під «коренем», де я знаходився, і виключив усі файли, які відповідали шаблону.

Сподіваюсь, це допомагає іншим!

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