Thêm đệ quy các tệp theo mẫu


172

Làm cách nào để thêm đệ quy các tệp theo một mẫu (hoặc toàn cầu) nằm trong các thư mục khác nhau?

Ví dụ: tôi muốn thêm A/B/C/foo.javaD/E/F/bar.java(và một số tệp java khác) bằng một lệnh:

git add '*.java'

Thật không may, điều đó không làm việc như mong đợi.


2
Nó hoạt động với tôi (Mac OS X, Git 1.7.1+). Bạn đang sử dụng phiên bản HĐH và Git nào?
Chris Johnsen

3
Nếu bạn có một số .javatệp (đã được theo dõi) trong thư mục hiện tại của mình, bạn có thể đang chạy vào, xử lý ký tự đại diện phức tạp giữa bash và dòng lệnh helper helper dòng msys . Tôi không chắc chắn về một giải pháp. Bạn có thể thử nhiều lớp trích dẫn: git add '"*.java"'(các trích dẫn đơn được lấy bởi bash để ngăn chặn sự mở rộng toàn cầu, các trích dẫn kép được lấy bởi lớp msys để ngăn chặn sự mở rộng toàn cầu).
Chris Johnsen

1
Cảm ơn đã lưu ý. Thật không may, điều đó cũng không hoạt động. Họ nói đã được sửa, nhưng tôi đã có phiên bản mới nhất.
Michel Krämer


1
git add *.javahoạt động với tôi (trên powershell với ứng dụng khách GitHub)
ThaDafinser

Câu trả lời:


88

Câu trả lời của Sergio Acosta có lẽ là đặt cược tốt nhất của bạn nếu một số tệp được thêm vào có thể chưa được theo dõi. Nếu bạn muốn giới hạn bản thân trong các tệp git đã biết, bạn có thể kết hợp git-ls-filesvới bộ lọc:

git ls-files [path] | grep '\.java$' | xargs git add

Git không cung cấp bất kỳ cơ chế ưa thích nào để thực hiện việc này, vì về cơ bản, đây là một vấn đề chính: làm thế nào để bạn có được một danh sách các tệp để cung cấp làm đối số cho một lệnh đã cho.


8
Cảm ơn! Tôi đã cải thiện lệnh của bạn một chút và bây giờ nó đang làm những gì tôi đang tìm kiếm:git ls-files -co --exclude-standard | grep '\.java$' | xargs git add
Michel Krämer

169

Bạn có thể sử dụng git add [path]/\*.javađể thêm các tệp java từ thư mục con,
ví dụ git add ./\*.javacho thư mục hiện tại.

Từ git addtài liệu :

Thêm nội dung từ tất cả *.txtcác tệp trong Documentationthư mục và thư mục con của nó:

$ git add Documentation/\*.txt

Lưu ý rằng dấu hoa thị *được trích dẫn từ shell trong ví dụ này; điều này cho phép lệnh bao gồm các tệp từ thư mục con của thư mục Documentation/.


2
@ MichelKrämer có lẽ là không, nhưng bây giờ là vậy.
Alberto

7
Đây là giải pháp tốt nhất, cũng hoạt động trong windows.
TheTFo

1
"dấu hoa thị * được trích dẫn từ vỏ". Tôi nghĩ bạn có nghĩa là "thoát". Trong mọi trường hợp, dấu gạch chéo ngược ngăn vỏ mở rộng nó.
gwideman

1
@gwideman Tôi nghĩ bạn đúng, nhưng không phải tôi. Đó là trích dẫn từ các tài liệu git-scm.com/docs/git-add#_examples
Sergey Glotov

62

Với zshbạn có thể chạy:

git add "**/*.java"

và tất cả các *.javatập tin của bạn sẽ được thêm đệ quy.


Cảm ơn vì điều đó, nhưng tôi đang làm việc với msysgit trên Windows và nó chỉ có một bash.
Michel Krämer

1
Chà, tôi thấy rằng có một zshcái vỏ cho các cửa sổ ... bạn sẽ tự mình sử dụng nó thay vì bash, imho.
Olivier Verdier

1
Cổng zsh của Windows dựa trên một phiên bản rất cũ và luôn gặp sự cố (ví dụ như khi tôi nhập ls).
Michel Krämer

Wow, hoàn hảo. Tôi không biết về tính năng đó!
Tomáš Votruba

1
Điều này không có gì để làm với zsh. Tôi nghĩ rằng câu trả lời này bỏ lỡ điểm mà bạn muốn vượt qua con đường với các ký tự đại diện còn nguyên vẹn để git và để git xử lý nó. Do đó, bạn muốn ngăn bất kỳ shell nào bạn đang sử dụng để mở rộng (các) ký tự đại diện. Để làm điều này, bạn cần trích dẫn một số cách phù hợp với vỏ bạn đang sử dụng. Xem câu trả lời khác để biết chi tiết.
gwideman

55

Một chút lạc đề (không liên quan cụ thể đến git) nhưng nếu bạn đang dùng linux / unix, một cách giải quyết có thể là:

find . -name '*.java' | xargs git add

Và nếu bạn mong đợi các đường dẫn có khoảng trắng:

find . -name '*.java' -print0 | xargs -0 git add

Nhưng tôi biết đó không phải là chính xác những gì bạn yêu cầu.


6
Vấn đề nhỏ với cách tiếp cận này - nếu bạn "tìm thấy" một tệp phù hợp với .gitignore của bạn thì git phàn nàn rằng bạn đang cố thêm một tệp mà bạn đã nói để bỏ qua.
yoyo

2
@yoyo - Tôi vừa thêm -f vào cuối, và nó đã sửa nó
Maslow

5
@Maslow, điều đó sẽ buộc thêm tệp, mặc dù nó được cho là bị bỏ qua (dựa trên .gitignore). Tôi muốn nhận được khiếu nại và không thêm tệp (đó là hành vi mặc định.)
yoyo

Làm thế nào là điều này tốt hơn là để git thực hiện việc mở rộng ký tự đại diện?
gwideman

12

Câu trả lời của Sergey (không tin tôi) đang hoạt động:

You can use git add [path]/\*.java

với một git gần đây:

$git version
git version 1.7.3.4

Tập tin cho bài kiểm tra:

$find -name .git -prune -o -type f -print | sort
./dirA/dirA-1/dirA-1-1/file1.txt
./dirA/dirA-1/dirA-1-2/file2.html
./dirA/dirA-1/dirA-1-2/file3.txt
./dirA/dirA-1/file4.txt
./dirB/dirB-1/dirB-1-1/file5.html
./dirB/dirB-1/dirB-1-1/file6.txt
./file7.txt

Trạng thái Git:

$git status -s
?? dirA/
?? dirB/
?? file7.txt

Thêm * .txt:

$git add \*.txt

Tình trạng cập nhật:

$git status -s
A  dirA/dirA-1/dirA-1-1/file1.txt
A  dirA/dirA-1/dirA-1-2/file3.txt
A  dirA/dirA-1/file4.txt
A  dirB/dirB-1/dirB-1-1/file6.txt
A  file7.txt
?? dirA/dirA-1/dirA-1-2/file2.html
?? dirB/dirB-1/dirB-1-1/file5.html

8

Nếu bạn đã theo dõi các tệp của mình và đã thực hiện các thay đổi đối với chúng và bây giờ bạn muốn thêm chúng một cách có chọn lọc dựa trên một mẫu, bạn có thể sử dụng --modifiedcờ

git ls-files --modified | grep '<pattern>' | xargs git add

Ví dụ: nếu bạn chỉ muốn thêm các thay đổi CSS vào cam kết này, bạn có thể làm

git ls-files --modified | grep '\.css$' | xargs git add

Xem man git-ls-filesđể biết thêm cờ


5

Chỉ cần sử dụng git add *\*.java. Điều này sẽ thêm tất cả các tệp .java trong thư mục gốc và tất cả các thư mục con.


Câu trả lời chính xác. Tôi đã git add * / pom.xml để thêm tất cả các tên tệp pom.xml.
Philip Rego

4

Thêm một giải pháp dòng lệnh Windows chưa được đề cập:

for /f "delims=" %G in ('dir /b/s *.java') do @git add %G

3

Tôi muốn chỉ thêm các tệp có một chuỗi nhất định dựa trên git status:

git status | grep string | xargs git add

và sau đó có thể git commit -m 'commit msgcam kết tất cả các tệp đã thay đổi bằng "chuỗi" trong tiêu đề của tệp


2

Như đã đề cập trong " git: Làm thế nào để tôi thêm đệ quy tất cả các tệp trong một thư mục con phù hợp với mẫu hình cầu? ", Nếu bạn thoát hoặc trích dẫn chính xác đường dẫn của bạn (như '*.java'), thì có, git add'*.java'

Git 2.13 (Q2 2017) cải thiện điều đó cho add tương tác:

Xem cam kết 7288e12 (14 tháng 3 năm 2017) của Jeff King ( peff) .
(Được hợp nhất bởi Junio ​​C Hamano - gitster- trong cam kết 153e0d7 , ngày 17 tháng 3 năm 2017)

add --interactive: không mở rộng pathspecs với ls-files

Khi chúng tôi muốn lấy danh sách các tệp đã sửa đổi, trước tiên chúng tôi sẽ mở rộng bất kỳ đường dẫn nào do người dùng cung cấp với " ls-files", sau đó cung cấp danh sách đường dẫn kết quả dưới dạng đối số thành " diff-index" và " diff-files".
Nếu pathspec của bạn mở rộng thành một số lượng lớn các đường dẫn, bạn có thể gặp phải một trong hai vấn đề:

  1. HĐH có thể phàn nàn về kích thước của danh sách đối số và từ chối chạy. Ví dụ:

    $ (ulimit -s 128 && git add -p drivers)
    Can't exec "git": Argument list too long at .../git-add--interactive line 177.
    Died at .../git-add--interactive line 177.
    

Đó là trên linux.gitkho lưu trữ, có khoảng 20K tệp trong thư mục "trình điều khiển" (không có tệp nào được sửa đổi trong trường hợp này). Thủ thuật " ulimit -s" là cần thiết để hiển thị vấn đề trên Linux ngay cả đối với một bộ đường dẫn khổng lồ như vậy.
Các hệ điều hành khác có giới hạn nhỏ hơn nhiều (ví dụ: trường hợp trong thế giới thực được nhìn thấy chỉ với 5K tệp trên OS X).

  1. Ngay cả khi nó hoạt động, nó rất chậm. Mã pathspec không được tối ưu hóa cho số lượng lớn đường dẫn. Đây là trường hợp tương tự mà không có ulimit:

    $ time git add -p drivers
      No changes.
    
    real  0m16.559s
    user    0m53.140s
    sys 0m0.220s
    

Chúng ta có thể cải thiện điều này bằng cách bỏ qua " ls-files" hoàn toàn và chỉ cung cấp các đường dẫn gốc cho các lệnh diff.

Trong lịch sử, ngôn ngữ pathspec được hỗ trợ bởi " diff-index" yếu hơn, nhưng đó không còn là vấn đề nữa.


1

đặt dòng trong ~ / .gitconfig

[alias] addt = !sh -c 'git ls-files | grep \"\\.$1*\" | xargs git add' -

Nếu bạn muốn thêm tất cả các tệp java đã sửa đổi, chỉ cần làm: git addt java

Samely, nếu bạn muốn thêm tất cả các tập tin python đã sửa đổi, chỉ có thể làm: git addt py

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.