Zoeken…


Invoering

Dit onderwerp illustreert hoe te voorkomen dat ongewenste bestanden (of bestandswijzigingen) worden toegevoegd aan een Git-repo. Er zijn verschillende manieren (globaal of lokaal .gitignore , .git/exclude , git update-index --assume-unchanged en git update-index --skip-tree ), maar houd in gedachten dat Git inhoud beheert, wat betekent: negeren negeert eigenlijk de inhoud van een map (bijv. bestanden). Een lege map wordt standaard genegeerd, omdat deze toch niet kan worden toegevoegd.

Bestanden en mappen negeren met een .gitignore-bestand

Je kunt Git bepaalde bestanden en mappen laten negeren - dat wil zeggen ze uitsluiten van het volgen door Git - door een of meer .gitignore bestanden in je repository te maken.

In softwareprojecten bevat .gitignore meestal een lijst met bestanden en / of mappen die tijdens het .gitignore of tijdens runtime worden gegenereerd. Vermeldingen in het .gitignore bestand kunnen namen of paden bevatten die verwijzen naar:

  1. tijdelijke bronnen zoals caches, logbestanden, gecompileerde code, enz.
  2. lokale configuratiebestanden die niet met andere ontwikkelaars mogen worden gedeeld
  3. bestanden die geheime informatie bevatten, zoals inlogwachtwoorden, sleutels en inloggegevens

Wanneer de regels worden gemaakt in de map op het hoogste niveau, zijn ze recursief van toepassing op alle bestanden en submappen in de hele repository. Wanneer de regels in een submap worden gemaakt, zijn de regels van toepassing op die specifieke map en de submappen.

Wanneer een bestand of map wordt genegeerd, is dit niet:

  1. gevolgd door Git
  2. gerapporteerd door commando's zoals git status of git diff
  3. geënsceneerd met opdrachten zoals git add -A

In het ongewone geval dat u bijgehouden bestanden moet negeren, moet u extra voorzichtig zijn. Zie: Negeer bestanden die al zijn vastgelegd in een Git-repository .


Voorbeelden

Hier zijn een aantal generieke voorbeelden van regels in een .gitignore bestand, gebaseerd op glob file patronen :

# Lines starting with `#` are comments.

# Ignore files called 'file.ext'
file.ext

# Comments can't be on the same line as rules!
# The following line ignores files called 'file.ext # not a comment'
file.ext # not a comment 

# Ignoring files with full path.
# This matches files in the root directory and subdirectories too.
# i.e. otherfile.ext will be ignored anywhere on the tree.
dir/otherdir/file.ext
otherfile.ext

# Ignoring directories
# Both the directory itself and its contents will be ignored.
bin/
gen/

# Glob pattern can also be used here to ignore paths with certain characters.
# For example, the below rule will match both build/ and Build/
[bB]uild/

# Without the trailing slash, the rule will match a file and/or
# a directory, so the following would ignore both a file named `gen`
# and a directory named `gen`, as well as any contents of that directory
bin
gen

# Ignoring files by extension
# All files with these extensions will be ignored in
# this directory and all its sub-directories.
*.apk
*.class

# It's possible to combine both forms to ignore files with certain
# extensions in certain directories. The following rules would be
# redundant with generic rules defined above.
java/*.apk
gen/*.class

# To ignore files only at the top level directory, but not in its
# subdirectories, prefix the rule with a `/`
/*.apk
/*.class

# To ignore any directories named DirectoryA 
# in any depth use ** before DirectoryA
# Do not forget the last /, 
# Otherwise it will ignore all files named DirectoryA, rather than directories
**/DirectoryA/
# This would ignore 
# DirectoryA/
# DirectoryB/DirectoryA/ 
# DirectoryC/DirectoryB/DirectoryA/
# It would not ignore a file named DirectoryA, at any level

# To ignore any directory named DirectoryB within a 
# directory named DirectoryA with any number of 
# directories in between, use ** between the directories
DirectoryA/**/DirectoryB/
# This would ignore 
# DirectoryA/DirectoryB/ 
# DirectoryA/DirectoryQ/DirectoryB/ 
# DirectoryA/DirectoryQ/DirectoryW/DirectoryB/

# To ignore a set of files, wildcards can be used, as can be seen above.
# A sole '*' will ignore everything in your folder, including your .gitignore file.
# To exclude specific files when using wildcards, negate them.
# So they are excluded from the ignore list:
!.gitignore 

# Use the backslash as escape character to ignore files with a hash (#)
# (supported since 1.6.2.1)
\#*#

De meeste .gitignore bestanden zijn standaard in verschillende talen, dus om te beginnen, hier is een aantal voorbeeld .gitignore bestanden die zijn gerangschikt per taal van waaruit ze naar uw project moeten klonen of kopiëren / wijzigen. Als alternatief kunt u voor een nieuw project overwegen een startbestand automatisch te genereren met behulp van een online tool .


Andere vormen van .gitignore

.gitignore bestanden zijn bedoeld om te worden .gitignore als onderdeel van de repository. Als u bepaalde bestanden wilt negeren zonder de negeerregels te gebruiken, zijn hier enkele opties:

  • Bewerk het .git/info/exclude bestand (met dezelfde syntaxis als .gitignore ). De regels zullen algemeen zijn in het bereik van de repository;
  • Stel een globaal gitignore-bestand in dat negeerregels zal toepassen op al uw lokale repositories:

Verder kun je lokale wijzigingen in bijgehouden bestanden negeren zonder de globale git-configuratie te wijzigen met:

  • git update-index --skip-worktree [<file>...] : voor kleine lokale aanpassingen
  • git update-index --assume-unchanged [<file>...] : voor productie gereed, niet-veranderende bestanden stroomopwaarts

Zie meer details over verschillen tussen de laatste vlaggen en de git update-index documentatie voor verdere opties.


Genegeerde bestanden opschonen

Je kunt git clean -X om genegeerde bestanden op te git clean -X :

git clean -Xn #display a list of ignored files
git clean -Xf #remove the previously displayed files

Opmerking: -X (hoofdletters) ruimt alleen genegeerde bestanden op. Gebruik -x (geen hoofdletters) om ook niet-bijgehouden bestanden te verwijderen.

Zie de git clean documentatie voor meer details.


Zie de Git-handleiding voor meer details.

Uitzonderingen in een .gitignore-bestand

Als u bestanden negeert met behulp van een patroon maar uitzonderingen hebt, moet u een uitroepteken (!) Voor de uitzondering plaatsen. Bijvoorbeeld:

*.txt
!important.txt

In het bovenstaande voorbeeld wordt Git geïnstrueerd om alle bestanden met de extensie .txt te negeren, behalve de bestanden met de naam important.txt .

Als het bestand in een genegeerde map staat, kunt u het NIET zo gemakkelijk opnieuw opnemen:

folder/
!folder/*.txt

In dit voorbeeld blijven alle .txt-bestanden in de map genegeerd.

De juiste manier is om de map zelf opnieuw op te nemen op een afzonderlijke regel en vervolgens alle bestanden in de folder negeren op * , ten slotte de *.txt in de folder , als volgt:

!folder/
folder/*
!folder/*.txt

Opmerking : voeg voor bestandsnamen die met een uitroepteken beginnen twee uitroeptekens toe of ontsnap met het \ -teken:

!!includethis
\!excludethis

Een globaal .gitignore-bestand

Om Git bepaalde bestanden in alle repositories te laten negeren, kun je een globale .gitignore maken met de volgende opdracht in je terminal of opdrachtprompt:

$ git config --global core.excludesfile <Path_To_Global_gitignore_file>

Git zal dit nu gebruiken naast het eigen .gitignore- bestand van elke repository. Regels hiervoor zijn:

  • Als het lokale .gitignore bestand expliciet een bestand bevat terwijl de globale .gitignore negeert, heeft de lokale .gitignore prioriteit (het bestand wordt opgenomen)
  • Als de repository op meerdere machines wordt gekloond, moet de globale .gigignore op alle machines worden geladen of op zijn minst worden opgenomen, omdat de genegeerde bestanden naar de repo worden gepusht, terwijl de pc met de globale .gitignore deze niet zou bijwerken . Dit is de reden waarom een repo-specifieke .gitignore een beter idee is dan een wereldwijd idee als het project door een team wordt bewerkt

Dit bestand is een goede plek om platform-, machine- of gebruikersspecifieke .DS_Store te bewaren, bijv. OSX .DS_Store , Windows Thumbs.db of Vim *.ext~ en *.ext.swp negeert als je die niet in de repository wilt houden . Dus een teamlid dat werkt met OS X kan alle .DS_STORE en _MACOSX (wat eigenlijk nutteloos is), terwijl een ander teamlid op Windows alle thumbs.bd kan negeren.

Negeer bestanden die al zijn toegewezen aan een Git-repository

Als je al een bestand hebt toegevoegd aan je Git-repository en nu wilt stoppen met het volgen ervan (zodat het in toekomstige commits niet aanwezig zal zijn), kun je het uit de index verwijderen:

git rm --cached <file>

Dit zal het bestand uit de repository verwijderen en voorkomen dat verdere wijzigingen worden gevolgd door Git. De optie --cached zorgt ervoor dat het bestand niet fysiek wordt verwijderd.

Merk op dat eerder toegevoegde inhoud van het bestand nog steeds zichtbaar is via de Git-geschiedenis.

Houd er rekening mee dat als iemand anders uit de repository haalt nadat u het bestand uit de index heeft verwijderd, zijn kopie fysiek wordt verwijderd .


Je kunt Git doen doen alsof de versie van de werkmap van het bestand up-to-date is en in plaats daarvan de indexversie lezen (waardoor wijzigingen daarin worden genegeerd) met het bit " werktijd overslaan ":

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

Het schrijven wordt niet beïnvloed door dit bit, inhoudveiligheid is nog steeds de eerste prioriteit. Je zult nooit je kostbare genegeerde veranderingen verliezen; aan de andere kant conflicteert dit bit met stashing: gebruik dit om dit bit te verwijderen

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

Het wordt soms ten onrechte aanbevolen om tegen Git te liegen en ervan uit te gaan dat het bestand ongewijzigd is zonder het te onderzoeken. Het ziet er op het eerste gezicht uit als het negeren van verdere wijzigingen aan het bestand, zonder het uit de index te verwijderen:

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

Dit zal git dwingen om elke wijziging in het bestand te negeren (houd er rekening mee dat als je wijzigingen in dit bestand ophaalt, of je stopt het, je genegeerde wijzigingen verloren gaan )

Als je wilt dat git dit bestand weer "verzorgt", voer je de volgende opdracht uit:

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

Controleren of een bestand wordt genegeerd

Het git check-ignore commando rapporteert over bestanden die door Git worden genegeerd.

Je kunt bestandsnamen doorgeven op de opdrachtregel en git check-ignore zal de bestandsnamen weergeven die worden genegeerd. Bijvoorbeeld:

$ cat .gitignore
*.o
$ git check-ignore example.o Readme.md
example.o

Hier zijn alleen * .o-bestanden gedefinieerd in .gitignore, dus Readme.md wordt niet vermeld in de uitvoer van git check-ignore .

Als je de regel wilt zien waarvan .gitignore verantwoordelijk is voor het negeren van een bestand, voeg je -v toe aan de opdracht git check-ignore:

$ git check-ignore -v example.o Readme.md
.gitignore:1:*.o        example.o

Vanaf Git 1.7.6 kun je ook de git status --ignored gebruiken om genegeerde bestanden te zien. Meer informatie hierover vindt u in de officiële documentatie of in Zoeken naar bestanden die zijn genegeerd door .gitignore .

Bestanden in submappen negeren (meerdere gitignore-bestanden)

Stel dat u een repositorystructuur als deze heeft:

examples/
    output.log
src/
    <files not shown>
    output.log
README.md

output.log in de voorbeeldenmap is geldig en vereist voor het project om inzicht te krijgen terwijl degene onder src/ tijdens het debuggen is gemaakt en niet in de geschiedenis of een deel van de repository zou moeten staan.

Er zijn twee manieren om dit bestand te negeren. U kunt een absoluut pad in het .gitignore bestand in de hoofdmap van de werkmap plaatsen:

# /.gitignore
src/output.log

U kunt ook een .gitignore bestand maken in de src/ directory en het bestand negeren dat relatief is aan deze .gitignore :

# /src/.gitignore
output.log

Een bestand in een willekeurige map negeren

Om een bestand foo.txt in een willekeurige map te negeren, moet u gewoon de naam ervan schrijven:

foo.txt # matches all files 'foo.txt' in any directory

Als u het bestand alleen in een deel van de boom wilt negeren, kunt u de submappen van een specifieke map met ** patroon opgeven:

bar/**/foo.txt # matches all files 'foo.txt' in 'bar' and all subdirectories

Of u kunt een .gitignore bestand maken in de bar/ map. Gelijk aan het vorige voorbeeld zou het maken van een bestandsbalk bar/.gitignore met deze inhoud:

foo.txt # matches all files 'foo.txt' in any directory under bar/

Negeer bestanden lokaal zonder regels te negeren

.gitignore negeert bestanden lokaal, maar het is bedoeld om te worden .gitignore in de repository en gedeeld met andere bijdragers en gebruikers. U kunt een globale .gitignore , maar dan zouden al uw repositories die instellingen delen.

Als je bepaalde bestanden in een repository lokaal wilt negeren en het bestand geen deel van een repository wilt maken, bewerk dan .git/info/exclude in je repository.

Bijvoorbeeld:

# these files are only ignored on this repo
# these rules are not shared with anyone
# as they are personal                                              
gtk_tests.py
gui/gtk/tests/*
localhost
pushReports.py
server/

Voorgevulde .gitignore-sjablonen

Als u niet zeker weet welke regels u in uw .gitignore bestand moet opnemen, of als u gewoon algemeen geaccepteerde uitzonderingen aan uw project wilt toevoegen, kunt u een .gitignore bestand kiezen of genereren:

Veel hostingservices zoals GitHub en BitBucket bieden de mogelijkheid om .gitignore bestanden te genereren op basis van de programmeertalen en IDE's die u mogelijk gebruikt:

GitHub .gitignore dropdown

Volgende wijzigingen aan een bestand negeren (zonder het te verwijderen)

Soms wil je een bestand in Git hebben, maar negeer volgende wijzigingen.

Laat Git wijzigingen in een bestand of map negeren met behulp van update-index :

git update-index --assume-unchanged my-file.txt

De bovenstaande opdracht geeft Git de opdracht om aan te nemen dat my-file.txt niet is gewijzigd en om wijzigingen niet te controleren of te rapporteren. Het bestand is nog steeds aanwezig in de repository.

Dit kan handig zijn om standaardwaarden te bieden en lokale omgevingsoverschrijvingen mogelijk te maken, bijvoorbeeld:

# create a file with some values in
cat <<EOF
MYSQL_USER=app
MYSQL_PASSWORD=FIXME_SECRET_PASSWORD
EOF > .env

# commit to Git
git add .env
git commit -m "Adding .env template"

# ignore future changes to .env
git update-index --assume-unchanged .env

# update your password
vi .env

# no changes!
git status

Slechts een deel van een bestand negeren [stub]

Soms wilt u misschien lokale wijzigingen in een bestand dat u niet wilt vastleggen of publiceren. Idealiter zouden lokale instellingen moeten worden geconcentreerd in een afzonderlijk bestand dat in .gitignore kan worden geplaatst, maar soms als een oplossing op korte termijn kan het nuttig zijn om iets lokaal in een ingecheckt bestand te hebben.

Je kunt Git die regels "onzichtbaar maken" met een schoon filter. Ze zullen niet eens in diffs verschijnen.

Stel dat hier een fragment uit bestand file1.c :

struct settings s;
s.host = "localhost";
s.port = 5653;
s.auth = 1;
s.port = 15653; // NOCOMMIT
s.debug = 1; // NOCOMMIT
s.auth = 0; // NOCOMMIT

U wilt NOCOMMIT regels nergens publiceren.

Maak een "nocommit" -filter door dit toe te voegen aan het Git-configuratiebestand zoals .git/config :

[filter "nocommit"]
    clean=grep -v NOCOMMIT

Voeg dit toe (of maak dit) aan .git/info/attributes of .gitmodules :

file1.c filter=nocommit

En je NOCOMMIT-regels zijn verborgen voor Git.

Voorbehoud:

  • Het gebruik van een schone filter vertraagt de verwerking van bestanden, vooral op Windows.
  • De genegeerde regel kan uit het bestand verdwijnen wanneer Git deze bijwerkt. Het kan worden tegengegaan met een veegfilter, maar het is lastiger.
  • Niet getest op Windows

Negeren van wijzigingen in bijgehouden bestanden. [stomp]

.gitignore en .git/info/exclude werk uitsluiten alleen voor niet-bijgehouden bestanden.

Gebruik de opdracht update-index om de vlag voor het negeren van een bijgehouden bestand in te stellen:

git update-index --skip-worktree myfile.c

Om dit terug te zetten, gebruik:

git update-index --no-skip-worktree myfile.c

Je kunt dit fragment toevoegen aan je globale git-configuratie om handiger git hide , git unhide en git hidden opdrachten te hebben:

[alias]
    hide   = update-index --skip-worktree
    unhide = update-index --no-skip-worktree
    hidden  = "!git ls-files -v | grep ^[hsS] | cut -c 3-"

U kunt ook de optie --assume-ongewijzigd met de update-indexfunctie gebruiken

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

Gebruik als u dit bestand opnieuw wilt bekijken voor de wijzigingen

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

Wanneer de vlag --assume-ongewijzigd is opgegeven, belooft de gebruiker het bestand niet te wijzigen en laat Git aan dat het werkende boombestand overeenkomt met wat is opgenomen in de index. Git zal mislukken in het geval dat dit bestand in de index moet worden gewijzigd bijv. bij het samenvoegen van een commit; dus in het geval dat het veronderstelde niet-bijgehouden bestand stroomopwaarts wordt gewijzigd, moet u de situatie handmatig verwerken. De nadruk ligt in dit geval op de prestaties.

Hoewel de vlag --skip-worktree nuttig is wanneer je git instrueert nooit een specifiek bestand aan te raken omdat het bestand lokaal zal worden gewijzigd en je niet per ongeluk de wijzigingen wilt doorvoeren (dat wil zeggen configuratie / eigenschappenbestand geconfigureerd voor een bepaald milieu). Skip-worktree heeft voorrang op veronderstellen-onveranderd wanneer beide zijn ingesteld.

Wis al vastgelegde bestanden, maar opgenomen in .gitignore

Soms gebeurt het dat een bestand werd bijgehouden door git, maar op een later tijdstip werd toegevoegd aan .gitignore, om te stoppen met het volgen. Het is een veel voorkomend scenario om dergelijke bestanden op te ruimen voordat ze worden toegevoegd aan .gitignore. In dit geval blijft het oude bestand rondhangen in de repository.

Om dit probleem op te lossen, zou men een "dry-run" verwijdering van alles in de repository kunnen uitvoeren, gevolgd door het opnieuw toevoegen van alle bestanden. Zolang u geen openstaande wijzigingen heeft en de parameter --cached is doorgegeven, is deze opdracht redelijk veilig om uit te voeren:

# Remove everything from the index (the files will stay in the file system) 
$ git rm -r --cached .

# Re-add everything (they'll be added in the current state, changes included)
$ git add .

# Commit, if anything changed. You should see only deletions
$ git commit -m 'Remove all files that are in the .gitignore'

# Update the remote
$ git push origin master

Maak een lege map

Het is niet mogelijk om een lege map in Git toe te voegen en te plegen vanwege het feit dat Git bestanden beheert en hun map eraan toevoegt, wat commits afslankt en de snelheid verbetert. Om dit te omzeilen, zijn er twee methoden:

Methode één: .gitkeep

Een hack om dit te omzeilen is om een .gitkeep bestand te gebruiken om de map voor Git te registreren. Maak hiervoor de gewenste map en voeg een .gitkeep bestand toe aan de map. Dit bestand is leeg en heeft geen ander doel dan alleen het registreren van de map. Om dit te doen in Windows (die lastige bestandsnaamconventies heeft) open je git bash in de map en voer je de opdracht uit:

$ touch. gitkeep

Met deze opdracht maakt u gewoon een leeg .gitkeep bestand in de huidige map

Methode twee: dummy.txt

Een andere hack hiervoor lijkt erg op het bovenstaande en dezelfde stappen kunnen worden gevolgd, maar in plaats van een .gitkeep , gebruik gewoon een dummy.txt . Dit heeft de toegevoegde bonus dat het gemakkelijk in Windows kan worden gemaakt met behulp van het contextmenu. En je kunt er ook grappige berichten in achterlaten. Je kunt ook het .gitkeep bestand gebruiken om de lege map bij te houden. .gitkeep normaal gesproken een leeg bestand dat wordt toegevoegd om de lege directoy te volgen.

Zoeken naar bestanden genegeerd door .gitignore

Je kunt alle bestanden die door git worden genegeerd in de huidige map weergeven met de opdracht:

git status --ignored

Dus als we een repository-structuur hebben zoals deze:

.git
.gitignore
./example_1
./dir/example_2
./example_2

... en .gitignore bestand met:

example_2

... dan is het resultaat van de opdracht:

$ git status --ignored

On branch master

Initial commit

Untracked files:
  (use "git add <file>..." to include in what will be committed)

.gitignore
.example_1

Ignored files:
  (use "git add -f <file>..." to include in what will be committed)

dir/
example_2

Als u recursief genegeerde bestanden in mappen wilt weergeven, moet u een extra parameter gebruiken - --untracked-files=all

Resultaat ziet er als volgt uit:

$ git status --ignored --untracked-files=all
On branch master

Initial commit

Untracked files:
  (use "git add <file>..." to include in what will be committed)

.gitignore
example_1

Ignored files:
  (use "git add -f <file>..." to include in what will be committed)

dir/example_2
example_2


Modified text is an extract of the original Stack Overflow Documentation
Licentie onder CC BY-SA 3.0
Niet aangesloten bij Stack Overflow