gitignore 제외 규칙은 실제로 어떻게 작동합니까?


146

큰 디렉토리 구조에서 gitignore 문제를 해결하려고하지만 내 질문을 단순화하기 위해 다음과 같이 줄였습니다.

새로운 git 저장소에 두 파일 (foo, bar)의 다음 디렉토리 구조가 있습니다 (지금까지 커밋 없음).

a/b/c/foo
a/b/c/bar

분명히 'git status -u'는 다음을 보여줍니다.

# Untracked files:
...
#       a/b/c/bar
#       a/b/c/foo

내가하고 싶은 것은 a / b / c 내부의 모든 것을 무시하지만 'foo'파일을 무시하지 않는 .gitignore 파일을 만드는 것입니다.

내가 .gitignore를 만들면 :

c/

그런 다음 'git status -u'는 foo와 bar를 무시한 것으로 표시합니다.

# Untracked files:
...
#       .gitignore

내가 기대 한대로.

이제 foo에 대한 제외 규칙을 추가하면 다음과 같습니다.

c/
!foo

gitignore 맨 페이지에 따르면, 이것이 효과가있을 것으로 기대합니다. 그러나 그것은 아닙니다-여전히 foo를 무시합니다.

# Untracked files:
...
#       .gitignore

이것은 작동하지 않습니다 :

c/
!a/b/c/foo

이것도 마찬가지입니다 :

c/*
!foo

제공합니다 :

# Untracked files:
...
#       .gitignore
#       a/b/c/bar
#       a/b/c/foo

이 경우 foo는 더 이상 무시되지 않지만 bar도 무시되지 않습니다.

gitignore의 규칙 순서는 중요하지 않습니다.

이것은 또한 내가 기대하는 것을하지 않습니다 :

a/b/c/
!a/b/c/foo

그것은 foo와 bar를 모두 무시합니다.

작동하는 한 가지 상황은 a / b / c / .gitignore 파일을 만들고 거기에 넣는 경우입니다.

*
!foo

그러나 이것의 문제는 결국 a / b / c 아래에 다른 하위 디렉토리가 있고 모든 단일 디렉토리에 별도의 .gitignore를 넣기를 원하지 않는다는 것입니다. '프로젝트 기반'.gitignore를 만들고 싶었습니다. 각 프로젝트의 최상위 디렉토리에 있고 모든 '표준'서브 디렉토리 구조를 포함 할 수있는 파일.

이것은 또한 동등한 것으로 보입니다.

a/b/c/*
!a/b/c/foo

이것은 내가 달성 할 수있는 "작동"에 가장 가까운 것일 수 있지만 전체 상대 경로와 명시 적 예외를 명시해야합니다. 다른 수준에서 'foo'라는 이름의 파일이 많이 있으면 고통 스럽습니다. 서브 디렉토리 트리의

어쨌든 제외 규칙의 작동 방식을 잘 모르겠거나 / 와일드 카드가 아닌 디렉토리가 무시 될 때 전혀 작동하지 않습니다.

누구든지 이것에 대해 밝힐 수 있습니까?

gitignore 가이 서투른 쉘 기반 구문 대신 정규 표현식과 같은 합리적인 것을 사용하게하는 방법이 있습니까?

Cygwin / bash3의 git-1.6.6.1 및 Ubuntu / bash3의 git-1.7.1에서 이것을 사용하고 관찰합니다.



4
훌륭하게 쓰여진 질문! 당신이 시도한 사건의 양은 비슷한 사건에서 내가 잘못하고있는 것을 이해하는 데 실제로 도움이되었습니다. 고마워, 오늘 오랫동안 찾고 있었어
Alex G

답변:


153
/알파벳/*
! foo

나를 위해 일하는 것 같습니다 (Linux에서는 git 1.7.0.4). 은 *당신이 (제외 가능) 디렉토리 내에서 디렉토리 자체 (자식이 내 보이지 않도록) 대신 파일을 무시하고, 그렇지 않으면 중요하다.

말과 같이 예외 생각 "하지만이 일"보다는 "그러나이 포함"- "이 디렉토리 (무시 /a/b/c/)하지만이 일을 ( foo수행이 훨씬 이해가되지)"; "이 디렉토리 ( /a/b/c/*)의 모든 파일은 무시 하지만 이 파일 ( ) 은 무시하십시오 foo". 매뉴얼 페이지를 인용하려면 :

선택적 접두사! 패턴을 무효화합니다. 이전 패턴에서 제외 된 일치하는 파일은 다시 포함됩니다.

즉, 파일 이 이미 제외되어 다시 포함되어야합니다. 희망이 빛을 발합니다.


예, 당신이 제시 한 예가 저에게도 효과가 있습니다. 문제는 foo가 c에있는 경우 / a / b / *가 작동하지 않는다는 것입니다. 즉, c 아래의 여러 하위 디렉토리에 여러 개의 foo 파일이있는 경우 (예 : d /, e /, f / g / h /, i / j) / 등) 부정 규칙 '! foo'는 그 규칙을 잡을 수 없습니다.
davidA

1
@meowsqueak 실제로는 그렇지 않습니다. / a / b / *를 무시하면 foo를위한 디렉토리가 없습니다! / a / b 아래의 전체 디렉토리 트리를 무시하려고하지만 트리의 어느 곳에 나있을 수있는 "foo"라는 파일을 포함 시키려면 .gitignore 패턴으로 수행 할 수 없다고 생각합니다. \
Chris

실제로 이것은 왜 이것이 작동하지 않는지를 설명 할 수 있습니다. "/ a / b / *", "! c / foo"규칙이 작동하지 않습니다. 그래도 문제가 해결되지 않았습니다.
davidA

5
".gitignore 패턴으로는 불가능하다고 생각합니다."-불행히도 당신이 옳다고 생각합니다.
davidA

@meowsqueak 어쩌면 무시 /a/b/c하고 git add --force일치하는 파일을 미리 커밋하거나 다른 것에 후크를 작성할 수 있습니다.
Chris

24

비슷한 상황이 있는데 내 솔루션은 다음과 같습니다.

/a/**/*
!/a/**/foo

**올바르게 읽으면 임의의 수의 중간 디렉토리에서 작동 합니다.


6

이것은 .gitignore 매뉴얼 페이지에서 분명하지 않습니다. 이것은 작동합니다 :

*
!/a
!/a/b
!/a/b/c
!/a/b/c/foo

# don't forget this one
!.gitignore

Chris가 언급했듯이 디렉토리가 제외되면 열리지 않습니다. 따라서 * 그러나 일부 파일을 무시하려면 위와 같이 해당 파일의 경로를 작성해야합니다. 나에게 이것은 편리합니다. 라이브러리의 1 파일에서 코드 검토를 원하고 나중에 다른 파일을 원한다면 추가하면되고 다른 모든 것은 무시됩니다.


6

다른 옵션은 다음과 같습니다.

*
!/a*
!/a/*
!/a/*/*
!/a/*/*/*

그것은 3 단계 깊이의 파일 / 디렉토리를 제외하고 모든 파일과 디렉토리를 무시합니다.


5

보다 일반적인 메모에서, git1.8.2는 인클루드 것 패치 (또한 그 V4에서 , 일부 스택 오버플로 질문에서 메시지 에서) 아담 첨탑을 하는 결정에 대해 gitignore실제로 파일을 무시 지배.

참조 git1.8.2 릴리스 노트 및 "는 SO 질문 내 파일을 무시 gitignore 규칙을 "
명령이 될 것이다 git check-ignore.


1
이 정보를 방송 해 주셔서 감사합니다. check-ignore또한 어떤 경우 규칙 에서 파일을 무시 하지 못하게 하는지 알려줍니다 .
Adam Spiers

@AdamSpiers는 훌륭하게 들립니다. 나는 그것을 가지고 놀아야 할 것이다.
VonC
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.