development

파일의 특정 줄에 대한 커밋 로그를 검색 하시겠습니까?

big-blog 2020. 2. 16. 20:45
반응형

파일의 특정 줄에 대한 커밋 로그를 검색 하시겠습니까?


git 이 파일 의 특정 닿은 커밋에 대한 커밋 로그를 제공하는 방법이 있습니까?

처럼 git blame, 그러나 git blame특정 줄에 닿은 LAST 커밋을 보여줍니다.

파일의 어느 위치에 대한 커밋 목록이 아니라 특정 줄에 닿은 커밋 목록과 비슷한 로그를 얻고 싶습니다.


또한 Git : 어느 커밋이 다양한 라인에 닿았는지 발견 하십시오 .


힘내 1.8.4 이후 , git log-L라인의 범위의 진화를 볼 수 있습니다.

예를 들어 git blame의 출력을 보자고 가정합니다 . 여기서는 -L 150,+11"150 ~ 150 + 11 행만보십시오"라는 의미입니다.

$ git blame -L 150,+11 -- git-web--browse.sh
a180055a git-web--browse.sh (Giuseppe Bilotta 2010-12-03 17:47:36 +0100 150)            die "The browser $browser is not
a180055a git-web--browse.sh (Giuseppe Bilotta 2010-12-03 17:47:36 +0100 151)    fi
5d6491c7 git-browse-help.sh (Christian Couder 2007-12-02 06:07:55 +0100 152) fi
5d6491c7 git-browse-help.sh (Christian Couder 2007-12-02 06:07:55 +0100 153) 
5d6491c7 git-browse-help.sh (Christian Couder 2007-12-02 06:07:55 +0100 154) case "$browser" in
81f42f11 git-web--browse.sh (Giuseppe Bilotta 2010-12-03 17:47:38 +0100 155) firefox|iceweasel|seamonkey|iceape)
5d6491c7 git-browse-help.sh (Christian Couder 2007-12-02 06:07:55 +0100 156)    # Check version because firefox < 2.0 do
5d6491c7 git-browse-help.sh (Christian Couder 2007-12-02 06:07:55 +0100 157)    vers=$(expr "$($browser_path -version)" 
5d6491c7 git-browse-help.sh (Christian Couder 2007-12-02 06:07:55 +0100 158)    NEWTAB='-new-tab'
5d6491c7 git-browse-help.sh (Christian Couder 2007-12-02 06:07:55 +0100 159)    test "$vers" -lt 2 && NEWTAB=''
a0685a4f git-web--browse.sh (Dmitry Potapov   2008-02-09 23:22:22 -0800 160)    "$browser_path" $NEWTAB "$@" &

그리고 지금 155 행의 역사를 알고 싶습니다.

그런 다음을 사용하십시오 git log. 여기서는 -L 155,155:git-web--browse.sh"파일명에서 155 행에서 155 행까지의 진화를 추적"을 의미합니다 git-web--browse.sh.

$ git log --pretty=short -u -L 155,155:git-web--browse.sh
commit 81f42f11496b9117273939c98d270af273c8a463
Author: Giuseppe Bilotta <giuseppe.bilotta@gmail.com>

    web--browse: support opera, seamonkey and elinks

diff --git a/git-web--browse.sh b/git-web--browse.sh
--- a/git-web--browse.sh
+++ b/git-web--browse.sh
@@ -143,1 +143,1 @@
-firefox|iceweasel)
+firefox|iceweasel|seamonkey|iceape)

commit a180055a47c6793eaaba6289f623cff32644215b
Author: Giuseppe Bilotta <giuseppe.bilotta@gmail.com>

    web--browse: coding style

diff --git a/git-web--browse.sh b/git-web--browse.sh
--- a/git-web--browse.sh
+++ b/git-web--browse.sh
@@ -142,1 +142,1 @@
-    firefox|iceweasel)
+firefox|iceweasel)

commit 5884f1fe96b33d9666a78e660042b1e3e5f9f4d9
Author: Christian Couder <chriscool@tuxfamily.org>

    Rename 'git-help--browse.sh' to 'git-web--browse.sh'.

diff --git a/git-web--browse.sh b/git-web--browse.sh
--- /dev/null
+++ b/git-web--browse.sh
@@ -0,0 +127,1 @@
+    firefox|iceweasel)

pick-axe를 사용하여 커밋 세트를 얻을 수 있습니다.

git log -S'the line from your file' -- path/to/your/file.txt

그러면 해당 파일의 해당 텍스트에 영향을 준 모든 커밋이 제공됩니다. 파일 이름이 변경되면 --follow-parent를 추가 할 수 있습니다.

이러한 각 편집에서 커밋을 검사하려면 해당 결과를 git show로 파이프하십시오.

git log ... | xargs -n 1 git show

Git 1.8.4에서 구현 된 아래 명령을 사용해보십시오.

git log -u -L <upperLimit>,<lowerLimit>:<path_to_filename>

그래서 당신의 경우에 upperLimit& lowerLimit감동line_number

추가 정보-https: //www.techpurohit.com/list-some-useful-git-commands


가장 쉬운 방법은 vim-fugitive를 사용하는 것 입니다. vim에서 파일을 열고 사용하고자하는 라인을 V선택한 다음,

:Glog

이제 해당 행이 수정 된 파일의 모든 개정판을 사용 :cnext하고 :cprev수 있습니다 . 언제라도 :GblameSha, 작성자 및 날짜 정보를 보려면 입력 하십시오.


@matt의 답변 단순화-

git blame -L14,15 -- <file_path>

여기서 당신은 선의 비난을받을 것 14 to 15입니다.

-Loption Range은 매개 변수로 기대 하기 때문에 ``옵션을 Blame사용하여 한 줄을 얻을 수 없습니다-L .

참고


나는 이것에 대해 내장 된 것이 없다고 생각합니다. 한 줄이 파일의 나머지 부분을 크게 변경하지 않고 여러 번 변경하는 경우가 드물기 때문에 까다로워서 줄 번호가 많이 바뀌는 경향이 있습니다.

라인이 항상 가지고있는 거 운이 충분히 당신이 경우 몇 가지 이름이 변경되지 않습니다 변수에 예를 들어 할당 식별 특성을, 당신의 정규식 검색을 사용할 수 있습니다 git blame -L. 예를 들면 다음과 같습니다.

git blame -L '/variable_name *= */',+1

그러나 이것은 정규 표현식과 일치 하는 첫 번째 항목 만 찾기 때문에 줄을 일치시키는 좋은 방법이 없다면 너무 도움이되지 않습니다.

당신은 뭔가를 해킹 할 수 있다고 생각합니다. 지금 코드를 작성할 시간이 없지만 ...이 줄을 따라 뭔가. 를 실행하십시오 git blame -n -L $n,$n $file. 첫 번째 필드는 터치 한 이전 커밋이고 두 번째 필드는 변경 될 수 있으므로 해당 커밋 의 줄 번호입니다 . 파일을 가져 와서 실행하십시오 git blame -n $n,$n $commit^ $file. 즉, 파일이 마지막으로 변경되기 전에 커밋에서 시작하는 것과 동일한 것입니다.

(라인을 변경 한 마지막 커밋이 병합 커밋 인 경우에는 실패합니다. 라인이 병합 충돌 해결의 일부로 변경된 경우에 발생할 수있는 기본 방법입니다.)

편집 : 나는 걸쳐 일어난 이 메일 링리스트 게시물 월에서 것을 언급 2,011 오늘, tig그리고 git gui이 작업을 수행하는 데 도움이되는 기능이 있습니다. git 자체에 대해 기능이 고려되었지만 완료되지 않은 것처럼 보입니다.


이 호출 git blame에 대한 모든 쇼 라인에 의미있는 수정 $LINE파일 $FILE:

git log --format=format:%H $FILE | xargs -L 1 git blame $FILE -L $LINE,$LINE

평소와 같이 비난은 각 줄의 시작 부분에 개정 번호를 표시합니다. 당신은 추가 할 수 있습니다

| sort | uniq -c

이 줄을 바꾼 커밋 목록과 같은 집계 결과를 얻으려면. (확실히 코드가 이동하지 않은 경우 줄의 다른 내용에 대해 동일한 커밋 ID가 두 번 표시 될 수 있습니다.보다 자세한 분석 git blame을 위해서는 인접한 커밋 에 대한 결과를 지연 비교해야합니다 . )


다음은 git alias를 정의하는 솔루션이므로 다음과 같이 사용할 수 있습니다.

git rblame -M -n -L '/REGEX/,+1' FILE

출력 예 :

00000000 18 (Not Committed Yet 2013-08-19 13:04:52 +0000 728) fooREGEXbar
15227b97 18 (User1 2013-07-11 18:51:26 +0000 728) fooREGEX
1748695d 23 (User2 2013-03-19 21:09:09 +0000 741) REGEXbar

.gitconfig 에서 별칭을 정의 하거나 다음 명령을 간단히 실행할 수 있습니다

git config alias.rblame !sh -c 'while line=$(git blame "$@" $commit 2>/dev/null); do commit=${line:0:8}^; [ 00000000^ == $commit ] && commit=$(git rev-parse HEAD); echo $line; done' dumb_param

이것은 추악한 one-liner이므로, 난독 처리 된 동등한 bash 함수는 다음과 같습니다.

git-rblame () {
    local commit line
    while line=$(git blame "$@" $commit 2>/dev/null); do
        commit="${line:0:8}^"
        if [ "00000000^" == "$commit" ]; then
            commit=$(git rev-parse HEAD)
        fi
        echo $line
    done
}

곡괭이 솔루션 ( git log --pickaxe-regex -S'REGEX ' )은 정규 표현식을 포함하는 줄의 다른 변경 사항이 아니라 줄 추가 / 삭제 만 제공합니다.

이 솔루션의 한계는 git blame 이 첫 번째 REGEX 일치 만 리턴하므로 여러 일치가 존재하면 재귀가 다른 행을 따라 "점프"할 수 있다는 것입니다. "점프"를 발견하기 위해 전체 히스토리 출력을 확인한 다음 REGEX를 수정하여 기생충 선을 무시하십시오.

마지막으로, 각 커밋마다 git show 를 실행 하여 전체 diff를 얻는 대체 버전이 있습니다 .

git config alias.rblameshow !sh -c 'while line=$(git blame "$@" $commit 2>/dev/null); do commit=${line:0:8}^; [ 00000000^ == $commit ] && commit=$(git rev-parse HEAD); git show $commit; done' dumb_param

제 경우에는 줄 번호가 시간이 지남에 따라 많이 바뀌 었습니다. 또한 "git blame -L"의 정규 표현식을 지원하지 않는 git 1.8.3에있었습니다. (RHEL7에는 여전히 1.8.3이 있습니다)

myfile=haproxy.cfg
git rev-list HEAD -- $myfile | while read i
do
    git diff -U0 ${i}^ $i $myfile | sed "s/^/$i /"
done | grep "<sometext>"

짧막 한 농담:

myfile=<myfile> ; git rev-list HEAD -- $myfile | while read i; do     git diff -U0 ${i}^ $i $myfile | sed "s/^/$i /"; done | grep "<sometext>"

이것은 물론 스크립트 나 함수로 만들 수 있습니다.


git blame 명령에서 각 커밋의 요약을 검색하고 추가하기 위해 명령 git blamegit log명령을 혼합 할 수 있습니다 . 다음 bash + awk 스크립트와 같은 것. 커밋 요약을 코드 주석 인라인으로 추가합니다.

git blame FILE_NAME | awk -F" " \
'{
   commit = substr($0, 0, 8);
   if (!a[commit]) {
     query = "git log --oneline -n 1 " commit " --";
     (query | getline a[commit]);
   }
   print $0 "  // " substr(a[commit], 9);
 }'

한 줄로 :

git blame FILE_NAME | awk -F" " '{ commit = substr($0, 0, 8); if (!a[commit]) { query = "git log --oneline -n 1 " commit " --"; (query | getline a[commit]); } print $0 "  // " substr(a[commit], 9); }'

참고 URL : https://stackoverflow.com/questions/8435343/retrieve-the-commit-log-for-a-specific-line-in-a-file



반응형