- Quy tắc bỏ qua tệp trong Git được chia thành ba cấp độ theo phạm vi chia sẻ:
.gitignore, .git/info/exclude, và ~/.config/git/ignore
.gitignore được commit cùng với mã nguồn của kho lưu trữ, nên đây là nơi đặt quy tắc dùng chung mà cả nhóm hoặc dự án cần áp dụng
- Các mục như tệp cá nhân hoặc tệp phục vụ công việc cục bộ, vốn cần trong kho lưu trữ nhưng khó đưa thành quy tắc chung cho cả nhóm, phù hợp hơn khi đặt trong
.git/info/exclude
- Những tệp cần được loại trừ lặp đi lặp lại ở mọi kho lưu trữ, như
.DS_Store trên macOS, có thể được đưa vào ~/.config/git/ignore, tức tệp ignore toàn cục của máy
git check-ignore -v <tên_tệp> hữu ích khi cần lần theo quy tắc nào đang khiến một tệp bị bỏ qua; nếu không có quy tắc khớp thì sẽ không có đầu ra
Vị trí áp dụng quy tắc ignore trong Git
- Git có thể xử lý quy tắc bỏ qua tệp ở ba vị trí
.gitignore
.git/info/exclude
~/.config/git/ignore
.gitignore: quy tắc dùng chung được commit vào kho lưu trữ
.gitignore là tệp thông dụng để ghi tên các tệp cần bỏ qua
- Nó được check in vào Git cùng với phần còn lại của mã nguồn
- Các tệp khớp với quy tắc trong
.gitignore sẽ không được git xem xét khi chạy lệnh
.git/info/exclude: quy tắc cá nhân theo từng kho lưu trữ
- Tệp
exclude nằm trong thư mục .git của mọi kho lưu trữ Git
- Các thay đổi trong tệp này không được check in vào Git
- Trong kho Git mới, tệp này thường chứa vài dòng chú thích
- Nó phù hợp với các tệp bạn chỉ muốn bỏ qua trong riêng kho đó nhưng không muốn đưa vào
.gitignore
- Ví dụ: nếu bạn muốn không commit
notes.txt, vốn chỉ cần cho quy trình làm việc cá nhân, mà cũng không muốn thêm nó vào .gitignore của dự án, hãy thêm notes.txt vào .git/info/exclude
~/.config/git/ignore: quy tắc toàn cục cho máy
- Tệp
ignore toàn cục nằm tại ~/.config/git/ignore trong thư mục home
- Những tên tệp thêm vào đây sẽ bị bỏ qua toàn cục ở cấp máy
- Nó không được check in vào Git và không gắn với kho lưu trữ cụ thể nào
- Đây là nơi phù hợp để đặt các tệp bạn muốn bỏ qua trong mọi kho Git trên máy tính
- Ví dụ: trên macOS, việc thêm
.DS_Store vào đây là phù hợp
Thay đổi đường dẫn tệp ignore toàn cục
- Có thể chỉ định tệp khác làm tệp ignore toàn cục
- Để dùng
.gitignore_global làm tệp Git ignore toàn cục, chạy lệnh sau
git config --global core.excludesFile ~/.gitignore_global
- Để quay lại thiết lập mặc định, chạy lệnh sau
git config --global --unset core.excludesFile
Kiểm tra quy tắc nào đang bỏ qua một tệp
- Có thể dùng
git check-ignore -v <tên_tệp> để kiểm tra một tệp cụ thể đang bị bỏ qua bởi quy tắc nào
- Để kiểm tra
.DS_Store đang bị bỏ qua như thế nào, chạy lệnh sau bên trong kho Git
git check-ignore -v .DS_Store
- Nếu
.gitignore của kho lưu trữ đang bỏ qua .DS_Store, ví dụ đầu ra sẽ như sau
$ git check-ignore -v .DS_Store
.gitignore:1:.DS_Store .DS_Store
- Nếu
.git/info/exclude của kho lưu trữ đang bỏ qua .DS_Store, ví dụ đầu ra sẽ như sau
$ git check-ignore -v .DS_Store
.git/info/exclude:7:.DS_Store .DS_Store
- Nếu tệp
~/.config/git/ignore toàn cục đang bỏ qua .DS_Store, ví dụ đầu ra sẽ như sau
$ git check-ignore -v .DS_Store
/Users/nelson/.config/git/ignore:2:.DS_Store .DS_Store
- Nếu tệp ignore toàn cục tùy chỉnh
.gitignore_global đang bỏ qua .DS_Store, ví dụ đầu ra sẽ như sau
$ git check-ignore -v .DS_Store
/Users/nelson/.gitignore_global:1:.DS_Store .DS_Store
- Nếu không có quy tắc nào bỏ qua một tệp cụ thể, lệnh
git check-ignore -v sẽ không in ra gì
3 bình luận
Có lẽ cũng hữu ích nếu đưa những thứ như đặc tả công việc hoặc tệp
plan.mdvào.git/info/exclude.Thì ra còn có thể thiết lập ở thư mục gốc nữa haha
Ý kiến Hacker News
Bài viết thú vị, nhưng lại thiếu tính năng gần như bỏ qua mà tôi thích nhất trong Git là
.gitattributesVới file này, bạn có thể chỉ định để Git “bỏ qua” phần khác biệt của một số tệp nhất định. Ví dụ, trong dự án Node,
package-lock.jsongần như chỉ là nhiễu nếu nhìn từ góc độ Git. Nó chỉ hiện ra những khác biệt khổng lồ chứa phiên bản cụ thể của thư viện, còn thông tin phiên bản thực sự mà con người dễ đọc thì đã có riêng trongpackage.jsonNếu thêm một dòng
package-lock.json -diffvào.gitattributesở thư mục gốc của dự án, tệp đó vẫn được stage/commit bình thường nhưnggit diffsẽ không còn hiện những thay đổi khổng lồ vô nghĩa nữapackage-lock.jsonkhông nên bị xem là nhiễu. Nếu không định cập nhật có chủ ý thì bạn không nên thay đổi nó, nếu không sẽ tự dưng phơi bày trước rủi ro chuỗi cung ứngNếu thay đổi trong
package-lock.jsonthường xuyên xuất hiện ngoài dự kiến thì chắc chắn là đang làm gì đó saipackage-lock.jsoncho thấy toàn bộ phụ thuộc bắc cầu, cònpackage.jsonchỉ cho thấy phụ thuộc trực tiếp. Vì vậy nói cái sau mới là “phiên bản thật mà con người đọc được” là không đúngHai file này phục vụ mục đích khác nhau, và nói rằng luôn có thể bỏ qua diff của file lock là điều nguy hiểm
git diffkhông hiển thị thay đổi trong file lockTôi hiểu vì sao nó trông giống như nhiễu ở cấp dòng, nhưng lúc cần thì nó thật sự rất cần thiết
Thiết lập loại trừ toàn cục/theo người dùng là tính năng nên được biết đến rộng rãi hơn. Tôi thường nhận các thay đổi muốn thêm file liên quan đến IDE/OS/AI vào
.gitignorecủa mọi dự án, nhưng khi giải thích rằng đưa chúng vào cấu hình chuẩn thì sẽ bị bỏ qua ở mọi nơi, không cần đụng vào từng dự án, và cũng tránh nguy cơ lỡ commit ở những dự án chưa cập nhật.gitignore, thì đa số đều rất thíchNguyên tắc cá nhân của tôi là
.gitignoretrong repository chỉ nên dùng cho các mục riêng của repository như build artifact hay thư mục dependency, còn phần lớn công cụ của người dùng nên nằm trong cấu hình riêng của từng người.gitignoretoàn cục chính là hệ quả tự nhiên của nguyên tắc cho rằng.gitignoretrong repo chỉ nên dùng cho các mục riêng của repoNếu muốn tốn ít thời gian của mọi người hơn thì cứ cho các file đó vào
.gitignorecủa mọi dự án vẫn tốt hơn.gitignorecủa dự án để người thiếu hiểu biết không vô tình thêm chúng vào projectĐằng nào cuối cùng cũng sẽ phải xóa chúng khỏi Git, và người đó sẽ gặp phiền toái, nên tôi chặn trước như một sự tử tế. Có lẽ từ nay tôi sẽ bớt tử tế hơn
gitignorehơn vì nó vẫn tồn tại ngay cả khi rebuild development containerNếu buộc phải tránh
gitignorethì vẫn có thể khôi phục/giữ lại cấu hình bằng script tạo môi trường hoặc volume, nhưng như vậy sẽ cần thêm script hoặc cấu hình mountdevcontainerthay vì chỉ một dòng trong.gitignoreVới cấu hình Git toàn cục và file ignore, tôi nghĩ nên đặt trong
~/.config/git/ignorevà~/.config/git/configthay vì tạo~/.gitignore_globalrồi sửa cấu hìnhNếu tận dụng
~/.config/cho nhiều mục đích thì số lượng dotfile ở cấp thư mục gốc sẽ giảm đi đáng kểLý do Git exclude ít được dùng hơn là vì nó không được commit vào repository, nên mỗi lần muốn dùng lại phải tạo lại. Không phải là nó tệ, chỉ là đó là lý do nó ít phổ biến hơn
~/.configthì về sau sẽ dễ chỉnh sửa và chia sẻ hơn~/.cvsignorecho các công cụ khác dùng cùng loại file đóKhông nhớ đã học ở đâu, nhưng tôi đã thêm
atticvào global Git ignoreNhờ vậy tôi có thể tạo một thư mục
attictrong bất kỳ dự án nào để chứa đủ thứ linh tinh tuyệt đối không nên commit. Đến giờ tôi vẫn chưa thấy repository nào thực sự kiểm tra sự tồn tại của thư mục như vậyNếu có một thư mục như
atticthì bạn có thể tạoattic/.gitignorevà ghi/**, khi đó thư mục đó và mọi thứ bên trong sẽ bị bỏ qua, kể cả chính file ignoreThường thì tôi đặt tên thư mục theo đúng một ký tự U+1F4A9, nhưng HN không cho chèn nó vào bình luận
auxTôi chỉ đặt một
.gitignorechứa đúng một dấu sao*trong đó để ẩn nó đi, thế là chính nó và mọi thứ bên trong đều bị bỏ qua.localscratch/Tới giờ vẫn chưa bị phản tác dụng
Về ignore theo người dùng, với macOS thì thêm
.DS_Storevào đó là lý tưởng, nhưng mọi người dùng Mac trong dự án đều phải làm vậyNếu có từ hai người trở lên thì có thể sẽ tốt hơn nếu không giao cho từng người tự xử lý
.DS_Storetrong file~/.gitignore_global, và trong cấu hình Git toàn cục cũng có thiết lập bỏ qua các mục trong file đóFile này trên máy Mac mới có ngày tạo từ hai ngày trước khi tôi đặt mua máy, và tôi không nhớ là mình đã tự cấu hình, nên có vẻ nó đã có sẵn mặc định. Máy Mac cũ chắc cũng tương tự, và nhìn theo phiên bản macOS thì rất có thể đây đã là mặc định từ khá lâu rồi
Vì vậy có lẽ thời phải thêm
.DS_Store/vào.gitignoregiờ đã qua rồiTrời, sao tôi lại không biết chuyện này nhỉ? Tôi là lập trình viên phần mềm chuyên nghiệp 20 năm mà chỉ toàn dùng
.gitignoreGiờ mới nhận ra là tôi chưa từng tự hỏi liệu có cách nào tốt hơn việc làm rối
.gitignorebằng đủ loại mục loại trừ chỉ liên quan đến riêng mình hay không. Tôi cứ thế chấp nhận thế giới như nó hiện ra trước mắtHôm nay thế giới tốt đẹp hơn một chút rồi
Tôi dùng
.git/info/excluderất nhiều. Nó cực hợp cho script/Makefilechỉ dùng cục bộ, không cần cho cộng tác viên khác hoặc họ cũng không thể dùng đượcgit statusvào.git/info/excludeThường tôi áp dụng nó sau khi
addvàcommitnhững thứ thực sự muốn đưa vào repositoryTôi dùng file excludes như thế này để áp dụng cấu hình Git theo cấp dự án khác nhau cho một thư mục dự án chứa nhiều repository
https://laszlo.nu/blog/project-level-git-config.html
Tôi có một số alias liên quan đang dùng
assume = update-index --assume-unchangedunassume = update-index --no-assume-unchangedassumed = "!git ls-files -v | grep ^h | cut -c 3-"unassumeall = "!git assumed | xargs git update-index --no-assume-unchanged"assumeall = "!git st -s | awk {'print $2'} | xargs git assume"Với các file đã được theo dõi sẵn thì còn có
git update-index --[no]-skip-worktreeNó có thể hữu ích cho thử nghiệm cục bộ, nhưng không phải là tính năng Git hiển thị rõ ràng ở đâu đó nên dùng hơi phiền. Bạn phải nhớ là mình đã bật nó, và nếu quên thì có thể cản trở những thao tác khác như checkout