Як зрабіць 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 не правяраў стан вялікіх адсочваных файлаў. См. lifetop.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 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 адказ дадзены 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 ў 03: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, а затым дадалі іх у свой.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 у 07:09 2016/04/04 07: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 03: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

Іншыя пытанні па пазнаках або Задайце пытанне