[git] Git-메서드 / 함수의 변경 내역을 보려면 어떻게해야합니까?

그래서 파일의 변경 내역을 보는 방법에 대한 질문을 찾았지만이 특정 파일의 변경 내역은 엄청나고 특정 방법의 변경에만 관심이 있습니다. 특정 방법에 대한 변경 내역을 볼 수 있습니까?

나는 이것이 코드를 분석하기 위해 git이 필요하고 분석이 다른 언어에 따라 다를 것이라는 것을 알고 있지만 메소드 / 함수 선언은 대부분의 언어에서 매우 비슷해 보이므로 누군가이 기능을 구현했다고 생각했습니다.

현재 작업중인 언어는 Objective-C이고 현재 사용중인 SCM은 git이지만이 기능이 SCM / 언어에 대해 존재하는지 알고 싶습니다.



답변

최근 버전의 git log학습 된 특수한 형태의 -L매개 변수 :

-L : <기능 이름> : <파일>

에서 제공하는 줄 범위 "<start>,<end>"(또는 함수 이름 regex <funcname>) 의 진화를 추적합니다 <file>. pathspec 제한자를 제공 할 수 없습니다. 이것은 현재 단일 개정에서 시작하는 걷기로 제한됩니다. 즉, 긍정적 인 개정 인수를 0 개 또는 1 개만 제공 할 수 있습니다. 이 옵션을 두 번 이상 지정할 수 있습니다.

만일이 “:<funcname>”대신에 부여 <start>하고 <end>는, 제 funcname에 줄의 범위를 나타내고, 일반 식된다 일치 <funcname>최대 funcname에 다음 라인. “:<funcname>”이전 -L범위 의 끝 (있는 경우)에서 검색하고 그렇지 않은 경우 파일 시작부터 검색합니다. “^:<funcname>”파일의 시작부터 검색합니다.

git log -L :myfunction:path/to/myfile.c, Git에게을 요청 하면 이제 해당 함수의 변경 내역을 기꺼이 인쇄합니다.


답변

사용은 git gui blame스크립트의 사용을 위해 열심히하고, 동안 git log -Ggit log --pickaxe방법 정의가 나타나거나 내가 그들에 대한 모든 변경 목록을 만들 수있는 방법을 발견하지 않은, 사라 때마다 당신을 보여줄 수있는 신체 당신의 방법을.

그러나 gitattributestextconv속성을 사용 하여이를 수행 하는 솔루션을 결합 할 수 있습니다 . 이러한 기능은 원래 바이너리 파일 작업을 돕기위한 것이지만 여기에서도 잘 작동합니다.

핵심은 Git이 diff 작업을 수행하기 전에 관심있는 행을 제외한 모든 행을 파일에서 제거하도록하는 것입니다. 그러면 git log, git diff등이 관심있는 영역 만 표시합니다.

다음은 제가 다른 언어로하는 일에 대한 개요입니다. 자신의 필요에 맞게 조정할 수 있습니다.

  • 하나의 인수 (소스 파일 이름)를 취하고 해당 파일의 흥미로운 부분 만 출력하는 짧은 쉘 스크립트 (또는 다른 프로그램)를 작성하십시오 (또는 흥미로운 부분이 없으면 아무것도 출력하지 않음). 예를 들어 sed다음과 같이 사용할 수 있습니다 .

    #!/bin/sh
    sed -n -e '/^int my_func(/,/^}/ p' "$1"
    
  • textconv새 스크립트에 대한 Git 필터를 정의하십시오 . (자세한 내용은 gitattributesman 페이지를 참조하십시오.) 필터 이름과 명령 위치는 원하는대로 지정할 수 있습니다.

    $ git config diff.my_filter.textconv /path/to/my_script
    
  • 문제의 파일에 대한 diff를 계산하기 전에 해당 필터를 사용하도록 Git에 지시하십시오.

    $ echo "my_file diff=my_filter" >> .gitattributes
    
  • 이제 -G.(참고 .)를 사용 하여 필터를 적용했을 때 눈에 띄는 변경 사항을 생성하는 모든 커밋을 나열하면 관심있는 커밋이 정확히 표시됩니다., 같은 Git의 diff 루틴을 사용하는 다른 옵션은 다음과 같습니다 --patch. 이 제한된보기도 얻을 수 있습니다.

    $ git log -G. --patch my_file
    
  • Voilà!

유용한 개선 사항 중 하나는 필터 스크립트가 메서드 이름을 첫 번째 인수로 사용하고 파일을 두 번째 인수로 사용하도록하는 것입니다. 이렇게하면 git config스크립트를 편집 할 필요 없이을 호출하여 관심있는 새 메서드를 지정할 수 있습니다 . 예를 들어 다음과 같이 말할 수 있습니다.

$ git config diff.my_filter.textconv "/path/to/my_command other_func"

물론, 필터 스크립트는 당신이 좋아하는 것을 할 수 있고, 더 많은 인수를 받거나, 무엇이든 할 수 있습니다. 제가 여기에서 보여준 것보다 훨씬 더 많은 유연성이 있습니다.


답변

git log 에는 모든 차이점을 찾는 데 사용할 수있는 ‘-G’옵션이 있습니다.

-G 추가되거나 제거 된 행이 주어진 <regex>.

관심있는 함수 이름의 적절한 정규식을 제공하십시오. 예를 들면

$ git log --oneline -G'^int commit_tree'
40d52ff make commit_tree a library function
81b50f3 Move 'builtin-*' into a 'builtin/' subdirectory
7b9c0a6 git-commit-tree: make it usable from other builtins


답변

당신이 할 수있는 가장 가까운 일은 파일에서 당신의 함수의 위치를 ​​결정하는 것입니다 (예를 들어 당신의 함수 i_am_buggy가의 241-263 라인에 있다고 가정 해 봅시다 foo/bar.c), 그리고 다음의 효과를 위해 무언가를 실행하십시오 :

git log -p -L 200,300:foo/bar.c

이것은 덜 열릴 것입니다 (또는 동등한 호출기). 이제 입력 /i_am_buggy(또는 이에 상응하는 호출기)을 입력하고 변경 단계를 시작할 수 있습니다.

코드 스타일에 따라 작동 할 수도 있습니다.

git log -p -L /int i_am_buggy\(/,+30:foo/bar.c

이는 해당 정규식의 첫 번째 히트 (이상적으로는 함수 선언)에서 검색을 그 이후 30 행으로 제한합니다. end 인수는 regexp가 될 수도 있지만 regexp로 감지 하는 것은 iffier 제안입니다.


답변

올바른 방법은 eckes answer에git log -L :function:path/to/file 설명 된 대로 사용하는 것 입니다.

그러나 함수가 매우 긴 경우에는 이러한 행 중 하나만 터치 할 수있는 각 커밋에 대해 수정되지 않은 전체 기능 행이 아니라 다양한 커밋이 도입 한 변경 사항 만보고 싶을 수 있습니다. 평범한 것처럼 diff.

일반적으로 git log에서는 차이점을 볼 수 -p있지만에서는 작동하지 않습니다 -L. 따라서 grep git log -L컨텍스트 화하려면 관련된 라인과 커밋 / 파일 헤더 만 표시해야합니다. 여기서 트릭 --color은 정규식과 스위치를 추가하여 터미널 컬러 라인 만 일치 시키는 것입니다. 드디어:

git log -L :function:path/to/file --color | grep --color=never -E -e "^(^[\[[0-9;]*[a-zA-Z])+" -3

참고 ^[문자, 실제이어야한다 ^[. bash에서 ^ V ^ [, 즉 Ctrl+ V, Ctrl+ 를 눌러 입력 할 수 있습니다 [. 여기를 참조 하십시오 .

또한 마지막 -3스위치를 사용하면 일치하는 각 줄 앞뒤에 3 줄의 출력 컨텍스트를 인쇄 할 수 있습니다. 필요에 따라 조정할 수 있습니다.


답변

git blame 은 파일의 각 줄을 마지막으로 변경 한 사람을 보여줍니다. 검사 할 줄을 지정하여 함수 외부의 줄 기록을 가져 오지 않도록 할 수 있습니다.


답변

  1. eckes의 답변git docgit log -L :<funcname>:<file>표시된 대로 함수 기록 표시

    아무것도 표시되지 않으면 사용자 정의 hunk-header 정의를 참조 하여 해당 언어를 지원 *.java diff=java하기 위해 .gitattributes파일에 유사한 항목을 추가 하십시오.

  2. 커밋 간 함수 기록 표시 git log commit1..commit2 -L :functionName:filePath

  3. 오버로드 된 함수 기록 표시 (이름은 같지만 매개 변수가 다른 함수가 많을 수 있음) git log -L :sum\(double:filepath