이동되거나 이름이 바뀐 파일에서 git diff를 수행하는 방법은 무엇입니까?


128

을 사용하여 파일을 옮겼습니다 git mv. 이제 새 파일을 다른 파일과 비교하여 이전 파일 (이전의 존재하지 않는 이름으로)과 비교하고 싶습니다.

어떻게해야합니까?


4
곧 (git 2.9, 2016 년 6 월) 간단 git diff -- yourRenamedFile합니다. 아래 답변을
VonC

답변:


145

diff 할 때 git이 이동 된 파일을 자동 감지하도록하려면 -M을 사용해야합니다. git diffknittl 언급 한대로 사용하면 효과가 없습니다.

간단히 말해서 git diff -M해야합니다.

이 스위치의 설명서는 다음과 같습니다.

-M[<n>], --find-renames[=<n>]
       Detect renames. If n is specified, it is a threshold on the similarity index 
       (i.e. amount of addition/deletions compared to the file’s size). For example, 
       -M90% means git should consider a delete/add pair to be a rename if more than
       90% of the file hasn’t changed.

7
생명의 은인! 내 자식 차이가 훨씬 좋아졌습니다. 1)이 옵션을 항상 사용하는 것이 안전합니까? 2)이 옵션을 기본 동작으로 추가 할 수 있습니까 ~/.gitconfig?
kevinarpe

5
이름 바꾸기 감지는 이전 파일과 새 파일이 모두에서 처리하는 파일 모음에 나타나는 경우에만 작동합니다 git diff. git diff -M이름이 바뀐 단일 파일에서 실행 해도 이름이 변경되지 않습니다.
Leon

1
이것은 나를 위해 작동하지 않지만 git log --follow -- file_after_move.txt잘 작동합니다. 이동 전을 포함한 전체 역사를 보여줍니다. 어떤 아이디어? 나는 달리고있다 git version 2.11.0.windows.1.
bouvierr

1
-C사본을 검출하기위한 옵션이 유용과 유사하다. 나는 -M하나의 파일을 두 개로 리팩토링 한 diff (원본과 이름이 일치하지 않는)를 볼 때 사용했습니다.
cp.engr

85

knittl이 쓴 것 외에도 항상 다음을 사용할 수 있습니다.

git diff HEAD:./oldfilename newfilename

여기서 HEAD:./oldfilename현재 디렉토리를 기준으로 마지막 커밋 (HEAD의)에서 oldfilename을 의미합니다.

새로운 자식이 없다면 대신 사용해야합니다.

git diff HEAD:path/to/oldfilename newfilename

8
고마워 또한 헤드 대신 특정 커밋을 지정할 수도 있습니다.git diff 39fa7c77e85c51d43ea0cf30d33aec8721812e9e:./oldfilename newfilename
Chris Bloom

8
명확하지 않은 경우 분기 이름이나 다음과 같은 다른 참조를 지정할 수도 있습니다.git diff branch:old/filen.name newfilename
jricher

첫 번째 양식은 cd디렉토리에 있고 쌍 --앞에 추가하지 않으면 저에게 효과적입니다 commit:path. Git은 문법이 매우 까다로워 보입니다.
dhardy

1
@dhardy <commit-ish>:<pathname>문법은 Git-ish라는 객체 식별자입니다. 후 --힘내 파일 이름 만 기대하고있다.
Jakub Narębski

18

git 2.9 (2016 년 6 월)를 사용하면 -M더 이상 추가 할 필요가 없습니다. 기본적으로 git diff사용 -M합니다.

참조 5404c11 커밋 , 9501d19 커밋 , a9276a6 커밋 , f07fc9e 커밋 , 62df1e6 커밋 에 의해 (2016년 2월 25일) 마티유 Moy와을 ( moy) .
( Junio ​​C gitsterHamano 에 의해 합병 -- 커밋 5d2a30d , 2016 년 4 월 3 일)

diff: diff.renames기본적으로 활성화

이름 변경 감지는 매우 편리한 기능이며, 새로운 사용자는이를 활용하기 위해 설명서를 파헤칠 필요가 없습니다.

이름 변경 감지를 활성화하는 데 대한 반대 의견은 때때로 실패하고 때로는 느리다는 것입니다. 그러나 " git status"및 " git merge" 와 같은 여러 경우에 기본적으로 이름 바꾸기 감지가 이미 활성화되어 있으므로 활성화 diff.renames해도 기본적으로 상황이 변경되지는 않습니다. 이름 변경 감지에 실패하면 이제 " git diff"와 " git status" 간에 일관되게 실패합니다 .

이 설정은 배관 명령에 영향을 미치지 않으므로 잘 작성된 스크립트에는 영향을 미치지 않습니다.

이 기능에 대한 새로운 테스트는 다음과 같습니다 .


1

git diff -M다른 사람들이 말한 것처럼 이름 바꾸기 감지를 활성화합니다 (@VonC가 지적했듯이 기본적으로 git 2.9에서 활성화됩니다). 그러나 대규모 변경 세트가있는 경우 부정확 한 이름 변경 감지 기능이 여전히 다시 꺼질 수 있습니다. Git은 다음과 같은 경고를 표시하는데, 사용자가보고있는 diff 중에 놓치기 쉽습니다.

warning: inexact rename detection was skipped due to too many files.
warning: you may want to set your diff.renameLimit variable to at least 450 and retry the command.

이 경우 git에서 제안한대로 구성 옵션을 설정하십시오 (예 :

git config diff.renamelimit 450

diff 명령을 다시 실행하십시오.


0

어떤 이유로 든 HEAD:./oldfilename(또는 절대 경로)를 사용하면 효과가 HEAD:oldfilename없었지만 (cmn 덕분에)

git diff HEAD:oldfilename newfilename
git diff 2a80f45:oldfilename f65f3b3:newfilename

HTH


아마도 당신의 자식은 너무 오래되어 이해할 수 HEAD:./oldfilename없습니까?
Jakub Narębski

-4

git diff인수없이 간단히 실행 하십시오 git diff -- newfilename. git은 올바른 파일 / 콘텐츠를 비교할 수있을 정도로 똑똑합니다 (예 : 이름을 바꾸기 전의 원래 내용을 이름을 바꾼 후 변경된 내용으로)


2
git은 대부분의 경우 똑똑하지 않습니다. 단순히 git mv하나의 파일을 만든 다음 단계적 상태를 다른 동일 지점과 비교하면 " -M사용 하지 않는 한"모든 항목이 삭제되었다가 다시 작성됩니다 "diff 가 생성됩니다.
Reinderien
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.