.gitignore 구문 : bin vs bin / vs. bin / * vs. bin / ** 에서 이중 및 단일 별은

추가의 차이점은 무엇입니까 bin, bin/, bin/*bin/**내 .gitignore 파일에? 나는 .gitignore 파일을 사용 bin/하고 있지만 다른 .gitignore 파일을 보고 있습니다 ( 일식 파일 에서 이중 및 단일 별은 다음과 같이 함께 사용됩니다. tmp/**/*무슨 일입니까?) 처음 두 패턴도 널리 사용된다는 것을 알 수 있습니다. 누군가가 세 가지 차이점을 설명해 주시겠습니까?



답변

bin‘bin’이라는 파일 또는 디렉토리 와 일치합니다 .

bin/‘bin’이라는 이름의 디렉토리 와 일치합니다 . 이는 사실상 Git이 디렉토리 만 추적하지 않기 때문에 모든 내용을 의미합니다.

bin/*모든 파일 및 디렉토리를 bin/. 이렇게하면 Git이 하위 디렉터리에서 파일을 자동으로 찾지 못하지만 bin/foo하위 디렉터리가 생성 된 경우이 규칙은 의 콘텐츠 와 일치 하지 않습니다foo .

bin/**모든 bin/디렉토리 및 모든 하위 디렉토리의 모든 파일 및 디렉토리와 일치합니다 .

규칙은 저장소 루트와 관련이없고 파일 시스템 트리의 모든 위치 에 적용되므로 여기서 “임의”라는 단어가 중요합니다 . 의도 한 내용 만 일치 시키려면 시스템의 루트가 아닌 저장소의 루트를 의미하는 a /(또는 !/무시 해제)로 규칙을 시작해야합니다 .

경고 : 당신이해야 결코 같은 규칙을 사용하지 dir/*, /dir/**등 혼자 당신은 또한 디렉토리 내부에 존재하는 무엇인가를 취소 무시하지 않는 한 . 생략 별표는 또는 영구적으로 많은 양의 데이터를 잃을 수있는 특정의 호출로부터 git gc, git stash그리고 더.

나는 무엇을해야하는지 정말로 모른다 tmp/**/*. 처음에는 하위 디렉토리에있는 파일을 일치시키는 데 사용할 수 있다고 생각 tmp/했지만 tmp/그 자체로 직접 존재하는 파일 은 아닙니다 . 그러나 간단한 테스트는 이것이 tmp/.


답변

binbin/차이가 아니라 후자는 디렉토리와 일치합니다.

bin/**/*bin/**@VonC의 답변에 따르면 1.8.2 이후 로 동일 합니다.

까다로운 하나, 난 그냥 시간을 보냈다 정도 이상 내 머리를 추출한다는 점이다 bin/bin/**아니다 확실히 같은! 앞의 것은 디렉토리 전체를 무시하고 후자는 그 안의 각 파일을 무시하고 거의 모든 경우에 git은 디렉토리를 신경 쓰지 않기 때문에 일반적으로 차이가 없습니다. !그러나을 사용 하여 하위 경로 무시를 해제 하려고 하면 부모 디렉토리를 무시하면 git (ahem)이 무시 한다는 것을 알 수 있습니다! (디렉토리 내용이 아니라 다시)

이것은 예제에서 가장 명확하므로 새로 초기화 된 저장소의 경우 다음과 같이 설정됩니다.

$ cat .gitignore
ignored-file
or-dir
dir-only/
!dir-only/cant-reinclude
dir-contents/**
!dir-contents/can-reinclude

$ mkdir or-dir dir-only dir-contents

$ touch file ignored-file or-dir/ignored-file dir-only/cant-reinclude dir-contents/can-reinclude

다음과 같은 추적되지 않은 파일이 있습니다.

$ git ls-files --other
.gitignore
dir-contents/can-reinclude
dir-only/cant-reinclude
file
ignored-file
or-dir/ignored-file

그러나 다음 파일이 무시되지 않음을 알 수 있습니다.

$ git ls-files --other --exclude-standard
.gitignore
dir-contents/can-reinclude
file

추가하려고하면 다음과 같은 결과가 나타납니다.

$ git add dir-only/cant-reinclude
The following paths are ignored by one of your .gitignore files:
dir-only/cant-reinclude
Use -f if you really want to add them.
fatal: no files added

나는이 행동을 버그라고 생각한다. (모두 켜짐 git version 1.8.4.msysgit.0)


답변

엄밀히 말하면 git은 디렉토리가 아니라 파일 만 추적합니다. 따라서 디렉토리를 추가 할 수 없으며 해당 내용 만 추가 할 수 있습니다 .

.gitignore그러나 맥락 에서 git은 다음과 같은 유일한 이유로 디렉토리를 이해하는 척합니다.

해당 파일의 상위 디렉토리가 제외 된 경우 파일을 다시 포함 할 수 없습니다.
https://git-scm.com/docs/gitignore#_pattern_format

이것은 제외 패턴에 대해 무엇을 의미합니까? 자세히 살펴 보겠습니다.

bin

이것은 무시합니다

  • 이름이 bin.
  • 이름이 지정된 폴더의 내용 bin

bin후속 !항목 을 추가하여 무시 된 파일 및 폴더를 허용 할 수 있지만 이름이 지정된 폴더 의 내용 을 허용 할 수는 없습니다.bin

bin

!bin/file_in_bin # has no effect, since bin/ is blacklisted!
!bin/* # has no effect, since bin/ is blacklisted!
!file_in_bin # has no effect, since bin/ is blacklisted!

!bin # this works

bin/

위와 동일, 일치하지 않는 것을 제외하고 파일 이름을 bin. 후행을 추가하면 /git이 디렉토리 만 일치하도록 지시합니다.

bin/*

이것은 무시합니다

  • 이름이 지정된 폴더에 포함 된 파일bin
  • 이름이 지정된 폴더의 직접 하위 폴더 내용 bin
bin/*  # blacklists bin/file_in_bin and bin/subfolder/

!bin/subfolder/file_in_sub # has no effect, since bin/subfolder is blacklisted!
!bin # whitelists files named bin/bin, since bin/ itself is not blacklisted
!bin/ # has no effect, since bin/ itself is not blacklisted


!bin/file_in_bin # works since bin/ itself is not blacklisted
!file_in_bin # works too
!bin/subfolder # works (so implicitly whitelists bin/subfolder/file_in_sub)
!bin/subfolder/ # works just as well
!bin/* # works for file_in_bin and subfolder/

bin/**

이것은 무시합니다

  • 내용 bin
  • 하위 폴더의 내용 (모든 중첩 수준) bin
bin/**  # blacklists bin/file_in_bin and
        # bin/subfolder/ and bin/subfolder/file_in_sub and
        # bin/subfolder/2/ and bin/subfolder/2/file_in_sub_2

!bin/subfolder/file_in_sub # has no effect, since bin/subfolder is blacklisted
!bin/subfolder/2/ # has no effect, since bin/subfolder is blacklisted
!bin/subfolder/2/file_in_sub_2 # has no effect, since bin/subfolder is blacklisted

!bin/subfolder # works only in combinations with other whitelist entries,
               # since all contents of subfolder are blacklisted (1)

!bin/file_in_bin # works since bin itself is not blacklisted
!bin/* # works for file_in_bin and subfolder; see (1)


답변

방금 새 저장소를 만들고 몇 가지 시도했습니다. 내 결과는 다음과 같습니다.

새로운 결과

git 버전 2.10.1.windows.1

  1. 거의 비어있는 저장소를 초기화합니다. README 파일 만
  2. bin디렉터리를 여러 레이어 깊이

    채 웁니다.

    • bin.txt
    • Test.txt
    • bin/a/b/bin.txt
    • bin/a/b/Test.txt
    • bin/a/bin/bin.txt
    • bin/a/bin/Test.txt
    • bin/a/bin.txt
    • bin/a/Test.txt
    • bin/bin.txt
    • bin/Test.txt
  3. bingitignore에 추가 : 결과
    • bin이제 디렉토리 아래 (및 더 깊은) 아래의 모든 항목 이 무시됩니다.
    • 루트 수준은 무시되지 않습니다 (/bin.txt 및 /Test.txt는 계속 표시됨).
  4. 편집 binbin/gitignore의 : 결과
    • 변경 없음
  5. 편집 bin/bin/*
    • 변경 없음
  6. 편집 bin/*bin/**
    • 변경 없음
  7. 편집 bin/**bin/**/
    • bin/bin.txt그리고 bin/Test.txt더 이상 무시하지 않습니다
  8. 편집 bin/**/bin/**/*
    • bin/bin.txt그리고 bin/Test.txt무시로 돌아

오래된 결과

git 버전 : 2.7.0.windows.1

  1. 거의 비어있는 저장소를 초기화합니다. README 파일 만
  2. bin디렉터리를 여러 레이어 깊이

    채 웁니다.

    • bin/a/b/Test.txt
    • bin/a/bin/Test.txt
    • bin/a/Test.txt
    • bin/Test.txt
  3. bingitignore에 추가 : 결과
    • bin이제 디렉토리 아래 (및 더 깊은) 아래의 모든 항목 이 무시됩니다.
  4. 편집 binbin/gitignore의 : 결과
    • bin디렉토리 아래 (및 더 깊은) 아래의 모든 항목 은 여전히 ​​무시됩니다 (변경 없음).
  5. 편집 bin/bin/*
    • bin디렉토리 아래 (및 더 깊은) 아래의 모든 항목 은 여전히 ​​무시됩니다 (변경 없음).
  6. 편집 bin/*bin/**
    • bin디렉토리 아래 (및 더 깊은) 아래의 모든 항목 은 여전히 ​​무시됩니다 (변경 없음).
  7. 편집 bin/**bin/**/
    • bin/Test.txt 더 이상 무시되지 않습니다
  8. 편집 bin/**/bin/**/*
    • bin디렉토리 아래 (및 더 깊은) 아래의 모든 항목 이 다시 무시됩니다.


답변

참고 그 ‘ **하위 디렉토리와 결합 할 때 ( **/bar)이 있기 때문에, 기본 동작 변경해야합니다 git1.8.2에 대한 릴리스 노트가 지금 언급 :

의 패턴 .gitignore.gitattributes파일을 가질 수 **/하위 디렉토리의 0 또는 그 이상의 수준을 일치하는 패턴으로,.

예를 들어 ” foo/**/barbar는 ” foo“자체 또는 ” “의 하위 디렉토리 에서 ” “와 일치 foo합니다.


기억해야 할 규칙 (그리고 해당 구문 뒤에있는 의도의 차이를 이해하는 데 도움이 됨)는 다음과 같습니다.

해당 파일의 상위 디렉토리가 제외 된 경우 파일을 다시 포함 할 수 없습니다.


일반적으로 무시 폴더 f의 하위 폴더에서 파일을 제외하려면 다음을 수행합니다.

f/**
!f/**/
!f/a/sub/folder/someFile.txt

그건:

  • 첫 번째 규칙이 f/이면 폴더 f/가 무시되고 관련 아래 규칙 f은 중요하지 않습니다.
  • f/**와 동일 f/하지만 모든 하위 요소 (파일 및 하위 폴더)를 무시합니다 .
    그러면 하위 폴더를 허용 목록 (gitignore에서 제외) 할 수 !f/**/있습니다..
  • 모든 f하위 폴더가 무시 되지 않으므로 파일 ( !f/a/sub/folder/someFile.txt) 을 제외하는 규칙을 추가 할 수 있습니다.


답변

bin/*와 사이에는 또 다른 차이점이 있습니다 bin/.

bin/foo/bin/test.txt(예상대로) 일치 하지만 bin/*그렇지 않습니다. 이상하게 보이지만 문서화되었습니다 : https://git-scm.com/docs/gitignore

“Documentation / *. html”은 “Documentation / git.html”과 일치하지만 “Documentation / ppc / ppc.html”또는 “tools / perf / Documentation / perf.html”과는 일치하지 않습니다.

그 이유는 다음과 같은 규칙으로 보입니다.

  • 패턴이 슬래시로 끝나는 경우 다음 설명을 위해 제거됩니다.

  • 패턴에 슬래시 /가 포함되어 있지 않으면 Git은이를 쉘 glob 패턴으로 취급하고 .gitignore 파일의 위치에 상대적인 경로 이름과 일치하는지 확인합니다.

  • 그렇지 않으면 Git은 패턴을 FNM_PATHNAME 플래그를 사용하여 fnmatch (3)에서 사용하기에 적합한 쉘 glob으로 취급합니다.

따라서 패턴이 슬래시로 끝나면 슬래시가 제거되고 쉘 glob 패턴으로 처리되며이 경우 bin일치 foo/bin/test.txt합니다. 로 끝나는 경우 /*슬래시가 제거되지 않고 하위 디렉터리에서 일치하지 않는 fnmatch로 전달됩니다.

그러나 에서 후행 슬래시를 제거한 후에도 여전히 슬래시가 포함되어있어 glob이 아닌 fnmatch 패턴으로 처리 되기 때문에 foo/bin/및의 foo/bin/*경우도 마찬가지 foo/bin/입니다. 즉 일치하지 않습니다bar/foo/bin/test.txt


답변