패턴별로 파일을 재귀 적으로 추가


172

다른 디렉토리에있는 패턴 (또는 glob)별로 파일을 재귀 적으로 추가하려면 어떻게합니까?

예를 들어, 하나의 명령으로 A/B/C/foo.javaD/E/F/bar.java(및 다른 여러 Java 파일) 을 추가 하고 싶습니다 .

git add '*.java'

불행히도, 그것은 예상대로 작동하지 않습니다.


2
그것은 나를 위해 작동합니다 (Mac OS X, Git 1.7.1+). 어떤 OS 및 Git 버전을 사용하고 있습니까?
Chris Johnsen

3
.java현재 디렉토리에 일부 (이미 추적 된) 파일이있는 경우 bash 와 msys 명령 줄 "helper" 사이에 복잡한 와일드 카드 처리 가 실행될 수 있습니다 . 해결책이 확실하지 않습니다. 따옴표의 여러 레이어를 시도 할 수 있습니다 git add '"*.java"'. 작은 따옴표는 glob 확장을 방지하기 위해 bash 에 의해 사용 되며 큰 따옴표는 glob 확장을 방지하기 위해 msys 레이어에서 가져옵니다.
Chris Johnsen

1
메모 주셔서 감사합니다. 불행히도, 그것은 작동하지 않습니다. 그들은 수정되었다고 말하지만 이미 최신 버전을 가지고 있습니다.
Michel Krämer


1
git add *.java나를 위해 일합니다 (GitHub 클라이언트의 powershell에서)
ThaDafinser

답변:


89

추가 할 파일 중 일부가 아직 추적되지 않은 경우 Sergio Acosta의 답변이 가장 좋습니다. git 이미 알고있는 파일로 자신을 제한하려면 git-ls-files필터와 결합 할 수 있습니다 .

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

Git은 기본적으로 쉘 문제이기 때문에이 작업을 수행하는 멋진 메커니즘을 제공하지 않습니다. 주어진 명령에 인수로 제공 할 파일 목록을 얻는 방법은 무엇입니까?


8
감사! 나는 당신의 명령을 약간 개선했고 지금은 내가 찾고있는 것을하고 있습니다 :git ls-files -co --exclude-standard | grep '\.java$' | xargs git add
Michel Krämer

169

git add [path]/\*.java하위 디렉토리에서 Java 파일을 추가 하는 데 사용할 수 있습니다 (
예 : git add ./\*.java현재 디렉토리).

에서 git add문서 :

디렉토리 및 해당 서브 디렉토리 *.txt아래의 모든 파일에서 컨텐츠를 추가합니다 Documentation.

$ git add Documentation/\*.txt

*이 예에서 별표 는 쉘에서 인용됩니다. 이를 통해 명령은 디렉토리의 서브 디렉토리에있는 파일을 포함 할 수 있습니다 Documentation/.


2
@ MichelKrämer는 아닐 수도 있지만 지금은 그렇지 않습니다.
Alberto

7
이것은 최상의 솔루션이며 Windows에서도 작동합니다.
TheTFo

1
"별표 *는 쉘에서 인용됩니다". "탈출"을 의미한다고 생각합니다. 어쨌든 백 슬래시는 쉘이 확장되지 않도록합니다.
gwideman

1
@gwideman 나는 당신이 옳다고 생각하지만 그것은 내가 아닙니다. git-scm.com/docs/git-add#_examples
Sergey Glotov

62

zsh당신 과 함께 실행할 수 있습니다 :

git add "**/*.java"

모든 *.java파일이 재귀 적으로 추가됩니다.


고마워하지만 Windows에서 msysgit로 작업하고 있으며 bash 만 있습니다.
Michel Krämer

1
글쎄, 나는 zsh창문을 위한 껍질 이 있다는 것을 알았다 ... 당신은 bash 대신 imho를 사용하는 것이 좋다.
Olivier Verdier

1
zsh의 Windows 포트는 매우 오래된 버전을 기반으로하며 항상 충돌합니다 (예 : 입력시 ls).
Michel Krämer

와, 완벽 해 나는 그 기능에 대해 몰랐다!
Tomáš Votruba

1
이것은 zsh와 관련이 없습니다. 이 답변은 와일드 카드로 경로를 전달하여 git에 그대로 전달하고 git가 처리하도록하려는 요점을 놓친 것 같습니다. 따라서 사용중인 쉘이 와일드 카드를 확장하지 못하게하려고합니다. 이렇게하려면 사용중인 쉘에 적합한 방식으로 인용해야합니다. 자세한 내용은 다른 답변을 참조하십시오.
gwideman

55

약간 벗어난 주제 (특히 git 관련 아님)이지만 Linux / unix를 사용하는 경우 해결 방법은 다음과 같습니다.

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

공백이있는 경로가 예상되는 경우 :

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

그러나 나는 그것이 당신이 요구 한 것이 아니라는 것을 알고 있습니다.


6
이 접근법의 사소한 문제-.gitignore와 일치하는 파일을 "찾기"하면 git은 무시하도록 지시 한 파일을 추가하려고한다고 불평합니다.
yoyo

2
@yoyo-나는 방금 끝에 -f를 추가했고 그 문제를 해결했다
Maslow

5
@Maslow, 파일을 무시해야하지만 강제로 파일을 추가합니다 (.gitignore 기반). 불만 사항을 접수하고 파일 (기본 동작)을 추가하지 않는 것이 좋습니다.
yoyo

git이 와일드 카드 확장을 수행하게하는 것보다 어떻게 더 나은가요?
gwideman

12

Sergey의 답변 (나를 신용하지 마십시오)이 효과가 있습니다.

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

최근 자식으로 :

$git version
git version 1.7.3.4

테스트 용 파일 :

$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

힘내 상태 :

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

* .txt 추가 :

$git add \*.txt

업데이트 된 상태 :

$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

이미 파일을 추적하고 있으며 파일을 변경 한 후 패턴에 따라 선택적으로 추가하려는 경우 --modified플래그를 사용할 수 있습니다

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

예를 들어,이 커밋에 CSS 변경 사항 만 추가하려는 경우

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

참조 man git-ls-files이상의 플래그에 대한


5

그냥 사용하십시오 git add *\*.java. 루트 디렉토리와 모든 서브 디렉토리에 모든 .java 파일이 추가됩니다.


좋은 대답입니다. git add * / pom.xml을 사용하여 모든 파일 이름을 pom.xml로 추가했습니다.
Philip Rego 2016 년

4

아직 언급되지 않은 Windows 명령 행 솔루션 추가 :

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

3

다음을 기반으로 특정 문자열이있는 파일 만 추가하고 싶었습니다 git status.

git status | grep string | xargs git add

그런 다음 git commit -m 'commit msg파일 제목에 "string"을 사용하여 변경된 모든 파일을 커밋 할 수있었습니다.


2

" git : glob 패턴과 일치하는 디렉토리 서브 트리에 모든 파일을 재귀 적으로 추가하려면 어떻게해야합니까? ", 경로 스펙 globbing을 올바르게 이스케이프 처리하거나 인용하면 ( '*.java'예 : git add)'*.java'

Git 2.13 (2017 년 2 분기)은 대화식 추가 기능을 향상시킵니다.

Jeff King ( )의 commit 7288e12 (2017 년 3 월 14 일)를 참조하십시오 . ( Junio ​​C Hamano의해 병합 -- 커밋 153e0d7 , 2017 년 3 월 17 일)peff
gitster

add --interactive: 경로 스펙을 확장하지 마십시오 ls-files

수정 된 파일 목록을 가져 오려면 먼저 " ls-files"를 사용 하여 사용자 제공 경로 사양을 확장 한 다음 결과 경로 목록을 " diff-index"및 " diff-files"에 인수로 공급하십시오 .
pathspec이 많은 수의 경로로 확장되면 다음 두 가지 문제 중 하나가 발생할 수 있습니다.

  1. OS는 인수 목록의 크기에 대해 불평하고 실행을 거부 할 수 있습니다. 예를 들면 다음과 같습니다.

    $ (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.
    

linux.git"드라이버"디렉토리에 약 20K 파일이 있는 리포지토리에 있습니다 (이 경우에는 수정되지 않았습니다). " ulimit -s"트릭은 거대한 경로 집합에 대해서도 Linux에서 문제를 보여주기 위해 필요합니다.
다른 운영 체제의 한계는 훨씬 적습니다 (예 : OS X에서는 5K 파일 만있는 실제 사례).

  1. 작동하더라도 실제로 느립니다. pathspec 코드는 수많은 경로에 최적화되어 있지 않습니다. 다음은 ulimit가없는 동일한 사례입니다.

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

" ls-files"를 완전히 건너 뛰고 원래 경로 스펙을 diff 명령에 공급하여 이를 개선 할 수 있습니다 .

역사적으로 " diff-index"가 지원하는 경로 사양 언어 는 약했지만 더 이상 그렇지 않습니다.


1

~ / .gitconfig에 줄을 넣습니다.

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

수정 된 모든 Java 파일을 추가하려면 다음을 수행하십시오. git addt java

마찬가지로 모든 수정 된 파이썬 파일을 추가하려면 다음을 수행하십시오. git addt py

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.