바이너리 파일이없는 gitignore


141

어떻게 바이너리 파일은 무시 될 수있다 git사용하여 .gitignore파일을?

예:

$ g++ hello.c -o hello

"hello"파일은 이진 파일입니다. 수 git이 파일을 무시?



2
나는 그렇게 오래되고 중요한 질문에 적절한 대답이 없다는 것에 매우 놀랐습니다. 나는 그 대답이 간단하다는 사실에 더욱 놀랐다 [^\.]*.
TamaMcGlinn

이 작동하지 않습니다
timotheecour

답변:


136
# Ignore all
*

# Unignore all with extensions
!*.*

# Unignore all dirs
!*/

### Above combination will ignore all files without extension ###

# Ignore files with extension `.class` & `.sm`
*.class
*.sm

# Ignore `bin` dir
bin/
# or
*/bin/*

# Unignore all `.jar` in `bin` dir
!*/bin/*.jar

# Ignore all `library.jar` in `bin` dir
*/bin/library.jar

# Ignore a file with extension
relative/path/to/dir/filename.extension

# Ignore a file without extension
relative/path/to/dir/anotherfile

1
이 솔루션은 매력처럼 작동합니다! 모든 dirs "! * /"를 무시하면 왜 확장자를 가진 subdir의 파일을 무시할 수 있습니까? (예 : aaa / bbb.c) 확장명이없는 하위 디렉토리의 파일은 계속 무시합니다. (예 : aaa / ccc)
dragonxlwang

4
디렉토리의 여러 레이어가있을 때이 방법이 예상대로 작동하지 않는 것 같습니다.
dragonxlwang

@dragonxlwang 어디에서 작동하지 않는지 궁금합니다. 여기에서 허용되는 솔루션 stackoverflow.com/a/19023985/1426932 는 약간 다르며 !/**/대신에 !*/; 어느 것이 맞습니까? / cc @VonC
timotheecour

유닉스 문화권에서는 확장명이없는 바이너리 실행 파일뿐만 아니라 쉘 스크립트의 이름을 지정하는 것이 일반적입니다.이 경우이 솔루션으로 인해 스크립트가 무시됩니다. 더 좋은 아이디어는 프로젝트에 추가 될 때마다 바이너리 실행 파일을 .gitignore에 수동으로 추가하는 것입니다. 일반적으로 자주 발생하지는 않습니다. 그것이 너무 성 가시면 vedantk가 제안한 makefile 솔루션이 더 좋습니다.
피터 Helfer

이것은 makefile을 무시할 것이다
VMatrix1900

42

같은 것을 추가하십시오

*.o

.gitignore 파일에서 repo의 루트에 배치하십시오 (또는 원하는 하위 디렉토리에 배치 할 수 있습니다-해당 레벨에서 적용됩니다).

편집하다:

확장명이없는 바이너리의 경우 bin/또는 다른 폴더 에 배치하는 것이 좋습니다 . 결국 내용 유형에 따른 무시는 없습니다.

당신은 시도 할 수 있습니다

*
!*.*

그러나 그것은 완전하지 않습니다.


1
편집이 추가되었습니다. 바이너리가 확장을 원하지 않는 이유가 있습니까?
manojlds

10
실행 파일에는 종종 확장명이 없습니다. gcc전달하여 만든 파일에 대해 동일한 작업을 수행하려고합니다 -o $@.
Nathan Lilienthal

29

모든 실행 파일을 .gitignore(당신의 질문에서 판단하는 "이진 파일"로 의미 할 수 있음)에 추가하려면 다음을 사용할 수 있습니다

find . -executable -type f >>.gitignore

에서 행 순서를 신경 쓰지 않으면 다음 명령 .gitignore으로을 업데이트하여 .gitignore중복을 제거하고 알파벳 순서를 그대로 유지하십시오.

T=$(mktemp); (cat .gitignore; find . -executable -type f | sed -e 's%^\./%%') | sort | uniq >$T; mv $T .gitignore

읽기 위해 .gitignore파일을 열기 전에 파일을 자르기 때문에 출력을로 직접 파이프 할 수는 없습니다 cat. 또한 \! -regex '.*/.*/.*'하위 디렉토리에 실행 파일을 포함시키지 않으려는 경우 옵션 으로 추가 할 수 있습니다 .


23

바이너리를 사용하는 가장 좋은 방법은 표준 패턴으로 쉽게 필터링 할 수있는 확장 기능을 제공하거나 디렉토리 수준에서 필터링 할 수있는 디렉토리에 넣는 것입니다.

확장 제안은 기본적으로 기본적으로 필요하기 때문에 확장 제안은 Windows에서 더 적용 가능하지만 Unix에서는 실행 바이너리에 확장을 사용하거나 사용하지 않을 수 있습니다. 이 경우 bin / 폴더 bin/에 넣고 .gitignore에 추가 할 수 있습니다.

매우 구체적이고 작은 범위의 예제에서는 hello.gitignore를 넣을 수 있습니다 .


15

당신은 당신의 시도 할 수 있습니다 .gitignore:

*
!*.c

이 방법에는 많은 단점이 있지만 소규모 프로젝트에는 적합합니다.


3
가장 큰 단점을
적어 두는

명백한 단점은 허용 거부 규칙의 순서이며, 올바른 방법은 원하지 않는 파일 만 무시하고 모든 파일을 허용하지 않고 원하는 파일 만 포함하는 것입니다.
Andrei Beliankou

13

makefile을 사용하는 경우 make 규칙을 수정하여 새 바이너리 이름을 .gitignore 파일에 추가 할 수 있습니다.

다음은 작은 Haskell 프로젝트를위한 Makefile의 예입니다.

all: $(patsubst %.hs, %, $(wildcard *.hs))

%: %.hs
    ghc $^
    grep -xq "$@" .gitignore || echo $@ >> .gitignore

이 makefile은 Haskell 코드에서 실행 파일을 작성하기위한 규칙을 정의합니다. ghc가 호출 된 후 .gitignore에서 바이너리가 이미 있는지 확인합니다. 그렇지 않은 경우 바이너리 이름을 파일에 추가합니다.


자, 이것은 다른 접근법입니다.
René Nyffenegger


5

파일을 사용하는 또 다른 솔루션이 있습니다. 이런 식으로 실행 스크립트는 gitignore로 끝나지 않습니다. 파일 출력이 시스템과 일치하도록 해석되는 방식을 변경해야 할 수도 있습니다. 커밋 할 때마다이 스크립트를 호출하기 위해 커밋 전 후크를 설정할 수 있습니다.

import subprocess, os

git_root = subprocess.check_output(['git', 'root']).decode("UTF-8").strip()
exes = []
cut = len(git_root)

for root, dirnames, filenames in os.walk(git_root+"/src/"):
  for fname in filenames:
    f = os.path.join(root,fname)
    if not os.access(f,os.X_OK):
      continue

    ft = subprocess.check_output(['file', f]).decode("UTF-8")

    if 'ELF' in ft and 'executable' in ft:
      exes.append(f[cut:])

gifiles = [ str.strip(a) for a in open(git_root + "/.gitignore").readlines() ]
gitignore=frozenset(exes+gifiles)

with open(git_root+"/.gitignore", "w") as g:
  for a in sorted(gitignore):
    print(a, file=g)

비슷한 스크립트를 작성하고 중복 질문에 게시했습니다. stackoverflow.com/a/28258619/218294 코드가 더 좋습니다.
Sam Watkins

4

루트뿐만 아니라 일부 하위 디렉토리에서도 무시하는 방법 :

# Ignore everything in a root
/*
# But not files with extension located in a root
!/*.*
# And not my subdir (by name)
!/subdir/
# Ignore everything inside my subdir on any level below
/subdir/**/*
# A bit of magic, removing last slash or changing combination with previous line
# fails everything. Though very possibly it just says not to ignore sub-sub-dirs.
!/subdir/**/
# ...Also excluding (grand-)children files having extension on any level
# below subdir
!/subdir/**/*.*

또는 특정 유형의 파일 만 포함하려는 경우 :

/*
!/*.c
!/*.h
!/subdir/
/subdir/**/*
!/subdir/**/
!/subdir/**/*.c
!/subdir/**/*.h

원하는 경우 모든 새 하위 디렉토리처럼 작동 할 수도 있습니다! :

/*
!/*.c
!/*.h
!/*/
/*/**/*
!/*/**/
!/*/**/*.c
!/*/**/*.h

선행 슬래시는 처음 두 줄에서만 중요하고 다른 두 줄에서는 선택 사항입니다. 에 슬래시를 미행 !/*/하고하는 것은 !/subdir/만이 줄도 선택 사항입니다.


3

.gitignore 파일에서 다음 명령을 따른 후에도 여전히 파일이 표시되는 것 같습니다 :

git rm --cached FILENAME

그런 다음 .gitignore를 추가하고 커밋하고 푸시하십시오. 그것을 이해하기 위해 40 분 걸렸습니다. 이것이 나와 같은 초보자에게 도움이되기를 바랍니다.


2

오래된 스레드이지만 여전히 관련성이 있습니다. 링크 후 결과 바이너리 파일의 이름이 [filname]이되도록 makefile을 변경했습니다. [filname] 대신 bin . 그런 다음 gitignore에 * .bin 파일을 추가했습니다.
이 루틴은 내 요구를 충족시킵니다.


1

다른 솔루션을 모르지만에 하나씩 추가합니다 .gitignore.

테스트하는 조잡한 방법은 파일 명령의 출력을 grep하는 것입니다.

find . \( ! -regex '.*/\..*' \) -type f | xargs -n 1 file | egrep "ASCII|text"

편집하다

단순히 실행 파일 이름을 지정하지 hello.bin않습니까?


파일 확장자를 가진 실행 파일의 이름을 지정하는 .bin것은 좋지 않습니다.
MD XF


0

GOPATH 디렉토리에 두 개의 항목이있는 .gitignore 파일을 작성했습니다.

/bin
/pkg

현재 컴파일 된 모든 개발을 무시합니다.


0

.gitignore는 glob 프로그래밍 을 사용 하여 적어도 Linux에서 파일을 필터링합니다.

나는 Meetup에서 코딩 연설을하려고 준비 중이며, 제시하려는 순서에 따라 이름이 지정된 여러 하위 디렉토리 (01_subject1, 02_subject2, 03_subject3)로 디렉토리를 만들었습니다. 각 서브 디렉토리에는 공통의 지시에 따라 확장자가없는 소스 파일 이름과 이름이 일치하는 실행 파일로 컴파일되는 언어 종속 확장자를 가진 소스 파일이 있습니다.

다음 .gitignore 줄을 사용하여 숫자로 접두어 붙은 디렉토리에서 컴파일 된 파일을 제외합니다.

[0-9][0-9]_*/[!\.]*

문서에 대한 나의 이해에 따르면 작동하지 않아야합니다. 뒤에 별표가 있으면 '.'을 포함하여 지정되지 않은 문자 수와 일치해야하므로 실패해야합니다. + 확장. [!\.]마침표가없는 단일 문자 만 일치 하므로 후행 별표를 생략하면 실패하고 수행해야 합니다. 그러나 정규 표현식과 마찬가지로 후행 별표를 추가하여 작동합니다. 작업에 따르면, git 은 소스 파일에 대한 변경을 통지하지만 컴파일 된 파일에 대한 존재 또는 변경은 통지하지 않습니다.



0

.gitignore 파일에 다음을 추가하십시오.

[^\.]*

설명:

[] encloses a character class, e.g. [a-zA-Z] means "any letter".
^  means "not"
\. means a literal dot - without the backslash . means "any character"
*  means "any number of these characters"

0

.gitignore메커니즘은 파일 내용이 아닌 파일 이름을 기반으로 만 작동합니다 . 이진 파일은 콘텐츠의 속성이므로 git에게 이진 파일을 직접 무시하지 말고 이름으로 만 무시하도록 요청할 수는 없습니다 (다른 제안처럼 모든 이진 파일 이름을 추가 하거나 적절한 방법을 사용할 수 있습니다) 명명 규칙)..gitignore

.gitignore파일 이름에서 작동 하는 사실은 성능 측면에서 중요한 속성입니다. Git은 파일을 나열하기 만하면되지만 무시할 파일을 알기 위해 파일을 열고 읽을 필요는 없습니다. 다시 말해, Git이 내용에 따라 파일을 무시하도록 요청할 수 있다면 Git은 매우 느릴 것입니다.

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