gitignore без бінарних файлів


141

Як можна ігнорувати бінарні файли при gitвикористанні .gitignoreфайлу?

Приклад:

$ g++ hello.c -o hello

Файл "привіт" - це двійковий файл. Можна gitігнорувати цей файл?



2
Я дуже здивований, на таке старе і важливе питання немає належної відповіді. Я ще більше здивований, що відповідь - це прямо [^\.]*.
TamaMcGlinn

це не працює
timotheecour

Відповіді:


136
# 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

1
Це рішення працює як шарм! Я не розумію, чому unignore всі dirs "! * /", Він також може ігнорувати файли subdir з розширенням? (наприклад, aaa / bbb.c), але все ж ігнорують файл subdir без розширень. (наприклад, aaa / ccc)
dragonxlwang

4
Здається, що цей метод працює не так, як очікувалося після того, як я виявив, що в декількох шарах каталогу ...
dragonxlwang

@dragonxlwang Мені цікаво, де б це не працювало? Тут прийняте рішення stackoverflow.com/a/19023985/1426932 дещо інше, і використовує !/**/замість нього !*/; який з них правильний? / cc @VonC
timotheecour

У культурі Unix досить часто називати скрипти оболонки, а також двійкові виконувані файли без розширень; в цьому випадку це рішення призведе до ігнорування сценаріїв. Краща ідея - просто додати бінарні виконувані файли для .gitignore вручну кожного разу, коли вони додаються до проекту - зазвичай це відбувається не так часто. Якщо це занадто громіздко, то краще рішення для makefile, запропоноване vedantk.
Пітер Хелфер

Це ігнорує makefile
VMatrix1900

42

Додайте щось подібне

*.o

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

Редагувати:

Для бінарних файлів без розширення краще розмістити їх у bin/будь-якій іншій папці. Якщо не існує ігнору на основі типу вмісту.

Ви можете спробувати

*
!*.*

але це не дурно.


1
Додано редагування. Чи є причина, що ви не хочете, щоб ваш бінарний файл мав розширення
manojlds

10
Виконані файли часто не мають розширень. Я намагаюся зробити те саме, що і для файлів, створених при gccпроходженні -o $@.
Натан Ліліенталь

29

Щоб додати до себе всі виконувані файли .gitignore(що ви, мабуть, маєте на увазі під "двійковим файлом", судячи з вашого запитання), ви можете використовувати

find . -executable -type f >>.gitignore

Якщо вас не хвилює впорядкування рядків у вашому .gitignore, ви також можете оновити свою .gitignoreкоманду за допомогою наступної команди, яка також видаляє дублікати та зберігає впорядкованість за алфавітом.

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

Зауважте, що ви не можете передавати безпосередньо вихід .gitignore, тому що це вріже файл перед catвідкриттям його для читання. Також ви можете додати \! -regex '.*/.*/.*'як опцію, щоб знайти, якщо ви не хочете включати виконувані файли у підкаталоги.


23

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

Пропозиція щодо розширення більш застосовна в Windows, тому що розширення стандартні і в основному потрібні, але в Unix ви можете або не можете використовувати розширення на своїх виконуваних бінарних файлах. У цьому випадку ви можете помістити їх у бін / папку та додати bin/до свого .gitignore.

У вашому дуже конкретному, helloмаломасштабному прикладі ви можете просто ввести .gitignore.


15

Ви можете спробувати у своєму .gitignore:

*
!*.c

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


3
Було б чудово, якщо ви хоч би перерахували основні недоліки
pjvds

Очевидним недоліком є ​​порядок дозволу заборонити правила, правильний спосіб - ігнорувати лише небажані файли, не забороняти всі, а потім включати лише бажані файли.
Андрій Белянкуу

13

Якщо ви використовуєте makefile, ви можете спробувати змінити свої правила make, щоб додати імена нових бінарних файлів у файл .gitignore.

Ось приклад Makefile для невеликого проекту Haskell;

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

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

Цей makefile визначає правило для створення виконуваних файлів з коду Haskell. Після виклику ghc ми перевіряємо .gitignore, щоб перевірити, чи є в ньому вже двійковий файл. Якщо це не так, ми додаємо до файлу назву двійкового файлу.


Зараз це такий собі інший підхід.
Рене Ніффенеггер


5

Ось ще одне рішення за допомогою файлу. Таким чином виконувані сценарії не опиняться в gitignore. Можливо, вам доведеться змінити, як інтерпретується вихідний файл з відповідності вашій системі. Потім ви можете встановити гачок, що попередньо здійснює, для виклику цього сценарію кожного разу, коли ви здійснюєте їх виконання.

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)

Я зробив подібний скрипт і розмістив на дублюючому запитанні: stackoverflow.com/a/28258619/218294 Ваш код приємніший :) мій, ймовірно, працює швидше, оскільки він запускає "файл" лише один раз або кілька разів (використовуючи xargs).
Сем Уоткінс

4

Спосіб також ігнорувати в деякому підкаталозі, не тільки в корені:

# 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/**/*.*

Або якщо ви хочете включити лише деякі певні типи файлів:

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

Здається, це може навіть працювати як для кожного нового підкаталогу, якщо ви хочете !:

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

Провідні косої риси важливі лише в перших двох рядках і необов’язкові в інших. Tailing слеш в !/*/і !/subdir/також є необов'язковим, але тільки в цьому рядку.


3

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

git rm --cached FILENAME

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


2

Стара нитка, але все ще актуальна. Я змінив makefile, щоб отриманий бінарний файл після посилання мав назву [filename]. бін замість лише [назва фільму]. Потім я додав * .bin файли в gitignore.
Ця рутина відповідає моїм потребам.


1

Я не знаю жодного іншого рішення, але додавання їх по одному до .gitignore.

Грубий спосіб тестування - зібрати результат файлової команди:

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

EDIT

Чому ви просто не назвете його виконуваним hello.bin?


Тому що називати виконувані файли з розширенням файлів .bin- це погана практика.
MD XF


0

Я створив файл .gitignore з двома записами в каталозі GOPATH.

/bin
/pkg

Він ігнорує всі складені розробки на даний момент.


0

.gitignore використовує глобальне програмування для фільтрації файлів, принаймні в Linux.

Я збираюся виступити з розмовою про кодування на Meetup, і під час підготовки я створив каталог з кількома підкаталогами, які названі відповідно до порядку, який я хочу їх представити: 01_subject1, 02_subject2, 03_subject3. Кожен підкаталог містить вихідний файл із залежним від мови розширенням, який компілюється у виконуваний файл, ім'я якого відповідає імені вихідного файла без розширення відповідно до загальної практики.

Я виключаю компільовані файли з каталогів з попередньою цифрою із наступним рядком .gitignore:

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

Наскільки я розумію документацію, вона не повинна працювати. Наявність відмітки зосередження має бути невдалою, оскільки вона має відповідати будь-якій кількості невизначених символів, включаючи "." + розширення. Опущення задніх зірочок має бути невдалим (і так), оскільки [!\.]відповідає лише одному неперіодичному символу. Однак я додав зірочку, як і для звичайного виразу, і вона працює. Під роботою я маю на увазі, що git помічає зміни у вихідному файлі, але не існування чи зміни у складених файлах.



0

Додайте до файлу .gitignore:

[^\.]*

Пояснення:

[] 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

.gitignoreМеханізм працює тільки на основі файлів імен , а нема на файл вмісту . Бути бінарним файлом є властивістю вмісту, отже, ви не можете просити git ігнорувати бінарні файли безпосередньо, а лише ігнорувати їх по імені (і як інше пропонується, ви можете або додати всі назви бінарних файлів до свого .gitignoreабо використовувати відповідне іменування конвенції).

Те, що .gitignoreпрацює з іменами файлів, є важливим для продуктивності властивості: Git потрібно лише перелічити файли, але не відкривати їх та читати, щоб знати, які файли ігнорувати. Іншими словами, Git був би дуже повільним, якби ви могли попросити його ігнорувати файли на основі їх вмісту.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.