gitignore tanpa file biner

141

Bagaimana file biner dapat diabaikan dalam gitmenggunakan .gitignorefile?

Contoh:

$ g++ hello.c -o hello

File "halo" adalah file biner. Bisakah gitmengabaikan file ini?

JuanPablo
sumber
2
Saya sangat terkejut dan pertanyaan yang begitu penting tidak memiliki jawaban yang tepat. Saya bahkan lebih terkejut bahwa jawabannya lurus ke depan [^\.]*.
TamaMcGlinn
ini tidak berhasil
timotheecour

Jawaban:

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
VenomVendor
sumber
1
Solusi ini bekerja seperti pesona! Saya tidak mengerti mengapa dengan membatalkan tanda tangan semua dirs "! * /", Ia juga dapat membatalkan tanda tangan file subdir dengan ekstensi? (mis. aaa / bbb.c) tetapi masih mengabaikan file subdir tanpa ekstensi. (mis. aaa / ccc)
dragonxlwang
4
Tampaknya metode ini tidak berfungsi seperti yang diharapkan setelah saya menemukan bahwa ketika ada beberapa lapisan direktori ...
dragonxlwang
@dragonxlwang Saya ingin tahu di mana ini tidak akan berhasil? Solusi yang diterima di sini stackoverflow.com/a/19023985/1426932 sedikit berbeda, dan menggunakan !/**/sebagai ganti !*/; yang mana yang benar? / cc @VonC
timotheecour
Sangat umum dalam budaya Unix untuk memberi nama skrip shell serta executable biner tanpa ekstensi, dalam hal ini solusi ini akan menyebabkan skrip diabaikan. Ide yang lebih baik adalah dengan hanya menambahkan executable biner ke .gitignore secara manual setiap kali mereka ditambahkan ke proyek - biasanya tidak sering terjadi. Jika itu terlalu rumit, maka solusi makefile yang disarankan oleh vedantk lebih baik.
Peter Helfer
Ini akan mengabaikan makefile
VMatrix1900
42

Tambahkan sesuatu seperti

*.o

di file .gitignore dan letakkan di root repo Anda (atau Anda dapat menempatkannya di sub direktori yang Anda inginkan - itu akan berlaku dari level itu di atas) dan memeriksanya.

Edit:

Untuk binari tanpa ekstensi, Anda lebih baik menempatkannya di bin/folder lain. Lagipula tidak ada pengabaian berdasarkan tipe konten.

Anda dapat mencoba

*
!*.*

tapi itu tidak mudah.

manojlds
sumber
1
Menambahkan edit. Apakah ada alasan Anda tidak ingin biner Anda memiliki ekstensi
manojlds
10
Executables sering tidak memiliki ekstensi. Saya mencoba melakukan hal yang sama di sini untuk file yang dibuat dengan gccmelewati -o $@.
Nathan Lilienthal
29

Untuk menambahkan semua file yang dapat dieksekusi ke file Anda .gitignore(yang mungkin Anda maksud dengan "file biner" dilihat dari pertanyaan Anda), Anda dapat menggunakan

find . -executable -type f >>.gitignore

Jika Anda tidak peduli tentang pemesanan baris di Anda .gitignore, Anda juga bisa memperbarui Anda .gitignoredengan perintah berikut yang juga menghapus duplikat dan menjaga pemesanan alfabet tetap utuh.

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

Perhatikan, bahwa Anda tidak dapat mem-pipe output langsung ke .gitignore, karena itu akan memotong file sebelum catmembukanya untuk dibaca. Selain itu, Anda mungkin ingin menambahkan \! -regex '.*/.*/.*'sebagai opsi untuk menemukan jika Anda tidak ingin menyertakan file yang dapat dieksekusi dalam subdirektori.

icks
sumber
23

Taruhan terbaik Anda dengan binari adalah memberi mereka ekstensi yang Anda dapat dengan mudah menyaring dengan pola standar, atau memasukkannya ke direktori yang dapat Anda filter di tingkat direktori.

Saran ekstensi lebih berlaku di Windows, karena ekstensi adalah standar dan pada dasarnya diperlukan, tetapi di Unix, Anda mungkin atau mungkin tidak menggunakan ekstensi pada binari yang dapat dieksekusi. Dalam hal ini, Anda dapat meletakkannya di bin / folder, dan tambahkan bin/ke .gitignore Anda.

Dalam contoh Anda yang sangat spesifik, lingkup kecil, Anda bisa memasukkan hello.gitignore Anda.

Andy White
sumber
15

Anda dapat mencoba di .gitignore:

*
!*.c

Pendekatan ini memiliki banyak kelemahan, tetapi dapat diterima untuk proyek-proyek kecil.

Andrei Beliankou
sumber
3
Akan lebih baik jika Anda paling tidak mencantumkan kerugian utama
pjvds
Kerugian yang jelas adalah urutan aturan allow-deny, cara yang tepat adalah mengabaikan hanya file yang tidak diinginkan, tidak melarang semua dan kemudian hanya memasukkan file yang diinginkan.
Andrei Beliankou
13

Jika Anda menggunakan makefile, Anda bisa mencoba memodifikasi aturan make Anda untuk menambahkan nama-nama binari baru ke file .gitignore Anda.

Berikut ini contoh Makefile untuk proyek kecil Haskell;

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

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

Makefile ini mendefinisikan aturan untuk membuat executable dari kode Haskell. Setelah ghc dipanggil, kami memeriksa .gitignore untuk melihat apakah biner sudah ada di dalamnya. Jika tidak, kami menambahkan nama biner ke file.

vedantk
sumber
Sekarang, ini semacam pendekatan yang berbeda.
René Nyffenegger
5

Berikut ini solusi lain menggunakan file. Dengan cara ini skrip yang dapat dieksekusi tidak akan berakhir di gitignore. Anda mungkin perlu mengubah cara output dari file ditafsirkan agar sesuai dengan sistem Anda. Seseorang kemudian dapat mengatur kait pra-komit untuk memanggil skrip ini setiap kali Anda melakukan.

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)
Tyler Earnest
sumber
Saya membuat skrip yang serupa, dan memposting pertanyaan duplikat: stackoverflow.com/a/28258619/218294 Kode Anda lebih baik :) kode saya mungkin berjalan lebih cepat karena menjalankan "file" hanya sekali, atau beberapa kali (menggunakan xargs).
Sam Watkins
4

Cara untuk mengabaikan di beberapa subdir, tidak hanya di root:

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

Atau, jika Anda hanya ingin memasukkan beberapa jenis file tertentu:

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

Tampaknya itu juga bisa berfungsi seperti untuk setiap subdirektori baru jika Anda mau !:

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

Garis miring penting hanya di dua baris pertama dan opsional di garis lainnya. Tailing slash in !/*/dan !/subdir/juga opsional, tetapi hanya di baris ini.

shaman.sir
sumber
3

Jika Anda mengikuti perintah-perintah ini pada file .gitignore Anda dan file-file tersebut sepertinya masih muncul, Anda mungkin ingin mencoba:

git rm --cached FILENAME

Setelah itu, tambahkan .gitignore Anda, komit, dan tekan. Butuh waktu 40 menit untuk memahami hal itu, semoga ini membantu pemula seperti saya

Shaun Peretz
sumber
2

Utas lama, tetapi masih relevan. Saya mengubah makefile sehingga file biner yang dihasilkan setelah menautkan memiliki nama [nama file]. bin alih-alih hanya [nama file]. Kemudian saya menambahkan file * .bin di gitignore.
Rutinitas ini memenuhi kebutuhan saya.

Nalle Haddock
sumber
1

Saya tidak tahu solusi lain tetapi menambahkannya satu per satu ke .gitignore.

Cara kasar untuk menguji adalah dengan grep output perintah file:

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

EDIT

Mengapa Anda tidak menyebutkan nama Anda yang dapat dieksekusi hello.bin?

muhuk
sumber
Karena penamaan executable dengan ekstensi file .binadalah praktik yang buruk.
MD XF
1

Cukup tambahkan helloatau /helloke .gitignore Anda. Keduanya berfungsi.

Travis Reeder
sumber
Ini juga akan mengabaikan folder bernama hello.
Patrick D'appollonio
0

Saya membuat file .gitignore dengan dua entri di direktori GOPATH.

/bin
/pkg

Itu mengabaikan semua perkembangan yang dikompilasi, saat ini.

gszecsenyi
sumber
0

.gitignore menggunakan pemrograman glob untuk memfilter file, setidaknya di Linux.

Saya akan memberikan ceramah pengkodean di Meetup dan, dalam persiapan, saya membuat direktori dengan beberapa subdirektori yang diberi nama sesuai dengan urutan yang ingin saya presentasikan: 01_subject1, 02_subject2, 03_subject3. Setiap subdirektori berisi file sumber dengan ekstensi yang tergantung pada bahasa yang mengkompilasi ke file yang dapat dieksekusi yang namanya cocok dengan nama file sumber tanpa ekstensi sesuai dengan praktik umum.

Saya mengecualikan file yang dikompilasi dalam direktori awalan angka dengan baris .gitignore berikut:

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

Menurut pemahaman saya tentang dokumentasi, itu tidak akan berhasil. Memiliki tanda bintang tambahan harus gagal karena harus cocok dengan sejumlah karakter yang tidak ditentukan, termasuk '.' + ekstensi. Menghilangkan tanda bintang trailing harus gagal (dan tidak) karena [!\.]hanya cocok dengan karakter non-periode tunggal. Namun, saya menambahkan tanda bintang, seperti yang saya lakukan untuk ekspresi reguler, dan itu berfungsi. Dengan kerja, maksud saya git pemberitahuan perubahan ke file sumber, tetapi tidak ada atau perubahan pada file yang dikompilasi.

chuckj
sumber
0

Membangun jawaban VenomVendors

# Ignore all
*

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

# Unignore Makefiles recursively
!**/Makefile

# other .gitignore rules...
Eero Aaltonen
sumber
0

Tambahkan yang berikut ke file .gitignore Anda:

[^\.]*

Penjelasan:

[] 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"
TamaMcGlinn
sumber
0

The .gitignoreMekanisme bekerja hanya berdasarkan pada file nama , bukan pada file isi . Menjadi file biner adalah properti dari konten, maka Anda tidak dapat meminta git mengabaikan file biner secara langsung, tetapi hanya mengabaikannya dengan nama (dan seperti yang disarankan lainnya, Anda dapat menambahkan semua nama file biner ke file Anda..gitignore atau menggunakan yang sesuai Konvensi penamaan).

Fakta yang .gitignorebekerja pada nama file adalah properti yang penting berdasarkan kinerja: Git hanya perlu membuat daftar file, tetapi tidak membuka dan membacanya untuk mengetahui file mana yang harus diabaikan. Dengan kata lain, Git akan sangat lambat jika Anda bisa memintanya untuk mengabaikan file berdasarkan isinya.

Matthieu Moy
sumber