Git diff-이름 만 사용하고 해당 목록을 복사


151

두 개정판 사이에서 변경된 파일 목록을 얻고 싶습니다. 간단합니다.

git diff -–name-only commit1 commit2 > /path/to/my/file

그러나 나열된 모든 파일을 다른 곳에 복사하려면 어떻게해야합니까? 그리고 복사 된 파일에 대해 완전히 동일한 디렉토리 구조가 필요합니다.

예를 들어 파일을 수정하고 추가했습니다.

/protected/texts/file1.txt
/protected/scripts/index.php
/public/pics/pic1.png

/home/changes/변경되고 추가 된 모든 파일 을 갖고 싶습니다 .

/home/changes/protected/texts/file1.txt
/home/changes/protected/scripts/index.php
/home/changes/public/pics/pic1.png

1
나는 당신이 무엇을 달성하려고하는지 이해하지 못합니다 ... 다른 클론에 변경 사항을 전파합니까? 패치를 작성 하시겠습니까? 자식 저장소 외부에서 파일을 패치?
knittl

패치가 아니라 변경된 파일의 정확한 사본 구조. 패치처럼, 그러나 단단한 파일
BazZy

그리고 예, git 저장소 외부의 파일 패치-가장 가까운 대상 :)
BazZy

3
죄송합니다. 뭐? 파일 및 트리의 변경 사항을 캡처하고 재생하고 싶습니까? 그것은 패치입니다. git format-patch커밋 범위에 대해이 작업을 수행 할 수 있습니다.
knittl

1
git diff commit1 commit2 > my.patch다음 cd other/path; patch -p1 < my.patch. 파일의 전체 사본을 사용해야하는 이유는 무엇입니까? 패치가 적용되지 않을 수도 있습니다 생각, 따라서 다른 디렉토리가 정말 없습니다 때문이라면 commit1주, 당신이 정말로 복사한다고 모든 것을 으로부터 commit2상태 ...
Cascabel

답변:


118

내가 테스트 한 다음 명령을 시도하십시오.

$ cp -pv --parents $(git diff --name-only) DESTINATION-DIRECTORY

2
cp --parents힌트 주셔서 감사합니다 , 나는 그 옵션을 수년간 원했지만 그것이 존재한다는 것을 결코 알지 못했습니다! .. 분명히 그 어느 것도 찾아보기를 귀찮게하지 않았습니다.
Stephan Henningsen

2
--parents옵션을 cp사용할 수 없으므로 Mac에서는이 기능이 작동하지 않습니다 .
M. Justin

파일에 특이한 문자가있는 경우이를 사용하기위한 팁이 있습니까? 공백, 북유럽 문자
Halvor Holsten Strand

@HalvorStrand, 나는 그것을 테스트하지는 않았지만 IFS=$'\n'먼저 설정 하면 할 수 있습니다. (원래의 IFS 값을 엉망으로 만들지 않기 위해 서브 쉘에서 사용하는 것이 좋습니다.)
Wildcard

cp: cannot stat 'git diff --name-only': No such file or directoryWindows의 git bash에서 오류가 발생 했습니다. 내가 뭘 잘못하고 있죠? 대상 디렉토리가 존재 함
Shiva

14

다음은 잘 작동합니다.

git diff -z --name-only commit1 commit2 | xargs -0 -IREPLACE rsync -aR REPLACE /home/changes/protected/

추가 설명 :

  • -z와에 git diff --name-onlyNUL로 구분 된 파일의 출력 수단 목록은 파일 이름 그들에 이상한 문자가있는 경우에 대비, 대신 줄 바꿈의 바이트.

  • -0에이 xargs매개 변수의 NUL로 구분 된 목록으로 표준 입력을 해석했다.

  • -IREPLACE기본적으로 있기 때문에 필요 xargs의 끝에 매개 변수를 추가 할 rsync명령. 대신에, 그것은 나중에있는 곳에 두라고 말합니다 REPLACE. ( 이 서버 오류 답변 의 유용한 팁입니다 .)

  • -a에 매개 변수 rsync수단 권한, 소유권 등을 가능하면 보존한다. -R대상에서 파일을 만들 때 수단은 전체 상대 경로를 사용합니다.

업데이트 : 의 이전 버전 xargs을 사용하는 경우 -i대신 옵션 을 사용해야합니다 -I. 전자는 이후 버전에서 더 이상 사용되지 않습니다 findutils.


이상합니다-어떤 운영 체제를 사용하고 있습니까? 만약 그것이 리눅스 배포판이라면, 어떤 배포판 xargs --version입니까?
Mark Longair

1
아아, 그 버전의 xargs에서는 -i대신 사용해야 합니다.이 버전은 이후 버전에서 더 이상 사용되지 않습니다. 4.1은 현재 매우 오래되었습니다. 답변을 업데이트하겠습니다.
Mark Longair

@ Mark : -I일부 버전에서는 공백이 필요하다는 것을 읽은 것을 기억 -I REPLACE합니다. 대신 시도해보십시오 .
Mikel

신경 쓰지 마. 그것은 작동하지 않습니다. 2004 년 12 월에 릴리스 된 4.2.10 -I이후에만 지원됩니다 findutils.
Mikel

--diff-filter=d삭제 된 파일을 목록에서 제외 하려면 추가해야 합니다. 그렇지 않으면 오류를 변경 폴더에 복사하는 동안 오류가 발생합니다. 그렇지 않으면 큰 대답입니다. 감사!
taymless

11

하나의 라이너가 있습니다.

변경된 파일을 나열하고 * .zip으로 압축하십시오.

git diff --name-only | zip patched.zip -@

마지막으로 커밋 된 변경된 파일을 나열하고 * .zip으로 압축하십시오.

git diff --name-only HEAD~ HEAD | zip patched.zip -@

Windows를 사용하는 경우 sourceforge.net/projects/gnuwin32/files/zip
Radon8472

@ Radon8472 설치 sed.exe됩니까? 여전히 zip창문에서 찾을 수 없습니다.
Shiva

아니요, 링크가 sed가 아닌 zip.exe의 다운로드를 가리키고 있습니다. 명령 행에서 zip을 사용할 수 없으면 zip.exe가 설치된 폴더를 PATHenv 변수에 추가해야 합니다.
Radon8472

6
zip update.zip $(git diff --name-only commit commit)


2

완벽하게 작동합니다.

git diff 1526043 82a4f7d --name-only | xargs zip update.zip

git diff 1526043 82a4f7d --name-only |xargs -n 10 zip update.zip

1

cpio입력하기 쉽고 하드 링크를 만들고 파일 이름의 공백을 처리하는 사람은 아무도 없습니다 .

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