Apa perbedaan antara Git mengabaikan direktori dan direktori / *?

108

Saya bingung tentang cara apa yang benar untuk mengabaikan konten direktori di git.

Asumsikan saya memiliki struktur direktori berikut:

my_project  
     |--www  
         |--1.txt  
         |--2.txt
     |--.gitignore

Apa perbedaan antara meletakkan ini:

www

Dan ini?

www/*

Alasan saya menanyakan pertanyaan ini adalah: Dalam git, jika direktori kosong, git tidak akan menyertakan direktori kosong tersebut dalam repositori. Jadi saya mencoba solusi yaitu menambahkan file .gitkeep ekstra di bawah direktori sehingga tidak akan kosong. Ketika saya mencoba solusi itu, jika di file .gitignore, saya menulis seperti di bawah ini:

www
!*.gitkeep

Itu tidak berhasil (Tujuan saya adalah mengabaikan semua konten di bawah www tetapi simpan direktori). Tetapi jika saya mencoba yang berikut:

www/* 
!*.gitkeep

Kemudian berhasil! Jadi saya pikir itu pasti memiliki beberapa perbedaan antara kedua pendekatan tersebut.

Aaron Shen
sumber
Perbedaan sederhana antara bindan bin/adalah bahwa yang pertama akan mengabaikan file atau folder, yang terakhir hanya folder. Saya tidak tahu bedanya denganbin/*
Kolonel Panic

Jawaban:

203

Ada perbedaan antara www, www/dan www/*.

Pada dasarnya dari dokumentasi dan tes saya sendiri, wwwtemukan yang cocok dengan file atau direktori, www/hanya cocok dengan direktori, sedangkan www/*cocok dengan direktori dan file di dalamnya www.

Saya hanya akan membahas tentang perbedaan antara www/dan di www/*sini, karena perbedaan antara wwwdan www/sudah jelas.

Karena www/, git mengabaikan direktori wwwitu sendiri, yang berarti git tidak akan melihat ke dalam. Tetapi untuk www/*, git memeriksa semua file / folder di dalamnya www, dan mengabaikan semuanya dengan pola *. Tampaknya mengarah ke hasil yang sama karena git tidak akan melacak folder kosong wwwjika semua file / folder turunannya diabaikan. Dan memang hasilnya tidak akan ada perbedaan untuk kasus OP dengan www/atau www/*standalone. Tetapi akan membuat perbedaan jika digabungkan dengan aturan lain.

Misalnya, bagaimana jika kita hanya ingin memasukkan www/1.txttetapi mengabaikan semua yang lain di dalamnya www?

Berikut .gitignoreini tidak akan berhasil.

www/
!www/1.txt

Sementara berikut ini .gitignoreberhasil, mengapa?

www/*
!www/1.txt

Untuk yang pertama, git mengabaikan direktori www, dan tidak akan melihat ke dalam untuk memasukkannya www/1.txtlagi. Aturan pertama mengecualikan direktori indukwww tetapi tidak www/1.txt, dan akibatnya www/1.txttidak dapat " disertakan lagi ".

Tetapi untuk yang terakhir, git pertama-tama mengabaikan semua file / folers di bawah www, dan kemudian memasukkan salah satunya lagi yaitu www/1.txt.

Untuk contoh ini, baris berikut dalam dokumentasi dapat membantu:

Awalan opsional "!" yang meniadakan pola; file apa pun yang cocok yang dikecualikan oleh pola sebelumnya akan disertakan lagi. Tidak mungkin untuk memasukkan kembali file jika direktori induk dari file itu dikecualikan.

Landys
sumber
Tidakkah Anda berpikir bahwa www/1.txtdan kemudian www/akan melakukan hal yang sama dengan pendekatan kedua ...
Naveed Butt
8

Saya hanya memilah-milah dokumentasi, dan sejauh yang saya tahu mereka hanya berbeda dalam pola yang lebih maju, mis

$ cat .gitignore
    # exclude everything except directory foo/bar
    /*
    !/foo
    /foo/*
    !/foo/bar

Saya melakukan tes di atas, dan jika Anda menggantinya !/foodengan !/foo/*, Anda memang mendapatkan hasil yang berbeda.

Catatan

foo

Akan mengecualikan file apa pun foo, tetapi

foo/

hanya akan mengecualikan direktori bernama foo.

djechlin.dll
sumber
3

Terlepas dari jawaban yang sangat bagus yang telah Anda peroleh, Anda harus mencatat bahwa Anda dapat memiliki .gitignoredi mana saja dalam proyek Anda, termasuk subfolder.

Jadi jika Anda ingin mengabaikan semua file di dalamnya www, tetapi ingin wwwfolder diversi, alih-alih menggunakan kosong .gitkeep, .dummyatau nama apa pun yang Anda pilih, mengapa tidak menggunakan di .gitignoresana, menyuruh untuk mengabaikan semua file?

/
|- .gitignore   (a)
\- www
    |- .gitignore   (b)
    |- 1.jpg
    \- 2.jpg

Di root .gitignore(a), Anda tidak mengatakan apa pun tentang wwwfolder atau isinya.

Di www/.gitignore(b) Anda memasukkan yang berikut:

# ignore all files in this folder except this .gitignore
*
!.gitignore

Dengan cara ini semuanya terlihat lebih terorganisir (setidaknya bagi saya).

Carlos Campderrós
sumber
1

Untuk mengabaikan semua yang ada di direktori kecuali dotfiles, Anda dapat menggunakan pola-glob berikut di .gitignore:

www/[^.]*

Jadi tidak perlu tambahan .gitignore, cukup tambahkan .keepfile ke wwwdirektori Anda .

Koen.
sumber