git으로 이름이 바뀐 파일의 로그를 실제로 표시하는 방법은 무엇입니까?


132

나는 git을 처음 접했고 이전에는 Subversion을 사용했습니다.

파일 이름이 바뀌면 대부분의 그래픽 git 프론트 엔드 및 IDE 플러그인이 파일 기록을 표시 할 수없는 것으로 나타났습니다. 내가 사용할 때

git log --follow

명령 줄에서 이름을 바꾸면 전체 로그를 볼 수 있습니다.

Linus Torvalds에 따르면 --follow 스위치는 "SVN noob"입니다. 심각한 git 사용자는 사용하지 않습니다.

--follow는 어쨌든 부모 또는 훌륭한 수정 그래프와 같은 것에 대해 전혀 알지 못하는 전 SVN 사용자를 만족시키기위한 총 핵입니다.

완전히 기본적이지는 않지만 현재 "--follow"구현은 실제로 필수적인 것이 아니라 개정 워킹 로직에 기반을 둔 빠른 전처리 작업입니다.

문자 그대로는 "실제 git 기능"이 아닌 "SVN noob"지원 프로그램으로 설계되었습니다. 아이디어는 당신이 큰 그림에서 물질의 이름을 바꾸는 (깨진) 사고의 사고 방식에서 벗어날 것이라는 것이 었습니다.

내 질문 : 하드 코어 git 사용자는 파일 이름을 바꿀 때 어떻게 파일의 기록을 얻습니까? 이것을하는 '실제'방법은 무엇입니까?


17
@ 데이비드 홀 : git mv oldfile newfile이름 바꾸기가 기록 발생하지 않습니다 모두에서 - 그것은 단지 하나 개의 파일을 삭제하고 다른를 추가하는 것과 동일합니다. git은 사실 이후에 커밋 할 때마다 트리 상태에서 이름 바꾸기와 사본 만 처리합니다.
Mark Longair

20
@David Hall : git 외부의 다른 도구 (예 :)를 사용하여 파일의 이름을 바꾸면 결과는 /bin/mv oldfile newfile~와 다를 git add newfile; git rm oldfile수 없습니다 git mv oldfile newfile.
Mark Longair

1
파일을 새 리포지토리로 옮길 경우이 이데올로기가 분리됩니다.이 경우 전체 기록 을 이동할 수없는 것이 큰 문제 일 수 있습니다. 물론 복잡한 프로젝트에서 파일과 함께 제공 할 수있는 실제 기록의 양에는 한계가 있습니다.
Roman Starkov

1
참고 : git log --followgit 2.9 (2016 년 6 월)로 비트가 향상되었습니다. 아래 답변을
VonC

1
2.15 버전의, 당신은 실험 할 수 있습니다 --color-moveddiff.
Michael

답변:


71

나는 Linus가 주장하는 일반적인 드라이브는 소금 한 덩어리로 이것을 받아 들인다는 것입니다. 하드 코어 git 사용자는 "파일"의 역사에 대해 신경 쓰지 않습니다. 내용 전체가 의미있는 기록을 가지고 있기 때문에 내용을 git 저장소에 넣습니다.

파일 이름 바꾸기는 경로 사이를 이동하는 작은 "콘텐츠"의 특별한 경우입니다. git 사용자가 기능적으로 "pickaxe"로 추적 할 수있는 파일 사이를 이동하는 기능이있을 수 있습니다 (예 :) log -S.

다른 "경로"변경에는 파일 결합 및 분할이 포함됩니다. git은 실제로 이름을 바꾼 파일과 복사 (또는 이름을 바꾸고 삭제 한 것으로 간주)하는 파일은 트리의 전체 내용을 추적합니다.

git은 많은 버전 제어 시스템이 매우 파일 중심적인 곳에서 "전체 트리"사고를 권장합니다. 이것이 바로 git이 "filenames"보다 "paths"를 더 자주 참조하는 이유입니다.


찰스 안녕, 답변 주셔서 감사합니다. SVN을 사용하는 것과 같은 방식으로 git을 사용하는 것 같습니다. git이 다른 버전 제어 시스템과는 매우 다르다는 것을 이해하지만 git의 많은 개념이 아직 이상하게 보입니다 ... 아마도 최근에 구입 한 git book을 끝내야 할 것입니다.
Mike

24
Linus의 요점은 "적절한"GUI가 파일 전체에서 코드 덩어리를 추적 할 수 있다는 것이며, 지금까지 그러한 도구가 있기를 바랐습니다. 불행히도, 우리는 여전히 그 사치가 없으며 --follow가 여전히 유용합니다.
Michael Parker

11
git은 실제로 --follow이것 이외의 솔루션을 제공합니까 ?
Griwes

13
나는 "전체 트리"사고가 --follow기본이 됨으로써 향상된다고 주장한다 . 내 말은 파일 내에서 코드의 기록을보고 싶을 때 실제로 파일의 이름이 바뀌 었는지 여부를 신경 쓰지 않고 이름 바꾸기에 관계없이 코드 기록을보고 싶습니다. 제 생각에는 --follow개별 파일에 신경 쓰지 않기 때문에 기본값이되는 것이 합리적입니다 . --follow일반적으로 매우 중요하지 않은 개별 파일 이름 바꾸기를 무시하는 데 도움이됩니다.
Eddified

2
그래서 ... 파일 대신 "콘텐츠"에 관심이 있다면, 현재이 파일에있는 콘텐츠와 관련된 커밋을 어떻게 인쇄합니까? git이 나를 위해 다른 파일에서 모두 추적하고 모든 변경 사항에 대한 로그를보고하면 기뻐할 것입니다. 어떻게 얻는 지 알 수 없습니다.
Ed Avis

36

당신이 직면 한 것과 정확히 같은 문제가 있습니다. 답을 드릴 수는 없지만 Linus가 2005 년에 작성한 이 이메일을 읽을 수 있다고 생각합니다 . 이는 매우 적절하며 문제를 처리하는 방법에 대한 힌트를 줄 수 있습니다.

… 이름 변경이 중요하지 않기 때문에 내부 이유로 인해 (즉 효율적인 델타를 허용하기 위해) 이름 변경을 추적하지 않는 SCM은 근본적으로 손상되었다고 주장합니다. 그들은 당신을 돕지 않으며, 당신이 어쨌든 관심이없는 것이 아닙니다 .

중요한 것은 "이것이 어디에서 왔는가"를 찾는 것이며, git 아키텍처는 실제로 다른 어떤 것보다 훨씬 좋습니다. …

이 블로그 게시물에서 참조한 것으로 실용적인 솔루션을 찾는 데 유용 할 수 있습니다.

이 메시지에서 Linus는 이상적인 콘텐츠 추적 시스템을 통해 어떻게 코드 블록이 현재 형태로 만들어 졌는지 알 수있었습니다. 파일의 현재 코드 블록에서 시작하여 기록으로 돌아가 파일을 변경 한 커밋을 찾습니다. 그런 다음 커밋의 변경 사항을 검사하여 파일을 변경하는 커밋이 관심있는 코드 블록에 닿지 않을 수 있으므로 커밋 된 코드 블록이 수정되었는지 확인하십시오. 파일.

커밋 전에 파일에 코드 블록이 존재하지 않는 것을 발견하면 커밋을 더 자세히 검사합니다. 다음과 같은 여러 가지 가능한 상황 중 하나 일 수 있습니다.

  1. 커밋은 실제로 코드 블록을 도입했습니다. 그 커밋의 저자는 당신이 그 기원 (또는 버그를 도입 한 유죄 자)을 위해 사냥하고 있던 멋진 기능의 발명가였습니다. 또는
  2. 코드 블록은 파일에 존재하지 않았지만 5 개의 동일한 사본이 다른 파일에 존재했으며 모두 커밋 후에 사라졌습니다. 커밋의 작성자는 단일 도우미 함수를 도입하여 복제 된 코드를 리팩토링했습니다. 또는
  3. (특별한 경우) 커밋 전에 현재 관심있는 코드 블록이 포함 된 파일은 존재하지 않았지만 내용이 거의 동일한 다른 파일이 있었고 관심있는 코드 블록은 파일의 다른 모든 내용과 함께 그 당시 존재했지만 다른 파일에 존재했습니다. 커밋 후에 사라졌습니다. 커밋 작성자는 파일 이름을 약간만 변경하면서 파일 이름을 변경했습니다.

git에서는 Linus의 궁극적 인 콘텐츠 추적 도구가 아직 완전히 자동화 된 방식으로 존재하지 않습니다. 그러나 중요한 성분의 대부분은 이미 사용 가능합니다.

이에 대한 진행 상황을 계속 알려주십시오.


해당 기사를 게시 해 주셔서 감사합니다. 컨텐츠 히스토리에 대한 아이디어를 완전히 이해했다는 것을 읽을 때까지는 아니 었습니다!. 나는 이것에 대해 잘못 생각하고 있습니다!
DavidG

Linus의 이메일은 훌륭합니다. 이것을 게시 해 주셔서 감사합니다.
mik01aj

재미있는 사실, Git v2.15는--color-moved "이상적인 추적 시스템"으로 나아가는 것을 추가 합니다. 파일 내에서 움직 인 줄을 추적하기 위해 그것을 가지고 놀고 있었지만 실수로 전체 diff
Michael

2
Linus는 복잡한 상황을 설명합니다. 그러나 여기에는 간단한 상황이 있습니다. 파일 이름이 방금 변경되었거나 다른 디렉토리로 이동되었습니다. 따라서 간단한 해결책이 있어야합니다. 문제는 Subversion과 반대되는 사실에서 비롯된 것으로 생각합니다. 사용자는 파일이있는 커밋 시간에 Git에 지시 --follow할 수 없으며 잘못 될 수 있습니다 (예 : 두 파일이 동일한 내용을 가지고 있거나 수정이있는 경우) 파일 이동과 함께).
vinc17

13

파일 이름이 바뀌면 대부분의 그래픽 git 프론트 엔드 및 IDE 플러그인이 파일 기록을 표시하지 못하는 것으로 나타났습니다.

인기있는 Git UI 도구가 이제이를 지원한다는 사실을 알게되어 기쁩니다. 사용 가능한 수십 개의 Git UI 도구가 있으므로 모두 나열하지는 않지만 예를 들면 다음과 같습니다.

  • SourceTree는 파일 로그를 볼 때 왼쪽 하단에 "이름이 바뀐 파일 따르기"체크 상자가 있습니다
  • TortoiseGit의 왼쪽 하단에있는 로그 창에 "이름 바꾸기"확인란이 있습니다.

Git UI 도구에 대한 추가 정보 :


소스는 한 번 이름을 바꿀 때, 두 번 이름을 바꿀 때 이름을 바꾸기 전에 커밋에 대한 변경 정보를 사용할 수없는 경우에 효과적입니다. 여기에 버그가보고되었습니다 : jira.atlassian.com/browse/SRCTREE-5715
Intel

gitk는 파일 이름이 두 번 기록 된 경우에도 잘 작동합니다. 명령어는 "gitk --follow path / to / file"
Intel

6

참고 : git 2.9 (2016 년 6 월)는 다음과 같은 "버기"특성을 상당히 향상시킵니다 git log --follow.

SZEDER Gábor ( )의 commit ca4e3ca (2016 년 3 월 30 일)를 참조하십시오 . ( Junio ​​C Hamano의해 합병 -- 커밋 26effb8 , 2016 년 4 월 13 일)szeder
gitster

diffcore : 이름 바꾸기 감지 중에 동일한 파일의 반복 순서 수정

두 경로 ' dir/A/file'와 ' dir/B/file'의 내용이 동일하고 상위 디렉토리의 이름이 ' git mv dir other-dir'와 diffcore같이 바뀌면 다음과 같은 정확한 이름 변경 을 보고합니다.

renamed:    dir/B/file -> other-dir/A/file
renamed:    dir/A/file -> other-dir/B/file

(반전을 참고하십시오 : B/file -> A/fileA/file -> B/file)

기술적으로 잘못되지는 않았지만 사용자뿐만 아니라 이름 변경 정보를 기반으로 결정을 내리는 git 명령 (예 : 이름 변경 후 ' git log --follow other-dir/A/file'follow ' dir/B/file') 도 혼동됩니다 .

이 동작은 커밋 v2.0.0-rc4 ~ 8 ^ 2 ~ 14의 부작용입니다 ( diffcore-rename.c: 정확한 이름 바꾸기 찾기, 2013-11-14) : 소스를 저장하는 해시 맵은 동일한 버킷 (예 : 현재 대상과 일치하는 소스)에서 항목을 반환합니다. , LIFO 순서로.
따라서 반복은 먼저 ' other-dir/A/file'및 ' dir/B/file'를 검사 하고 동일한 컨텐츠 및 기본 이름을 찾으면 정확한 이름을보고합니다.


2

Linux에서 SmartGit 및 GitEye가 특정 파일의 히스토리를 따를 때 이름 바꾸기를 따를 수 있음을 확인했습니다. 그러나 gitk 및 GitEye와 달리 SmartGit은 별도의 파일보기 및 저장소보기 (디렉토리 구조는 포함하지만 그 안에 포함 된 파일 목록은 포함하지 않음)를 표시합니다.

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