gitignore двоичные файлы без расширения


146

Как можно игнорировать двоичные файлы при gitиспользовании .gitignoreфайла?

Пример:

$ g++ hello.c -o hello

Файл «hello» - это двоичный файл. Может gitигнорировать этот файл?



2
Я очень удивлен, что на такой старый и важный вопрос нет правильного ответа. Я еще более удивлен, что ответ прост [^\.]*.
TamaMcGlinn 03

это не работает
timotheecour

Ответы:


143
# 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
Это решение работает как шарм! Я не понимаю, почему, отменив игнорирование всех каталогов "! * /", Он также может отменить игнорирование файлов поддира с расширением? (например, aaa / bbb.c), но все равно игнорировать файл поддиапазона без расширений. (например, aaa / ccc)
dragonxlwang

4
Похоже, что этот метод не работает
должным образом

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

В культуре Unix довольно распространено называть сценарии оболочки, а также двоичные исполняемые файлы без расширений, и в этом случае это решение приведет к игнорированию сценариев. Лучше всего просто добавлять двоичные исполняемые файлы в .gitignore вручную всякий раз, когда они добавляются в проект - обычно это происходит не так часто. Если это слишком громоздко, то лучше использовать makefile, предложенный vedantk.
Питер Хелфер

1
Это игнорирует make-файл
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 / и добавить bin/в свой .gitignore.

В вашем очень конкретном примере с небольшим объемом вы можете просто вставить helloсвой .gitignore.


16

Вы можете попробовать .gitignore:

*
!*.c

У этого подхода много недостатков, но он приемлем для небольших проектов.


3
Было бы неплохо, если бы вы хотя бы перечислили основные недостатки
pjvds 01

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

12

Если вы используете make-файл, вы можете попробовать изменить свои правила make, чтобы добавить имена новых двоичных файлов в ваш файл .gitignore.

Вот пример Makefile для небольшого проекта Haskell;

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

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

Этот make-файл определяет правило для создания исполняемых файлов из кода Haskell. После вызова ghc мы проверяем .gitignore, чтобы увидеть, есть ли в нем двоичный файл. Если это не так, мы добавляем имя двоичного файла в файл.


Теперь это своего рода другой подход.
René Nyffenegger


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

Старая ветка, но все еще актуальная. Я изменил make-файл, чтобы полученный двоичный файл после связывания имел имя [filname]. bin вместо только [filname]. Затем я добавил файлы * .bin в gitignore.
Этот распорядок удовлетворяет мои потребности.


1

Я не знаю другого решения, кроме как добавлять их по одному .gitignore.

Грубый способ проверки - это выполнить grep с выводом команды file:

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

РЕДАКТИРОВАТЬ

Почему бы вам просто не назвать свой исполняемый файл 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.