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

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

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

4082
13 авг. заданий Ivan 13 Серпня. 2009-08-13 22:23 '09 о 22:23 2009-08-13 22:23
@ 22 відповідей

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

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

 git rm --cached <file> 

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

УВАГА: Хоча це не видалить фізичний файл з вашого локального, він буде видаляти файли з машин інших розробників при наступному git pull .

4329
13 авг. відповідь дан CB Bailey 13 Серпня. 2009-08-13 23:40 '09 о 23:40 2009-08-13 23:40

У наведеній нижче послідовності команд будуть видалені всі елементи з індексу Git (не з робочого каталогу або локального репо), а потім оновлюється індекс Git, при цьому ігнорується Git. PS. Index = Кеш

По перше:

 git rm -r --cached . git add . 
border=0

тоді:

 git commit -am "Remove ignored files" 
2209
30 сент. відповідь дан Matt Frear 30 вересня. 2013-09-30 16:51 '13 о 16:51 2013-09-30 16:51

git update-index робить всю роботу за мене:

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

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

зміна: так як ця відповідь була опублікована, нова опція була створена, і це повинно бути кращим. Ви повинні використовувати --skip-worktree який призначений для змінених відслідковуються файлів, які користувач більше не хоче фіксувати, і зберігає --assume-unchanged для підвищення продуктивності, щоб git не перевіряв стан великих відслідковуються файлів. Див. medican.site.site/questions/1817 / ... для отримання додаткової інформації ...

 git update-index --skip-worktree <file> 
830
27 нояб. відповідь дан Konstantin 27 нояб. 2013-11-27 14:24 '13 о 14:24 2013-11-27 14:24
 git ls-files --ignored --exclude-standard -z | xargs -0 git rm --cached git commit -am "Remove ignored files" 

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

237
24 мая '14 в 1:29 2014-05-24 01:29 відповідь дан thSoft 24 травня '14 о 1:29 2014-05-24 1:29

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

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

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

62
19 июня '15 в 18:42 2015-06-19 18:42 відповідь дан David Hernandez 19 червня '15 о 18:42 2015-06-19 18:42

Якщо ви не можете 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 / smudge для застосування і видалення змін, наприклад, розмазати файл конфігурації як витяг з альтернативної гілки і очистити файл конфігурації як витяг з HEAD. Це складна штука, я не рекомендую її для початківця користувача.
  • Збережіть файл конфігурації в виділеної для нього гілці розгортання, яка ніколи не буде об'єднана з master. Коли ви хочете розгорнути / скомпілювати / протестувати, ви зливається з цією гілкою і отримуєте цей файл. По суті, це підхід smudge / clean, за винятком використання політик злиття людей і додаткових git-модулів.
  • Антірекомендація: не використовуйте припущення без змін, це закінчиться тільки сльозами (бо помилкова брехня сама по собі може призвести до поганих речей, таким як ваші зміни будуть втрачені назавжди).
53
19 июля '12 в 3:08 2012-07-19 03:08 відповідь дан Seth Robertson 19 липня '12 в 3:08 2012-07-19 3:08

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

51
13 авг. відповідь дан Joel Hooks 13 Серпня. 2009-08-13 22:27 '09 о 22:27 2009-08-13 22:27

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

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 дозволить рекурсивне видалення
  • -Cached буде видаляти тільки файли з індексу. Ваші файли все одно будуть там.

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

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

 git add . 

Крок 4: Зафіксувати

 git commit -m ".gitignore fix" 

Ваш репозиторій чистий :)

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

40
22 апр. відповідь дан Dheeraj Bhaskar 22 Квітня. 2018-04-22 21:11 '18 о 21:11 2018-04-22 21:11

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

(В Linux) я хотів використовувати повідомлення, що пропонують підхід ls-files --ignored --exclude-standard | xargs git rm -r --cached ls-files --ignored --exclude-standard | xargs git rm -r --cached . Однак (деякі з) файлів, які повинні бути видалені, мали вбудовані символи newline / 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 

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

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

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

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

EDIT: мене попросили додати, що --- як і будь-яка команда git rm - за нею повинен слідувати commit, щоб зробити видалення перманентним, наприклад. git commit -am "Remove ignored files" .

38
29 дек. відповідь дан JonBrave 29 дек. 2015-12-29 15:50 '16 о 15:50 2015-12-29 15:50

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

ПОПЕРЕДЖЕННЯ: це призведе до видалення файлу з усієї історії

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

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

35
13 авг. відповідь дан drrlvn 13 Серпня. 2009-08-13 22:35 '09 о 22:35 2009-08-13 22:35
  • Оновлення файл .gitignore - наприклад, додайте папку, в яку ви не хочете відстежувати .gitignore .

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

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


Рада капелюхи @AkiraYamamoto для вказівки в правильному напрямку.

18
04 апр. відповідь дан Chen_Wayne 04 Квітня. 2016-04-04 07:09 '16 о 7:09 2016-04-04 7:09

Я думаю, що, можливо, 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 повинні бути відсутніми. Це рішення підходить для файлів конфігурацій, коли кожен розробник має власну конфігурацію проекту.

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

12
21 мая '17 в 18:12 2017-05-21 18:12 відповідь дан Boolean_Type 21 травня '17 о 18:12 2017-05-21 18:12

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

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

5
19 нояб. відповідь дан youhans 19 нояб. 2018-11-19 14:21 '18 о 14:21 2018-11-19 14:21

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

 # 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 . 
5
25 дек. відповідь дан Ameer Deen 25 дек. 2013-12-25 03:51 '13 в 3:51 2013-12-25 3:51

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

5
13 авг. відповідь дан Apreche 13 Серпня. 2009-08-13 22:27 '09 о 22:27 2009-08-13 22:27

Виконайте наступні кроки по черзі, все буде в порядку.

1. Видаліть помилково додані файли з каталогу / сховища. Ви можете використовувати команду "rm -r" (для linux) або видалити їх, переглядаючи каталоги.

2.add файли / каталоги в файл gitignore і збережіть його.

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

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

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

 git add . git commit -m "removed unnecessary files from git" git push origin 
3
20 сент. відповідь дан Shamsul Arefin Sajib 20 сент. 2018-09-20 13:52 '18 о 13:52 2018-09-20 13:52

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

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

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

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

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

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

3
03 сент. відповідь дан Meir Gerenstadt 03 сент. 2017-09-03 15:37 '17 о 15:37 2017-09-03 15:37

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

git config --global alias.exclude-ignored '! 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 "новий 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" 
  • видалити проігноровані файли з індексу
  • stage.gitignore і файли, які ви тільки що видалили.
  • здійснити
2
08 авг. відповідь дан Jay Irvine 08 Серпня. 2018-08-08 23:49 '18 о 23:49 2018-08-08 23:49

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

2
15 марта '18 в 14:04 2018-03-15 14:04 відповідь дан Pedi T. 15 березня '18 о 14:04 2018-03-15 14:04

Це вже не проблема в останньому 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 
1
13 июня '18 в 19:21 2018-06-13 19:21 відповідь дан Lloyd 13 червня '18 о 19:21 2018-06-13 19:21

У разі вже вчиненого 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 

Нарешті, зробіть фіксацію!

0
23 апр. відповідь дан user7718859 23 Квітня. 2018-04-23 00:14 '18 в 0:14 2018-04-23 00:14

На mac:

 $ git --version git version 2.6.4 $ uname -a Darwin MUSRV186016-382 14.5.0 Darwin Kernel Version 14.5.0: Sun Sep 25 22:07:15 PDT 2016; root:xnu-2782.50.9~1/RELEASE_X86_64 x86_64 

1. Видаліть файли DS_Store зі списку файлів, що відслідковуються git в гілці foo:

 $ for file in $(git ls-tree -r foo --name-only | grep -i DS_Store); do git rm --cached $file; done 

2. Commit:

 $ git commit -m "Removed .DS_Store files" 

3. Перевірте, що файли більше не відслідковуються

 $ git ls-tree -r foo --name-only # There should not be anything coming back 

4. Натисніть, щоб видалити їх з пульта:

 $ git push 
-5
13 янв. відповідь дан Raphvanns 13 Січня. 2017-01-13 22:53 '17 о 22:53 2017-01-13 22:53

Інші питання по мітках або Задайте питання