Nó được triển khai ngay bây giờ (git 1.9 / 2.0, Q1 2014) với phép thuật pathspec:(exclude)
:!
giới thiệu và dạng rút gọn của nó trong commit ef79b1f và commit 1649612 , bởi
Nguyễn Thái Ngọc Duy ( pclouds
) , có thể tìm thấy tài liệu tại đây .
Giờ đây, bạn có thể ghi lại mọi thứ ngoại trừ nội dung thư mục con:
git log -- . ":(exclude)sub"
git log -- . ":!sub"
Hoặc bạn có thể loại trừ các phần tử cụ thể trong thư mục con đó
một tệp cụ thể:
git log -- . ":(exclude)sub/sub/file"
git log -- . ":!sub/sub/file"
bất kỳ tệp nhất định nào trong sub
:
git log -- . ":(exclude)sub/*file"
git log -- . ":!sub/*file"
git log -- . ":(exclude,glob)sub/*/file"
Bạn có thể không phân biệt chữ hoa chữ thường loại trừ!
git log -- . ":(exclude,icase)SUB"
Như Kenny Evitt đã lưu ý
Nếu bạn đang chạy Git trong Bash shell, hãy sử dụng ':!sub'
hoặc ":\!sub"
thay thế để tránh bash: ... event not found
lỗi
Lưu ý: Git 2.13 (Quý 2 năm 2017) sẽ thêm một từ đồng nghĩa ^
với!
Xem cam kết 859b7f1 , cam kết 42ebeb9 (08/02/2017) bởi Linus Torvalds ( torvalds
) .
(Hợp nhất bởi Junio C Hamano - gitster
- in commit 015fba3 , 27 Feb 2017)
phép thuật pathspec: thêm ' ^
' làm bí danh cho ' !
'
Việc lựa chọn ' !
' cho một pathspec phủ định không chỉ không phù hợp với những gì chúng ta làm cho các bản sửa đổi mà nó còn là một đặc điểm kinh khủng cho việc mở rộng shell vì nó cần trích dẫn.
Vì vậy, hãy thêm ' ^
' làm bí danh thay thế cho mục nhập loại trừ pathspec.
Lưu ý rằng, trước Git 2.28 (Q3 2020), việc sử dụng pathspec phủ định, trong khi thu thập các đường dẫn bao gồm cả các đường dẫn chưa được theo dõi trong cây làm việc, đã bị hỏng.
Xem cam kết f1f061e (05/06/2020) của Elijah Newren ( newren
) .
(Được hợp nhất bởi Junio C Hamano - gitster
- trong cam kết 64efa11 , ngày 18 tháng 6 năm 2020)
dir
: sửa chữa xử lý các pathspec bị phủ định
Người trình bày: John Millikin
Người ký tên: Elijah Newren
do_match_pathspec()
bắt đầu cuộc sống như match_pathspec_depth_1()
và cho sự đúng đắn chỉ được cho là được gọi từ match_pathspec_depth()
. match_pathspec_depth()
sau đó được đổi tên thành match_pathspec()
, vì vậy điều bất biến mà chúng ta mong đợi ngày nay là do_match_pathspec()
không có người gọi trực tiếp bên ngoài match_pathspec()
.
Thật không may, ý định này đã bị mất với việc đổi tên của hai hàm và các lệnh gọi bổ sung do_match_pathspec()
được thêm vào trong các cam kết 75a6315f74 (" ls-files
: thêm đối sánh pathspec cho các mô-đun con", 2016-10-07, Git v2.11.0-rc0 - hợp nhất được liệt kê trong batch # 11 ) và 89a1f4aaf7 (" dir
: nếu pathspec của chúng tôi có thể khớp với các tệp dưới một dir, hãy đệ quy vào nó", 2019-09-17, Git v2.24.0-rc0).
Tất nhiên, do_match_pathspec()
có một lợi thế quan trọng hơn match_pathspec()
- match_pathspec()
sẽ mã hóa cờ thành một trong hai giá trị và những người gọi mới này cần phải chuyển một số giá trị khác cho cờ.
Ngoài ra, mặc dù việc gọi do_match_pathspec()
trực tiếp là không chính xác, có thể không có bất kỳ sự khác biệt nào trong kết quả đầu ra có thể quan sát được, bởi vì lỗi chỉ có nghĩa là nó fill_diretory()
sẽ tái diễn vào các thư mục không cần thiết.
Vì các lần kiểm tra đối sánh đường dẫn này với các đường dẫn riêng lẻ trong thư mục sẽ khiến các đường dẫn phụ đó bị lọc ra, sự khác biệt duy nhất so với việc sử dụng sai hàm là tính toán không cần thiết.
Lần thứ hai trong số những cuộc gọi xấu đó do_match_pathspec()
đã tham gia - thông qua chuyển động trực tiếp hoặc thông qua sao chép + chỉnh sửa - vào một số cơ cấu tái cấu trúc sau này.
Xem cam kết 777b420347 (" dir
: đồng bộ hóa treat_leading_path()
và read_directory_recursive()
", 2019-12-19, Git v2.25.0-rc0 - hợp nhất ), 8d92fb2927 (" dir
: thay thế thuật toán hàm mũ bằng thuật toán tuyến tính", 2020-04-01, Git v2.27.0 -rc0 - hợp nhất được liệt kê trong lô # 5 ) và 95c11ecc73 ("Khắc phục fill_directory()
API dễ xảy ra lỗi ; làm cho nó chỉ trả về các kết quả phù hợp", 2020-04-01, Git v2.27.0-rc0 - hợp nhất được liệt kê trong lô # 5 ) .
Cuối cùng trong số đó đã giới thiệu cách sử dụng do_match_pathspec()
trên một tệp riêng lẻ, và do đó dẫn đến các đường dẫn riêng lẻ được trả về mà không nên.
Vấn đề với việc gọi do_match_pathspec()
thay vì match_pathspec()
là bất kỳ mẫu phủ định nào như '':! Wish_path '' sẽ bị bỏ qua .
Thêm một match_pathspec_with_flags()
chức năng mới để đáp ứng nhu cầu chỉ định các cờ đặc biệt trong khi vẫn kiểm tra chính xác các mẫu bị phủ định, thêm nhận xét lớn ở trên do_match_pathspec()
để ngăn người khác sử dụng sai và sửa những người gọi hiện tại do_match_pathspec()
để thay vào đó sử dụng match_pathspec()
hoặc match_pathspec_with_flags()
.
Một lưu ý cuối cùng là DO_MATCH_LEADING_PATHSPEC
cần đặc biệt cân nhắc khi làm việc với DO_MATCH_EXCLUDE
.
Vấn đề DO_MATCH_LEADING_PATHSPEC
là nếu chúng ta có một pathspec như
*/Makefile
và chúng tôi đang kiểm tra một đường dẫn thư mục như
src/module/component
mà chúng tôi muốn coi nó là một kết quả phù hợp để chúng tôi đệ quy vào thư mục vì nó _might
_ có một tệp có tên Makefile
ở đâu đó bên dưới.
Tuy nhiên, khi chúng ta đang sử dụng một mẫu loại trừ, tức là chúng ta có một pathspec như
:(exclude)*/Makefile
chúng tôi KHÔNG muốn nói rằng một đường dẫn thư mục như
src/module/component
là một trận đấu (phủ định).
Mặc dù có thể có một tệp có tên 'Makefile' ở đâu đó bên dưới thư mục đó, cũng có thể có các tệp khác và chúng tôi không thể loại trừ trước tất cả các tệp trong thư mục đó; chúng ta cần đệ quy và sau đó kiểm tra các tệp riêng lẻ.
Điều chỉnh DO_MATCH_LEADING_PATHSPEC
logic để chỉ được kích hoạt cho các pathspec tích cực.
!f() { git log ... | path/to/filter-log.pl "$@" | git log --stdin --no-walk; f
, hoặc thậm chí bọc phần đường ống đó vào tập lệnh.