Git에서 파일 추적을 중지하고 파일 변경 사항을 무시하는 방법은 무엇입니까?


1731

일부 .csproj파일 이 포함 된 프로젝트를 복제했습니다 . 로컬 csproj파일이 Git에 의해 추적되거나 패치를 생성 할 때 필요하지는 않지만 프로젝트에 분명히 필요합니다.

*.csprojLOCAL에 추가 .gitignore했지만 파일이 이미 저장소에 있습니다.

git status를 입력하면 csproj패치를 추적하거나 제출하고 싶지 않은 변경 사항이 표시 됩니다.

상태를 확인하거나 패치를 만들 때 변경 사항을 볼 수 없도록 개인 저장소에서 이러한 파일의 "추적"을 제거하려면 (그러나 파일을 소스에 보관하십시오) 어떻게해야합니까?

이 상황을 처리하는 올바른 / 정규적인 방법이 있습니까?


18
매우 유용한 질문이지만 .csproj파일 변경 사항을 추적하고 싶지 않은 이유가 궁금 합니다. 이는 프로젝트의 중요한 부분입니다. 추적 할 수없는 .csproj.user파일 또는 파일 에 대한 변경 사항 .Publish.XML추적이 불가능한 이유에 대해 궁금한 점이 있습니다 .csproj.
Owen Blacker

7
아마도 그들은 다른 IDE를 사용합니까?
Jarrett

3
아이러니하게도 repo에서 .suo 파일을 제거하려고하지만 로컬로 유지하려고하기 때문에이 스레드에 왔습니다. 후손을 위해 .Net 개발을 위해서는 .csproj 파일을 저장소에 보관해야하며 프로젝트의 다른 개발자의 분노를 느끼지 않으려면 이러한 변경 사항을 항상 추적해야합니다. 확실하지 않은 경우 GitHub의 gitignore 파일 저장소를 살펴보십시오. github.com/github/gitignore/blob/master/VisualStudio.gitignore
longda

1
@Cupcake, 연결하신 질문은 15 일 후에 작성 되었습니까? 아마도 당신은 다른 것을 생각하고 있습니까?
stephenmurdoch

@marflar 정식 질문은 반드시 할 필요는 없습니다 오래된 것, 바로 최고의 것들. 내가 링크 한 사람은 20 개의 답변을 가지고 있지만이 답변은 5 명뿐입니다.

답변:


2129

git rm --cached수정본 제어에서 제거 할 각 파일을 호출 하면됩니다. 로컬 무시 패턴이 올바른 한 git status 출력에 이러한 파일이 포함되지 않습니다.

이 솔루션은 저장소에서 파일을 제거하므로 모든 개발자는 파일의 로컬 (개정되지 않은 제어) 사본을 유지해야합니다.

git이 이러한 파일의 변경 사항을 감지하지 못하게하려면 다음 명령을 사용해야합니다.

git update-index --assume-unchanged [path]

아마도하고 싶은 일 : (아래 @Ryan Taylor 답변 )

  1. 이것은 git에게 파일이나 폴더의 독립적 인 버전을 원한다는 것을 알리는 것입니다. 예를 들어, 프로덕션 / 스테이징 구성 파일을 덮어 쓰거나 삭제하지 않으려 고합니다.

git update-index --skip-worktree <path-name>

전체 답변은 다음 URL에 있습니다 : http://source.kohlerville.com/2009/02/untrack-files-in-git/


187
"git rm --cached <file>"은 작업 저장소에 유지하면서 버전 제어에서 <file>을 제거합니다. 그것이 당신이 원하는 것인지 ...
Jakub Narębski

51
그러나 다른 사람이 저장소를 가져올 때 자신의 * .csproj 파일이 제거됩니까? 파일을 추적하지 않고 삭제하지 않으려면 때문입니다.
FMaz008

23
디렉토리의 모든 파일을 제거하려고하면 git ls-files와 결합하십시오 : git ls-files | xargs git rm --cached-실제 파일을 삭제하지 않고 주어진 디렉토리의 git 색인에서 모든 것을 제거합니다.
Marco

129
git rm --cached -r <dir>폴더와 그 안의 모든 파일에서 재귀 적으로 작동합니다.
Chris K

41
이렇게하면 파일 추적이 중지되고 로컬로 유지되지만 파일 을 가져 오는 모든 사람에 대해 삭제됩니다
Edward Newell

249

그렇게 git update-index --assume-unchanged file.csproj하면 git은 file.csproj에서 자동으로 변경 사항을 확인하지 않습니다. 변경 할 때마다 git 상태로 변경되지 않습니다. 따라서 모든 .csproj 파일을 이런 식으로 표시 할 수 있지만 업스트림 리포지토리가 보내는 새 파일을 수동으로 표시해야합니다. ( .gitignore또는 .git/info/exclude에 파일이 있으면 생성 한 항목은 무시됩니다.)

나는 .csproj 파일이 무엇인지 완전히 확신하지 못합니다 ... IDE 구성 라인 (Eclipse의 .eclipse 및 .classpath 파일과 유사)에 해당하는 경우 소스에서 제어 할 수 없다고 제안합니다. 모두. 반면에, Makefile과 같은 빌드 시스템의 일부인 경우 분명히 선택해야합니다. 그리고 선택적 로컬 변경 사항 (예 : local.csproj a la config.mk)을 선택하는 방법이 유용합니다. : 빌드를 전역 부분과 로컬 재정의로 나눕니다.


8
csproj는 C # 프로젝트 파일로, 프로젝트에 포함 된 파일과 기타 몇 가지 구성을 추적합니다. 프로젝트가 작동하려면 소스 제어되어야합니다.
SparK

4
이것이 유일한 정답입니다! 나는 몇 년 동안 @araqnids 답변을 사용해 왔으며이 문제를 해결하기 위해 요청 한대로 정확하게 작동합니다.
NHDaly

명령에 대한 인수에서 '파일'접두어의 의미는 무엇입니까? 왜 안되지 .csproj?
GreenAsJade

1
이것이 파일에 대해 수행되었음을 또는 저장소에서 수행 된 파일에 대해 감지 할 수있는 방법이 있습니까? 나는 내가 한 일을 잊고 나중에이 파일이 왜 업데이트되지 않는지 궁금해합니다.
GreenAsJade

4
@GreenAsJade는 : git ls-files -v(예 소문자 표시로 변경되지 않은 것으로 가정되는 파일이 표시됩니다 h대신 보통의 H캐시 파일을).
Amadan

238

3 가지 옵션이 있습니다. 아마도 # 3을 원할 것입니다

1. 이렇게하면 로컬 파일이 유지되지만 다른 사람이 파일을 가져 오면 삭제됩니다.

git rm --cached <file-name> 또는 git rm -r --cached <folder-name>

2. 이것은 많은 파일이있는 폴더와 같은 최적화를위한 것입니다. git은 로컬에 변경 사항이 없을 때마다 변경 사항이 있는지 매번 큰 폴더 확인을 중지하도록 지시합니다. assume-unchanged(당길 때) 지수는 파일 / 폴더 상류 변경이있는 경우 덮어 리셋 및 파일 (들)입니다.

git update-index --assume-unchanged <path-name>

3. 이것은 git에게 파일이나 폴더의 독립적 인 버전을 원한다는 것을 알리기위한 것입니다. 예를 들어, 프로덕션 / 스테이징 구성 파일을 덮어 쓰거나 삭제하지 않으려 고합니다.

git update-index --skip-worktree <path-name>

git과 함께 git update-index 전파되지 않으며 각 사용자가 독립적으로 실행해야 한다는 것을 알아야합니다 .


8
이 답변은 가장 완벽합니다. 각 솔루션의 결과와 함께 다양한 솔루션을 제공합니다. 내가 작업하고있는 특정 사례에는 구성 파일에 비밀번호가 포함되어 있습니다. 템플릿 파일을 전파 한 다음 암호를 사본에 추가하고 싶습니다. 비밀번호가있는 사본은 무시하고 덮어 쓰지 않아야합니다.
bmacnaughton

1
로컬에서 '가정되지 않은 가정'또는 '건너 뛰기'에 적용되는 파일을 어떻게 확인할 수 있습니까?
Supawat Pusavanno

3
@SupawatPusavanno 이전에이 응답의 변화 - 가정 또는 생략 - worktree 모양으로 선택하는 파일을 볼 수 stackoverflow.com/questions/42363881/... -이 사용 grep하고git ls-files
라이언 테일러

1
아주 좋은 대답입니다. 그러나 다른 분기로 전환하려고하면 git에서 오류가 발생합니다. 오류 : "다음 파일에 대한 로컬 변경 사항을 체크 아웃 .....으로 덮어 씁니다." 당신은 지점으로 돌아옵니다.
팬텀 레퍼런스

@RyanTaylor : 변경되지 않은 첫 번째 (작동하지 않았다) 가정하고 worktree 명령을 건너 뛰었습니다 (작동하지 않았습니다) .git 상태를 확인할 때 파일이 표시되지 않으면 명령이 작동했음을 의미합니다. 그러나 it gives me error that your local changes would be overwritten그 두 파일의 git origin repo 에서 코드를 다시 가져 오면 제대로 추적되지 않습니다.
NeverGiveUp161

152

이것은 2 단계 프로세스입니다.

  1. 파일 / 폴더 추적을 제거하되 디스크에 보관하십시오.

    git rm --cached 
    

    이제 그들은 "변경된"것으로 나타나지 않지만 여전히

        untracked files in  git status -u  
    
  2. 에 추가 .gitignore


56
아니요, 이렇게하면 파일이 추적에서 제거되고 로컬로 보존 되지만을 당기는 사람에게는 삭제됩니다 .
Edward Newell

1
필자의 경우 실수로 추적하지 않으려는 폴더를 추가 했으므로 이것이 내가 필요한 것입니다.
Sonny

4
그렇습니다. 실제로 질문에 대한 대답은 잘못입니다.하지만 검색 결과 에서이 질문을 찾는 대부분의 사람들에게는 아마도 정답 일 것입니다.
앤드류 스펜서

95

수락 된 답변이 여전히 효과가 없었습니다.

나는 사용했다

git rm -r --cached.

git add.

git commit -m ".gitignore 수정"

여기 에서 답을 찾았습니다


이 링크는 특히 .gitignore의 모든 파일을 재귀 적으로 제거하는 데 매우 유용합니다
rmcsharry

9
나는 여기에 3 번 돌아 왔으며, 다음 번에 메모리에 커밋 할 수 있기를 바랍니다!
Harry Bosh

같이 @Edward 뉴웰의 코멘트 위의 대답은 여기에서도 적용 : "이 로컬로 유지, 추적에서 파일을 제거합니다 하지만이 끌어 누군가를 위해 삭제 될 수 ".
ToJo

46

.gitignore를 잊었습니까?

전체 프로젝트를 로컬로 가지고 있지만 git ignore를 추가하지 않고 이제 불필요한 파일을 추적하는 경우이 명령을 사용하여 모든 것을 제거하십시오

git rm --cached -r .

프로젝트의 루트에 있는지 확인하십시오.

그럼 평소에 할 수 있습니다

더하다

git add .

범하다

git commit -m 'removed all and added with git ignore'

푸시

git push origin master

결론

이것이 변경을 .gitignore하거나 함께 잊어 버린 사람들에게 도움이 되기를 바랍니다.

  • 전체 캐시를 제거합니다
  • 당신의 .gitignore를 본다
  • 추적하려는 파일을 추가합니다
  • 당신의 레포로 밀어

4
제거 또는 추가에 관해 말할 때는 언제 어디서 말하는지를 잊어 버리게됩니다. 트랙 목록에서 제거 하시겠습니까? 저장소에서? 지역 프로젝트 공간에서? 풀에서 제거 하시겠습니까? 커밋? 푸시? 아아, 여기의 모든 저자는 같은 문제가 있습니다.
Gangnus

3
@ Gangnus 나는 파일이 실제로 디스크 또는 저장소에서 제거되지 않는다는 것이 분명하기 때문에 누군가가 당신이 만들고자하는 요점을 '명확하게'생각하지 않습니다. 이 답변은 명령의 시간 순서를 지정합니다. 귀하의 의견에서 알 수 있듯이 신비 스럽거나 잘못 설명되지 않았습니다.
Anthony

같이 @Edward 뉴웰의 코멘트 위의 대답은 여기에서도 적용 : "이 로컬로 유지, 추적에서 파일을 제거합니다 하지만이 끌어 누군가를 위해 삭제 될 수 ".
ToJo

26

다른 답변에서 지적했듯이 선택한 답변이 잘못되었습니다.

대답 다른 질문은 필요한 것 스킵-worktree 수 있음을 시사한다.

git update-index --skip-worktree <file>

2
아니, 정말로 : --skip-worktree하는 데 사용되는 저장소에있는 파일을 유지하지만 변화를 추적 중지 . 답변에서 알 수 있듯이 --skip-worktree는 개발자 파일 변경 해야 하기 때문에 git에게 특정 파일을 건드리지 말라고 지시 할 때 유용 합니다.
Erdal G.

4
@ErdalG. 바로 그거죠. 질문에 따르면, 그들은 파일의 변경 사항을 무시하고 파일을 repo에 유지하려고합니다.
the_new_mr

@the_new_mr 동의 --assume-unchanged--skip-worktree유사한 효과를 가지고 있지만 자신의 목적을 완전히 다릅니다. 전자는 특정 파일을 검사하지 않도록 git을 속임으로써 git 성능을 향상시키는 데 사용되는 반면, 후자는 런타임에 적합하지만 필수 파일 인 특정 파일에 대한 향후 변경 사항무시 하기위한 것입니다.
Victor Wong

22

시간을 절약하기 위해 .gitignore에 추가 한 규칙을 사용하여 여러 파일 / 폴더를 제거 할 수 있습니다.

git rm --cached app/**/*.xml

또는

git rm --cached -r app/widgets/yourfolder/

기타


이것은 gitignore를 단계별로 수정하고자 할 때 매우 좋은 해결책입니다.
cutiko

15

자식으로 파일을 모니터링하지 못하게하려면

git update-index --assume-unchanged [file-path]

다시 되돌리려면

git update-index --no-assume-unchanged [file-path]

유사한 사용 사례를 참조하는 리포지토리 https://github.com/awslabs/git-secrets


1
되돌리기 팁은 생명의 은인이었습니다. 감사합니다!
Hamman Samuel

9

많은 사람들이 사용하도록 조언합니다 git update-index --assume-unchanged. 실제로 이것은 좋은 해결책 일 수 있지만 단기적으로 만 가능합니다.

아마 당신이하고 싶은 것은 이것입니다 : git update-index --skip-worktree.

(원치 않는 세 번째 옵션은 다음과 같습니다 git rm --cached.. 로컬 파일을 유지하지만 원격 저장소에서 제거 된 것으로 표시됩니다.)

처음 두 옵션의 차이점은 무엇입니까?

  • assume-unchanged파일에서 수정 사항을 일시적으로 숨길 수 있습니다. 파일에 대한 수정 사항을 숨기려면 파일을 수정 한 다음 다른 브랜치를 체크 아웃하십시오. 그런 다음 no-assume-unchanged숨김 수정 을 사용해야 합니다.
  • skip-worktree 당신이 수정 한 지점에 상관없이 당신을 따라갈 것입니다!

사용 사례 assume-unchanged

이 파일을 수정해서는 안되며, 수행 할 때 더 깨끗한 출력을 제공한다고 가정합니다 git status. 그러나 다른 브랜치를 체크 아웃 할 때는 플래그를 재설정하고 변경 사항을 커밋 또는 숨김 처리해야합니다. 이 옵션을 활성화 한 상태에서 당기면 충돌을 해결해야하며 자식은 자동 병합되지 않습니다. 실제로 git status는 수정 사항 만 숨 깁니다 ( 플래그 된 파일은 표시되지 않음).

나는 한동안 변경 사항 추적을 중지하고 싶을 때 + 같은 수정 git commit -a과 관련된 많은 파일 ( )을 커밋 하려고합니다 .

사용 사례 skip-worktree

친구가 설정에 따라 변경해야하는 매개 변수 (예 : 비밀번호 포함)가 포함 된 설정 클래스가 있습니다.

  • 1 :이 클래스의 첫 번째 버전을 작성하고 채울 수있는 필드를 채우고 다른 클래스는 비워 둘 수 있습니다.
  • 2 : 커밋하여 원격 서버로 푸시합니다.
  • 삼: git update-index --skip-worktree MySetupClass.java
  • 4 : 자신의 매개 변수로 구성 클래스를 업데이트하십시오.
  • 5 : 다른 기능에 대한 작업으로 돌아가십시오.

수정 사항은 지점에 관계없이 수행됩니다. 경고 : 친구가이 클래스를 수정하려면 동일한 설정을 가져야합니다. 그렇지 않으면 수정 사항이 원격 저장소로 푸시됩니다. 파일을 가져올 때 파일의 원격 버전이 사용자 파일을 덮어 씁니다.

추신 : 바람직하지 않은 부작용이 있기 때문에 둘 중 하나를 수행하십시오. 다른 플래그를 사용하려면 먼저 플래그를 비활성화해야합니다.


7

Git에게 로컬 파일 / 폴더의 변경 사항을 추적하지 말라고 지시하려면 (git 상태가 변경 사항을 감지하지 못함을 의미합니다)

git update-index --skip-worktree path/to/file

그리고 Git에게 로컬 버전의 변경 사항을 다시 한 번 추적하도록 변경하려면 (변경 사항을 커밋 할 수 있음) 다음을 수행하십시오.

git update-index --no-skip-worktree path/to/file

1

한 줄 답변 git update-index --assume-unchanged [path]

중앙 저장소 및 로컬 저장소에 파일이있을 때마다이 파일을 사용하십시오. 파일을 변경해야하지만 중앙 저장소에 스테이징 / 커밋해서는 안됩니다. 이 파일은에 추가해서는 안됩니다 .gitignore. 시스템 관리자가 도입 한 경우 파일의 새로운 변경 사항이 있기 때문에 선임 개발자는 모든 로컬 저장소에 배포해야합니다.

가장 좋은 예 : DB 연결을위한 구성 파일 . 중앙 저장소에는 프로덕션 DB 서버의 값이있는 모든 사용자 이름, 비밀번호, 호스트, 포트가 있습니다. 그러나 로컬 개발자에서는 로컬 또는 다른 개발 DB 서버 (팀이 설정 한) 만 사용해야합니다. 이 경우 구성 파일을 변경하고 싶지만 중앙 저장소에 커밋해서는 안됩니다.

베스트


0

각 파일을 개별적으로 선택하지 않고 특정 폴더 또는 bin 폴더의 모든 파일 을 제거하는 방법을 묻고 있다고 가정합니다 .

이 명령을 사용할 수 있습니다

git rm -r -f /<floder-name>\*

. 해당 디렉토리의 상위 디렉토리에 있는지 확인하십시오.
이 명령은 bin / 또는 build / 폴더에있는 모든 파일을 재귀 적으로 "삭제"합니다. delete라는 단어는 git이 해당 파일이 "삭제 된"것으로 가장하고 해당 파일이 추적되지 않는다는 것을 의미합니다. git은 실제로 해당 파일을 삭제 모드로 표시합니다.

다음 커밋에 .gitignore가 준비되어 있는지 확인하십시오.
문서 : git rm


0

작동 순서에 따라 문제가 발생할 수 있습니다. .gitignore를 먼저 수정 한 다음 git rm --cached xxx를 수정 한 경우이 문제가 계속 발생해야합니다.

올바른 해결책 :

  1. git rm-캐시 xxx
  2. .gitignore를 수정했습니다.

불변의 주문!

수정 후 .gitignore 다시로드!


0

git tacking에서 단일 파일을 제거하려고한다고 가정합니다. 이를 위해 아래 명령을 권장합니다.

git update-index-가정하지 않은 것으로 가정

예-git update-index-변경되지 않은 것으로 가정합니다 .gitignore .idea / compiler.xml


0

디렉토리의 모든 파일 (특정 유형의)에 대한 변경 사항을 무시하려면 이러한 접근법 중 일부를 결합해야했습니다. 그렇지 않으면 파일이 이전에 존재하지 않은 경우 파일이 만들어졌습니다.

아래에서 "excludedir"은 변경 사항을보고 싶지 않은 디렉토리의 이름입니다.

먼저, 파일 시스템에서 제거하지 않고 변경 내용 추적 캐시에서 기존의 새 파일을 제거하십시오.

git status | grep "new file:" | cut  --complement -d " " -f1-4 | grep "^excludedir" | xargs git rm --cache

당신도 같은 작업을 수행 할 수 있습니다 modified:. 새 파일 이름에 대한 renamed:포스트 ->비트 를보고 아래 ->설명 된대로 프리 비트를 수행해야하므로 조금 더 복잡 deleted:합니다.

deleted: 로컬 시스템에 존재하지 않는 파일의 색인을 업데이트 할 수 없으므로 파일이 좀 더 복잡해집니다.

echo .deletedfiles >> .gitignore
git status | grep "deleted:" | cut  --complement -d " " -f1-4 | grep "^excludedir" > .deletedfiles
cat .deletedfiles | xargs -d '\n' touch
cat .deletedfiles | xargs -d '\n' git add -f
cat .deletedfiles | xargs -d '\n' git update-index --assume-unchanged
cat .deletedfiles | xargs -d '\n' rm

위 목록의 마지막 명령은 파일 시스템에서 파일을 다시 제거하므로 생략하십시오.

그런 다음 해당 디렉토리에서 변경 내용 추적을 차단하십시오.

git ls-files excludedir/ | xargs git update-index --skip-worktree
git update index --skip-worktree excludedir/

0

답변 에는 거의 git command-free 접근법 이 제공되었습니다 .

무시하기 위한 특정 파일 의 모든 지역의 repo :

  1. 파일 작성 ~/.gitignore_global에 의해, 예를 touch ~/.gitignore_global터미널이다.
  2. git config --global core.excludesfile ~/.gitignore_global한 번만 실행하십시오 .
  3. 무시하려는 파일 / 디렉토리 경로를에 기록하십시오 ~/.gitignore_global. 예를 들어 modules/*.H, 작업 디렉토리에 있다고 가정합니다 $WORK_DIR/modules/*.H.

무시하기 위한 특정 파일을 하나의 지역 REPO를 :

  1. .git/info/excluderepo 내에서 파일에 대해 위의 세 번째 단계를 수행하십시오 . 즉 무시하려는 파일 / 디렉토리 경로를 작성하십시오 .git/info/exclude. 예를 들어 modules/*.C, 작업 디렉토리에 있다고 가정합니다 $WORK_DIR/modules/*.C.

0

현재 / 미래에 .gitignore 적용

이 방법은 표준 .gitignore 동작을 적용 하며 무시해야 할 파일을 수동으로 지정할 필요가 없습니다 .

--exclude-from=.gitignore더 이상 사용할 수 없습니다 : /-업데이트 된 방법은 다음과 같습니다.

일반적인 조언 : 정리 된 저장소로 시작하십시오 – 커밋 된 모든 것, 작업중인 디렉토리 나 인덱스에 보류중인 것 없음, 백업을 만드십시오 !

#commit up-to-date .gitignore (if not already existing)
#this command must be run on each branch
git add .gitignore
git commit -m "Create .gitignore"

#apply standard git ignore behavior only to current index, not working directory (--cached)
#if this command returns nothing, ensure /.git/info/exclude AND/OR .gitignore exist
#this command must be run on each branch
git ls-files -z --ignored --exclude-standard | xargs -0 git rm --cached

#optionally add anything to the index that was previously ignored but now shouldn't be:
git add *

#commit again
#optionally use the --amend flag to merge this commit with the previous one instead of creating 2 commits.

git commit -m "re-applied modified .gitignore"

#other devs who pull after this commit is pushed will see the  newly-.gitignored files DELETED

브랜치의 커밋 히스토리에서 새로 무시 된 파일을 제거해야 하거나 새로 무시한 파일을 향후 풀에서 삭제하지 않으려면 이 답변을 참조하십시오 .


-1

오랫동안 검색 한 후에는 방법을 찾으십시오. .gitconfig안드로이드 스튜디오 프로젝트의 .like와 같은 git 명령 별칭을 체크 아웃하기 전에 구성 파일을 되 돌린 다음 건너 뛰십시오. 체크 아웃 후 sed구성 파일을 로컬 구성으로 변경하십시오. checkoutandmodifylocalproperties = !git update-index --no-skip-worktree local.properties && git checkout local.properties && git checkout $1 && git update-index --skip-worktree local.properties && sed -i '' 's/.*sdk.dir.*/sdk.dir=\\/Users\\/run\\/Library\\/Android\\/sdk/g' local.properties && :

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