Как двоичные файлы можно игнорировать в git
с помощью файла .gitignore
?
Пример:
$ g++ hello.c -o hello
Файл hello - это двоичный файл. Может ли git
игнорировать этот файл?
Как двоичные файлы можно игнорировать в git
с помощью файла .gitignore
?
Пример:
$ g++ hello.c -o hello
Файл hello - это двоичный файл. Может ли git
игнорировать этот файл?
# 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
Добавьте что-то вроде
*.o
в файле .gitignore и поместите его в корень вашего репо (или вы можете поместить его в любой подкаталог, который вы хотите - он будет применяться с этого уровня) и проверьте его.
Edit:
Для двоичных файлов без расширения вам лучше разместить их в bin/
или в какой-либо другой папке. Afterall игнорируется на основе типа содержимого.
Вы можете попробовать
*
!*.*
но это не является надежным.
Чтобы добавить все исполняемые файлы к вашему .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 '.*/.*/.*'
в качестве опции, чтобы узнать, не хотите ли вы включать исполняемые файлы в подкаталоги.
Лучше всего использовать двоичные файлы, чтобы либо предоставить им расширение, которое можно легко отфильтровать с помощью стандартного шаблона, либо поместить его в каталоги, которые вы можете отфильтровать на уровне каталогов.
Предложение расширения больше применимо в Windows, поскольку расширения являются стандартными и в основном необходимы, но в Unix вы можете или не можете использовать расширения в исполняемых двоичных файлах. В этом случае вы можете поместить их в папку bin/и добавить bin/
в свой .gitignore.
В вашем очень конкретном примере с малой областью вы можете просто положить hello
в свой .gitignore.
Вы можете попробовать в .gitignore
:
*
!*.c
Этот подход имеет много недостатков, но он подходит для небольших проектов.
Если вы используете make файл, вы можете попробовать изменить свои правила make, чтобы добавить имена новых двоичных файлов в ваш файл .gitignore.
Вот пример Makefile для небольшого проекта Haskell;
all: $(patsubst %.hs, %, $(wildcard *.hs))
%: %.hs
ghc $^
grep -xq "[email protected]" .gitignore || echo [email protected] >> .gitignore
Этот make файл определяет правило для создания исполняемых файлов из кода Haskell. После вызова ghc мы проверяем .gitignore, чтобы узнать, находится ли в нем двоичный файл. Если это не так, мы добавим имя двоичного файла в файл.
Здесь другое решение, использующее файл. Таким образом, исполняемые скрипты не окажутся в gitignore. Возможно, вам придется изменить способ интерпретации вывода из файла в соответствии с вашей системой. Затем можно было бы создать привязку для предварительной фиксации для вызова этого script каждый раз, когда вы совершаете фиксацию.
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)
Способ также игнорировать в некотором субдире не только в корне:
# 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
Ведущие косые черты важны только в первых двух строках и необязательно в других. Сокращение косой черты в !/*/
и !/subdir/
также необязательно, но только в этой строке.
Я не знаю другого решения, но добавляю их один за другим до .gitignore
.
Грубый способ тестирования состоит в том, чтобы grep выводить команду файла:
find . \( ! -regex '.*/\..*' \) -type f | xargs -n 1 file | egrep "ASCII|text"
ИЗМЕНИТЬ
Почему бы вам просто не назвать исполняемый файл hello.bin
?
Просто добавьте hello
или /hello
к вашему .gitignore. Либо работает.
Бинарные файлы часто без расширений. Если это ваш случай, попробуйте это:
*
!/**/
!*.*
Старая тема, но все еще актуальна. Я изменил make файл, чтобы получившийся двоичный файл после ссылки имел имя [filname]. bin вместо только [filname]. Затем я добавил *.bin файлы в gitignore.
Эта рутина выполняет мои потребности.
Я создал файл .gitignore с двумя записями в каталоге GOPATH.
/bin
/pkg
В настоящее время игнорируется все скомпилированные разработки.
.gitignore использует glob programming для фильтрации файлов, по крайней мере, в Linux.
Я собираюсь поговорить о кодировании на Meetup, и в процессе подготовки я создал каталог с несколькими подкаталогами, которые названы в соответствии с порядком, который я хочу представить: 01_subject1, 02_subject2, 03_subject3. Каждый подкаталог содержит исходный файл с зависимым от языка расширением, который компилируется в исполняемый файл, имя которого совпадает с именем исходного файла без расширения в соответствии с обычной практикой.
Я исключаю скомпилированные файлы в числовые префиксные каталоги со следующей строкой .gitignore:
[0-9][0-9]_*/[!\.]*
По моему пониманию документации, он не должен работать. Наличие конечной звездочки должно завершиться неудачно, потому что оно должно соответствовать любому количеству неуказанных символов, включая '.' + расширение. Опускание конечной звездочки должно завершиться неудачно (и делает), потому что [!\.]
соответствует только одному непериодическому символу. Тем не менее, я добавил трейлинг-звездочку, как и для обычного выражения, и она работает. По работе я имею в виду, что git уведомляет об изменениях в исходном файле, но не о существовании или изменениях в скомпилированных файлах.
Опираясь на VenomVendors ответ
# Ignore all
*
# Unignore all files with extensions recursively
!**/*.*
# Unignore Makefiles recursively
!**/Makefile
# other .gitignore rules...
Добавьте следующее в ваш файл .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"
Механизм .gitignore
работает только на основе имен файлов, а не на их содержимом. Наличие двоичного файла является свойством содержимого, поэтому вы не можете попросить git игнорировать двоичные файлы напрямую, а только игнорировать их по имени (и, как предлагают другие, вы можете либо добавить все имена двоичных файлов в свой .gitignore
либо использовать соответствующее соглашение об именах).
Тот факт, что .gitignore
работает с именами файлов, является важным свойством производительности: Git нужно только перечислять файлы, но не открывать и читать их, чтобы знать, какие файлы игнорировать. Другими словами, Git будет очень медленным, если вы попросите его игнорировать файлы на основе их содержимого.
Если вы выполните эти команды в своем файле .gitignore, а файлы все еще появляются, вы можете попробовать:
git rm --cached FILENAME
После этого добавьте свой .gitignore, совершите коммит и нажмите. Мне понадобилось 40 минут, чтобы понять это, надеюсь, это поможет новичкам, таким как я