rsync 제외 .gitignore & .hgignore & svn : ignore like --filter = : C


113

Rsync에는 --cvs-exclude"CVS와 동일한 방식으로 파일을 무시" 할 수 있는 멋진 옵션 이 포함되어 있지만 CVS는 수년 동안 사용되지 않았습니다. 최신 버전 제어 시스템 (Git, Mercurial, Subversion)에서 무시되는 파일을 제외 할 수있는 방법이 있습니까?

예를 들어 GitHub에서 많은 Maven 프로젝트를 체크 아웃했습니다. 일반적으로 .gitignore최소한 target기본 Maven 빌드 디렉토리 (최상위 또는 하위 모듈에있을 수 있음) 목록을 포함합니다. 이 디렉토리의 내용은 완전히 폐기 가능하고 소스 코드보다 훨씬 클 수 있으므로 백업에 rsync를 사용할 때 제외하고 싶습니다.

물론 명시 적으로 할 수는 --exclude=target/있지만 이름이 지정 target되고 무시되지 않아야 하는 관련없는 디렉토리를 실수로 억제 합니다.

그리고 나는 어떤에서 언급 된 모든 파일 이름과 패턴에 대한 절대 경로의 전체 목록을 제공 할 수 있습니다 .gitignore, .hgignore또는 svn:ignore내 디스크의 특성,하지만이 스크립트의 일종으로 생산되어야 할 것이다 거대한 목록이 될 것입니다.

rsync에는 CVS 이외의 VCS 체크 아웃에 대한 내장 지원이 없기 때문에 무시 패턴을 제공하는 좋은 트릭이 있습니까? 아니면 사용자 스크립트가 주어진 파일 / 디렉토리를 포함해야하는지 여부를 물을 수있는 일종의 콜백 시스템입니까?

업데이트 : --filter=':- .gitignore'LordJavac에서 제안한 것처럼 --filter=:C구문이 정확히 일치하는지 확실하지 않지만 적어도 내가 찾은 예제에서는 CVS와 마찬가지로 Git에서도 작동하는 것 같습니다 . --filter=':- .hgignore'Mercurial에서는 잘 작동하지 않습니다. 예를 들어 (Git의 Mercurial에 해당 .hgignore하는) 라인을 포함하는 것은 rsync에 의해 정규 표현식으로 인식되지 않습니다. 그리고 Subversion에서는 작동하지 않는 것 같습니다 . 1.6 이전의 작업 복사본에 대해서는 구문 분석해야 하고 1.7 이상의 작업 복사본에 대해서는 당황스럽게 손을 내 밀어야합니다.^target$/target/.svn/dir-prop-base


11
사운드는 같은 비트 등 .gitignore에 대한 지원을 추가 rsync에 대한 패치를 제출하는 것이 좋습니다, .hgignore 될 것
ThiefMaster

3
@ThiefMaster : 시작점으로 bugzilla.samba.org/show_bug.cgi?id=9744 를 제출했습니다 .
Jesse Glick

2
다른 사용자를위한 참고 사항입니다. .gitignore는 명령이 실행되는 디렉토리가 아니라 rysnc'd되는 폴더 계층 구조에 있어야합니다
myol

:-정확히 무슨 뜻입니까? 콜론은 무엇을 의미합니까? 무슨 대시?
David

Git에는 check-ignore"무시되지 않은 모든 파일 목록 생성"옵션을 사용하려는 경우 다양한 "무시"파일을 구문 분석하는 어려운 작업을 처리 할 수 있는 하위 명령이 있습니다. 여기 내 대답 은 그 방법에 대한 세부 정보를 제공합니다.
cjs

답변:


120

luksan이 언급했듯이 --filter스위치를 rsync. 나는 이것을 달성 --filter=':- .gitignore'알려줍니다 ( ".gitignore"앞에 공백있다) rsync와 디렉토리 병합 할 .gitignore파일과 그들이 자식의 규칙에 따라 제외 가지고가. 전역 무시 파일이있는 경우 추가 할 수도 있습니다. 더 쉽게 사용할 수 있도록 rsync필터가 포함 된 별칭을 만들었습니다 .


Git 만 다루기 때문에이 답변을 "수락"하는 것을 주저하지만 좋은 시작입니다.
Jesse Glick

23
또한 제외 파일을 .git 더 자세한 버전 :--exclude='/.git' --filter="dir-merge,- .gitignore"
VasiliNovikov

2
나는 지금 다음과 같은 것을 가지고있다 : rsync -rvv --exclude='.git*' --exclude='/rsync-to-dev.sh' --filter='dir-merge,-n /.gitignore' $DIR/ development.foobar.com:~/test/.. 그러나 그것이라고되어 ​​있지만 [sender] hiding file .gitignore because of pattern .git*, 파일은 여전히 ​​desintation으로 보내진다
rolandow

2
--delete옵션 도 사용하려면 다음과 같은 작업 명령 줄이 rsync --delete-after --filter=":e- .gitignore" --filter "- .git/" -v -a ...있습니다.. 시간이 좀 걸렸고 ... e필터에서 --delete-after둘 다 중요합니다. rsync맨 페이지의 "디렉토리 별 규칙 및 삭제"장을 읽어 보시기 바랍니다 .
dbolotin

1
삭제 및 추가 및 업데이트를 동기화하려면 --delete-after@VasiliNovikov의 명령 버전에 추가 하기 만하면 됩니다. (이 명령은 @dboliton의 명령 버전과 동일합니다. 단, @db는 : e를 사용합니다. 단, .gitignore 파일이 복사되는 것을 제외한다고 생각합니다. 이것은 제가 원하는 것이 아닙니다.)
Bampfer

10

git ls-files저장소의 .gitignore파일 에서 제외 된 파일 목록을 작성하는 데 사용할 수 있습니다 . https://git-scm.com/docs/git-ls-files

옵션 :

  • --exclude-standard모든 .gitignore파일을 고려 하십시오.
  • -o 단계적이지 않은 변경 사항을 무시하지 마십시오.
  • -i 무시 된 파일 만 출력합니다.
  • --directory 전체 디렉토리가 무시되는 경우에만 디렉토리 경로를 출력하십시오.

내가 무시할 유일한 것은 .git.

rsync -azP --exclude=.git --exclude=`git -C <SRC> ls-files --exclude-standard -oi --directory` <SRC> <DEST>

4
이것은 작동하지 않습니다. git 하위 명령에서 첫 번째 파일을 제외하고 나머지는 SRC 목록의 일부로 처리합니다. 이 작동합니다 : rsync -azP --exclude-from="$(git -C SRC ls-files --exclude-standard -oi --directory > /tmp/excludes; echo /tmp/excludes)" SRC DEST
마라톤

2
이 방법은 제외 및 포함 줄 이 모두있는 경우에 작동하는 유일한 방법입니다 .gitignore(예 :으로 시작하는 줄 !). 또한 리포지토리에 --force추가 한 파일을 rsyncs 하는데 이는 일반적으로 좋은 것입니다.
ostrokach

1
실제로이 답변은 작동하지 않으므로 작동하는 답을 작성했습니다. stackoverflow.com/a/50059607/99834
sorin

6

방법은 rsync --exclude-from='path/.gitignore' --exclude-from='path/myignore.txt' source destination?
그것은 나를 위해 일했습니다.
나는 당신도 더 많은 --exclude-from매개 변수를 가질 수 있다고 믿습니다 .


3
당신의 이것은 한, 작동 .gitignore파일과 구문 호환 사용하는 일이 rsync.
Jesse Glick 2015 년

@JesseGlick이 맞습니다. rsync가 .gitignore 파일을 구문 분석 할 수 없습니다 . stackoverflow.com/a/50059607/99834 해결 방법을 참조하십시오 .
sorin apr

6

2018 년 솔루션 확인

rsync -ah --delete 
    --include .git --exclude-from="$(git -C SRC ls-files \
        --exclude-standard -oi --directory >.git/ignores.tmp && \
        echo .git/ignores.tmp')" \
    SRC DST 

세부 정보 : --exclude-from목록을 제외하는 대소 문자가 인수로 구문 분석되지 않을 가능성이 있으므로 --exclude 대신 필수입니다. 에서 제외하려면 파일이 필요하며 파이프로 작업 할 수 없습니다.

현재 솔루션은 제외 파일을 .git 폴더 안에 저장하여 git status자체 포함 상태로 유지하면서 영향 을 미치지 않도록합니다. 원한다면 / tmp를 사용할 수 있습니다.


3
동기화하려는 특정 Git 리포지토리 가있는 경우 (여기에서) 작동 할 것 같습니다. SRC그러나 제가 언급 한 원래 문제에 대해서는 작동하지 않는 것 같습니다.이 문제는 수천 개의 Git 리포지토리가 다양한 깊이의 하위 디렉터리로 확장 된 디렉터리입니다. 특이한 .gitignores.
Jesse Glick

1
프로세스 대체 (bash, zsh 등)를 지원하는 쉘을 사용하는 경우 다음을 사용할 수 있습니다.--exclude-from=<(git -C SRC ls-files --exclude-standard -oi --directory)
Roland W

3

들어 수은 당신이 사용할 수

hg status -i | sed 's/^I //' > /tmp/tmpfile.txt

.hgignore 제한으로 인해 수은으로 통제되지 않는 파일 목록을 수집 한 다음 실행

rsync -avm --exclude-from=/tmp/tmpfile.txt --delete source_dir/ target_dir/

무시 된 파일을 제외한 모든 파일을 재 동기화합니다. 공지 사항 -m 동기화에서 빈 디렉토리를 제외됩니다 rsync와의 플래그 때문에 HG 상태 -i 것 만 나열 제외 된 파일이 아닌 DIRS


2

이 시도:

rsync -azP --delete --filter=":- .gitignore" <SRC> <DEST>

'.gitignore'에있는 파일을 제외한 모든 파일을 원격 디렉터리에 복사하고 현재 디렉터리에없는 파일을 삭제할 수 있습니다.


1

rsync맨 페이지, 파일 패턴의 표준 목록에 추가 :

$ HOME / .cvsignore에 나열된 파일이 목록 및 CVSIGNORE 환경 변수에 나열된 모든 파일에 추가됩니다.

따라서 내 $ HOME / .cvsignore 파일은 다음과 같습니다.

.git/
.sass-cache/

.git 및 Sass에 의해 생성 된 파일을 제외합니다 .


2
반대로, .git/작업 복사본보다 훨씬 더 강력하게 디렉터리 를 포함하고 싶습니다 . 제외하고 싶은 것은 빌드 제품입니다.
Jesse Glick

또한이 설정은 이식 할 수 없습니다. 프로젝트 별이 아니라 사용자 별입니다.
VasiliNovikov 2014

@JesseGlick .git / dirs를 포함하는 것에 대해 두 번째로 설명합니다. Git은 분산 SCM이므로 전체 로컬 저장소를 백업하는 것이 중요합니다.
Johan Boulé

1 / rsync이 답변에 인용 된 맨 페이지 의 문장 은 --cvs-exclude옵션을 설명 하므로 명시 적으로 사용해야합니다. 2 / .cvsignore프로젝트 별 무시를 위한 파일을 디렉토리에 생성 할 수 있습니다 . 3 / .git--cvs-exclude설명서에 따라을 사용할 때 이미 무시 되므로 $HOME/.cvsignore중복 되는 것처럼 보입니다.
Niavlys

1

매우 큰 .gitignore파일이 많았지 만 "순수 rsync"솔루션 중 어느 것도 저에게 효과가 없었습니다. 나는이 rsync 래퍼 스크립트를 작성했으며 .gitignore규칙을 완전히 존중하고 ( 하위 디렉토리에 !스타일 예외 및 .gitignore파일 포함 ) 나를 위해 매력적으로 작동했습니다.


를 통해 이것을 시도 locate -0e .gitignore | (while read -d '' x; do process_git_ignore "$x"; done)하지만 많은 문제가 있습니다. 같은 디렉토리에있는 파일 .gitignore/. 빈 줄과 주석이 잘못 해석되었습니다. .gitignore공백이있는 경로의 파일을 초크 합니다 ( Ubuntu 용 패키지 의 악당 /opt/vagrant/embedded/gems/gems/rb-fsevent-0.9.4/spec/fixtures/custom 'path/.gitignore은 신경 쓰지 마십시오 vagrant). Perl 스크립트로 더 잘 수행 할 수 있습니다.
Jesse Glick 2015 년

@JesseGlick 스크립트 내에서 함수를 호출하는 이유를 잘 모르겠습니다. rsync인용 / 공백을 처리하는 것이 그토록 고통스러운 특정 이유 때문에에 대한 드롭 인 대체물로 사용하기위한 것 입니다. gsync실패한 명령 줄 의 예 와 이와 .gitignore관련된 파일이 있으면 자세히 살펴 보겠습니다.
cobbzilla

rsync다양한 Git 저장소가 흩어져있는 전체 파일 시스템이 필요 합니다. 단일 저장소 를 동기화하는 경우 스크립트가 제대로 작동 할 수 있습니다 .
Jesse Glick 2015 년

1
네, 물론입니다. 명확하게하지 못해서 죄송합니다. 이 스크립트를 사용하면 repo 디렉토리 내에서 git repo 당 한 번씩 호출해야합니다.
cobbzilla 2015 년

0

rsync (1)의 MERGE-FILES FILTER RULES 섹션을 확인하십시오.

디렉터리 구조를 통과 할 때 .gitignore 파일을 포함하는 rsync --filter 규칙을 생성 할 수있는 것 같습니다.


0

제외 필터를 만드는 대신 git ls-filesrsync 할 각 파일을 선택 하는 데 사용할 수 있습니다 .

#!/usr/bin/env bash

if [[ ! $# -eq 2 ]] ; then
    echo "Usage: $(basename $0) <local source> <rsync destination>"
    exit 1
fi

cd $1
versioned=$(git ls-files --exclude-standard)
rsync --verbose --links --times --relative --protect-args ${versioned} $2

git ls-files줄 바꿈으로 구분 된 경로를 반환 하더라도 작동 합니다. 파일 이름에 공백이있는 버전을 지정한 파일이 있으면 작동하지 않을 수 있습니다.


0

대안 :

git ls-files -zi --exclude-standard |rsync -0 --exclude-from=- ...

git ls-files -zi --exclude-per-directory=".gitignore" |...

(rsync는 .gitignore를 부분적으로 만 이해합니다)


0

짧은 답변

rsync -r --info=progress2 --filter=':- .gitignore' SOURCE DEST/

매개 변수 의미 :

-r: 재귀

--info=...: 진행률 표시

--filter=...: .gitignore 파일에 나열된 규칙에 따라 제외

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