web-dev-qa-db-fra.com

gitignore sans fichiers binaires

Comment les fichiers binaires peuvent-ils être ignorés dans git en utilisant le fichier .gitignore fichier?

Exemple:

$ g++ hello.c -o hello

Le fichier "hello" est un fichier binaire. Est-ce que git peut ignorer ce fichier?

126
JuanPablo
# Ignore all
*

# Unignore all with extensions
!*.*

# Unignore all dirs
!*/

### Above combination will ignore all files without extension ###

# Ignore files with extension `.class` & `.sm`
*.class
*.sm

# Ignore `bin` dir
bin/
# or
*/bin/*

# Unignore all `.jar` in `bin` dir
!*/bin/*.jar

# Ignore all `library.jar` in `bin` dir
*/bin/library.jar

# Ignore a file with extension
relative/path/to/dir/filename.extension

# Ignore a file without extension
relative/path/to/dir/anotherfile
109
VenomVendor

Ajouter quelque chose comme

*.o

dans le fichier .gitignore et placez-le à la racine de votre référentiel (ou vous pouvez placer dans n'importe quel sous-répertoire de votre choix - il s'appliquera à partir de ce niveau) et archivez-le.

Modifier:

Pour les binaires sans extension, il est préférable de les placer dans bin/ ou un autre dossier. Après tout, il n'y a pas d'ignor basé sur le type de contenu.

Tu peux essayer

*
!*.*

mais ce n'est pas infaillible.

40
manojlds

Pour ajouter tous les exécutables à votre .gitignore (que vous entendez probablement par "fichier binaire" à en juger par votre question), vous pouvez utiliser

find . -executable -type f >>.gitignore

Si vous ne vous souciez pas de commander des lignes dans votre .gitignore, vous pouvez également mettre à jour votre .gitignore avec la commande suivante qui supprime également les doublons et maintient intact l'ordre alphabétique.

T=$(mktemp); (cat .gitignore; find . -executable -type f | sed -e 's%^\./%%') | sort | uniq >$T; mv $T .gitignore

Notez que vous ne pouvez pas diriger directement la sortie vers .gitignore, car cela tronquerait le fichier avant que cat ne l’ouvre en lecture. Aussi, vous voudrez peut-être ajouter \! -regex '.*/.*/.*' comme une option à rechercher si vous ne souhaitez pas inclure de fichiers exécutables dans des sous-répertoires.

26
icks

Votre meilleur choix avec les fichiers binaires consiste à leur attribuer une extension que vous pouvez facilement filtrer avec un modèle standard ou à les placer dans des répertoires que vous pouvez filtrer au niveau du répertoire.

La suggestion d'extension est plus applicable dans Windows, car les extensions sont standard et généralement nécessaires, mais sous Unix, vous pouvez utiliser ou non des extensions sur vos fichiers binaires exécutables. Dans ce cas, vous pouvez les mettre dans un dossier/bin et ajouter bin/ à votre .gitignore.

Dans votre exemple très spécifique, de petite portée, vous pouvez simplement mettre hello dans votre .gitignore.

23
Andy White

Vous pouvez essayer dans votre .gitignore:

*
!*.c

Cette approche présente de nombreux inconvénients, mais elle est acceptable pour les petits projets.

14
Andrei Beliankou

Si vous utilisez un fichier Make, vous pouvez essayer de modifier vos règles de création pour ajouter les noms des nouveaux fichiers binaires à votre fichier .gitignore.

Voici un exemple de Makefile pour un petit projet Haskell;

all: $(patsubst %.hs, %, $(wildcard *.hs))

%: %.hs
    ghc $^
    grep -xq "$@" .gitignore || echo $@ >> .gitignore

Ce fichier make définit une règle pour la création d’exécutables à partir de code Haskell. Une fois que ghc est appelé, nous vérifions le fichier .gitignore pour voir si le binaire y est déjà. Si ce n'est pas le cas, nous ajoutons le nom du fichier binaire au fichier.

12
vedantk

Voici une autre solution en utilisant le fichier. De cette façon, les scripts exécutables ne se retrouveront pas dans gitignore. Vous devrez peut-être modifier la façon dont la sortie du fichier est interprétée pour correspondre à votre système. Vous pouvez ensuite configurer un hook de pré-validation pour appeler ce script chaque fois que vous validez.

import subprocess, os

git_root = subprocess.check_output(['git', 'root']).decode("UTF-8").strip()
exes = []
cut = len(git_root)

for root, dirnames, filenames in os.walk(git_root+"/src/"):
  for fname in filenames:
    f = os.path.join(root,fname)
    if not os.access(f,os.X_OK):
      continue

    ft = subprocess.check_output(['file', f]).decode("UTF-8")

    if 'ELF' in ft and 'executable' in ft:
      exes.append(f[cut:])

gifiles = [ str.strip(a) for a in open(git_root + "/.gitignore").readlines() ]
gitignore=frozenset(exes+gifiles)

with open(git_root+"/.gitignore", "w") as g:
  for a in sorted(gitignore):
    print(a, file=g)
4
Tyler Earnest

Les fichiers binaires sont souvent sans extension. Si c'est votre cas, essayez ceci:

*
!/**/
!*.*

REF: https://stackoverflow.com/a/19023985/1060487

4
mattdlockyer

Une manière d'ignorer également dans un sous-répertoire, pas seulement dans une racine:

# Ignore everything in a root
/*
# But not files with extension located in a root
!/*.*
# And not my subdir (by name)
!/subdir/
# Ignore everything inside my subdir on any level below
/subdir/**/*
# A bit of magic, removing last slash or changing combination with previous line
# fails everything. Though very possibly it just says not to ignore sub-sub-dirs.
!/subdir/**/
# ...Also excluding (grand-)children files having extension on any level
# below subdir
!/subdir/**/*.*

Ou, si vous souhaitez inclure uniquement certains types de fichiers spécifiques:

/*
!/*.c
!/*.h
!/subdir/
/subdir/**/*
!/subdir/**/
!/subdir/**/*.c
!/subdir/**/*.h

Il semble que cela puisse même fonctionner comme pour chaque nouveau sous-répertoire si vous le souhaitez!:

/*
!/*.c
!/*.h
!/*/
/*/**/*
!/*/**/
!/*/**/*.c
!/*/**/*.h

Les barres obliques sont importantes uniquement dans les deux premières lignes et facultatives dans les autres. Tailing slash in !/*/ et !/subdir/ est également facultatif, mais uniquement dans cette ligne.

3
shaman.sir

Si vous suivez ces commandes sur votre fichier .gitignore et que les fichiers semblent toujours apparaître, essayez de:

git rm --cached FILENAME

Après cela, ajoutez votre .gitignore, commit et Push. Il m'a fallu 40 minutes pour comprendre cela, j'espère que cela aidera les débutants comme moi

1
Shaun Peretz

Vieux fil, mais toujours d'actualité. J'ai changé le fichier make pour que le fichier binaire résultant après la liaison porte le nom [nom du fichier] .bin au lieu de seulement [nom du fichier]. Ensuite, j'ai ajouté des fichiers * .bin dans gitignore.
Cette routine répond à mes besoins.

1
Nalle Haddock

Je ne connais pas d'autre solution que de les ajouter un à un à .gitignore.

Une méthode grossière pour tester consiste à grep la sortie de la commande de fichier:

find . \( ! -regex '.*/\..*' \) -type f | xargs -n 1 file | egrep "ASCII|text"

EDIT

Pourquoi ne vous nommez-vous pas simplement votre exécutable hello.bin?

1
muhuk

Ajoutez simplement hello ou /hello à votre .gitignore. Soit fonctionne.

1
Travis Reeder

Construire sur réponse de VenomVendors

# Ignore all
*

# Unignore all files with extensions recursively
!**/*.*

# Unignore Makefiles recursively
!**/Makefile

# other .gitignore rules...
0
Eero Aaltonen

J'ai créé un fichier .gitignore avec deux entrées dans le répertoire GOPATH.

/bin
/pkg

Il ignore tous les développements compilés, actuellement.

0
gszecsenyi

Le mécanisme .gitignore Ne fonctionne que sur le fichier noms, pas sur le fichier conten. Être un fichier binaire est une propriété du contenu, vous ne pouvez donc pas demander à git d’ignorer les fichiers binaires directement, mais seulement de les ignorer par leur nom (et comme suggéré, vous pouvez soit ajouter tous les noms de fichiers binaires à votre .gitignore ou utilisez une convention de dénomination appropriée).

Le fait que .gitignore Fonctionne sur les noms de fichiers est une propriété importante du point de vue des performances: Git n'a besoin que de répertorier les fichiers, mais pas de les ouvrir et de les lire pour savoir quels fichiers ignorer. En d'autres termes, Git serait terriblement lent si vous pouviez lui demander d'ignorer les fichiers en fonction de leur contenu.

0
Matthieu Moy

.gitignore utilise programmation globale pour filtrer les fichiers, du moins sous Linux.

Je suis sur le point de parler de codage lors d’une réunion et, en préparation, j’ai créé un répertoire avec plusieurs sous-répertoires nommés selon l’ordre dans lequel je souhaite les présenter: 01_subject1, 02_subject2, 03_subject3. Chaque sous-répertoire contient un fichier source avec une extension dépendante de la langue qui est compilée en un fichier exécutable dont le nom correspond au nom du fichier source sans l'extension, conformément à la pratique courante.

J'exclus les fichiers compilés dans les répertoires préfixés par des nombres avec la ligne .gitignore suivante:

[0-9][0-9]_*/[!\.]*

Selon ma compréhension de la documentation, cela ne devrait pas fonctionner. L'astérisque de fin doit échouer car il doit correspondre à un nombre quelconque de caractères non spécifiés, y compris le '.' + extension. L'omission de l'astérisque de fin devrait échouer (et échoue) car [!\.] ne correspond qu'à un seul caractère non-périodique. Cependant, j'ai ajouté l'astérisque de fin, comme je le ferais pour une expression régulière, et cela fonctionne. Par travail, j'entends que git remarque les modifications apportées au fichier source, mais pas l'existence ni les modifications apportées aux fichiers compilés.

0
chuckj

Ajoutez les éléments suivants à votre fichier .gitignore:

[^\.]*

Explication:

[] encloses a character class, e.g. [a-zA-Z] means "any letter".
^  means "not"
\. means a literal dot - without the backslash . means "any character"
*  means "any number of these characters"
0
TamaMcGlinn