Как да направя Git "забрави" за файл, който е бил проследен, но сега е в .gitignore?

Има файл, който се проследява от git , но сега файлът е в списъка .gitignore .

Този файл обаче продължава да се показва в git status след неговото редактиране. Как да накараш git напълно да забрави за това?

4082
13 авг. set Иван 13 авг. 2009-08-13 22:23 '09 в 10:23 AM 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 = Cache

На първо място:

 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.info.site/questions/1817 / ... за повече информация ...

 git update-index --skip-worktree <file> 
830
27 нояб. отговорът е даден на Константин 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 01: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 Отговорът беше даден от Дейвид Ернандес на 19.06.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 magic, за да приложите и премахнете промените, например размазване на конфигурационния файл като извлечение от алтернативен клон и изчистване на конфигурационния файл като извлечение от HEAD. Това е трудно нещо, не го препоръчвам на начинаещ потребител.
  • Запазете конфигурационния файл в неговия специален клон за внедряване, който никога няма да бъде обединен с главния. Когато искате да разположите / компилирате / тествате, слеете с този клон и ще получите този файл. По същество това е подходът на зацапване / чист, с изключение на използването на политики за сливане на хора и допълнителни модули git.
  • Анти-препоръчител: не използвайте предположения без промени, той ще завърши само със сълзи (защото фалшивата лъжа сама по себе си може да доведе до лоши неща, като промените ви ще бъдат загубени завинаги).
53
19 июля '12 в 3:08 2012-07-19 03:08 Отговорът е даден от Сет Робъртсън на 19 юли 2012 г. в 3:08 ч. 2012-07-19 03: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 и след това ги добавили към your.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 . Въпреки това (някои от) файловете, които трябва да бъдат изтрити, съдържат нови знаци / 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-файлове , а аргументът -0 използва xargs за безопасно / правилно използване за "лоши" символи в имената на файловете.

Ръчната страница на git-ws-files (1) гласи:

Ако опцията -z не се използва, символите TAB, LF и обратната наклонена черта в пътеките се представят съответно, n и \ t

така че мисля, че решението ми е необходимо, ако имената на файлове съдържат някой от тези знаци.

EDIT: Бях помолен да добавя, че - като всяка git rm команда - трябва да бъде последвано от ангажиране , например, за да се направи премахването трайно. git commit -am "Remove ignored files" .

38
29 дек. Отговорът е даден от JonBrave на 29 декември. 2015-12-29 15:50 '16 в 15:50 2015-12-29 15:50

Направих това с помощта на клона на филтъра . Точната команда, която използвах, бе взета от man страницата:

ВНИМАНИЕ : това ще изтрие файла от цялата история.

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

Тази команда пресъздава цялата история на git rm като изпълнява git rm преди всяко поемане и по този начин разполага с посочения файл. Не забравяйте да направите резервно копие, преди да изпълните командата, тъй като тя ще бъде загубена.

35
13 авг. отговорът е даден drrlvn 13 aug. 2009-08-13 22:35 '09 в 10: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 07:09

Мисля, че може би git не може напълно да забрави за файла поради своята концепция ( раздела "Изображения, а не разлика" ).

Този проблем липсва например при използването на CVS. CVS съхранява информацията като списък с промени, базирани на файлове. Информация за CVS е колекция от файлове и промени, направени във всеки файл във времето.

Но в git всеки път, когато правите или запазвате състоянието на вашия проект, той всъщност прави снимка на това как изглеждат всичките ви файлове в момента и съхранява връзка към тази снимка, така че ако веднъж сте добавили файл, винаги е ще присъства в тази снимка.

Тези 2 статии бяха полезни за мен:

git поема - няма промяна срещу пропускане и как да се игнорират промените в проследявани файлове с помощта на 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 в 6:12 2017-05-05 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 скрипт за тези, които само за 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 03:51

Преместете или копирайте файла на безопасно място, така че да не го изгубите. Тогава git rm файл и ангажирайте. Файлът ще се покаже, ако се върнете към някоя от тези предишни корекции, или към друг клон, където той не е бил изтрит. Въпреки това във всички бъдещи корекции няма да видите файла отново. Ако файлът е в 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-more-than"

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

Ако искате да укажете файлове по име, можете да направите и това:

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

BFG е с 10-1000 пъти по-бърз от Git филтъра и обикновено е много по-лесен за използване - проверете инструкциите за пълна употреба и примери за повече подробности.

Източник: https://confluence.atlassian.com/bitbucket/reduce-repository-size-321848262.html

3
03 сент. Отговор, даден от Меир Геренштадт 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 - игнорира --exclude-standard | xargs -0 git rm -r --cached git ls-files -z - игнорира --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 , той има действието "Delete (save local)" в менюто, което работи добре.

2
15 марта '18 в 14:04 2018-03-15 14:04 Отговорът е даден от Педи Т. 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. Извършване на ангажимент:

 $ 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 Jan 13 2017-01-13 22:53 '17 в 10:53 2017-01-13 22:53

Други въпроси относно таговете или Задайте въпрос