sourcecode

git diff의 출력을 읽는 방법은 무엇입니까?

codebag 2023. 5. 3. 21:24
반응형

git diff의 출력을 읽는 방법은 무엇입니까?

의 맨 git-diff다소 길고 초보자에게 필요하지 않은 많은 사례를 설명합니다.예:

git diff origin/master

git 저장소(commit 1088261fing.git 저장소)에서 고급 diffgit 내역의 예를 살펴보겠습니다.

diff --git a/builtin-http-fetch.c b/http-fetch.c
similarity index 95%
rename from builtin-http-fetch.c
rename to http-fetch.c
index f3e63d7..e8f44ba 100644
--- a/builtin-http-fetch.c
+++ b/http-fetch.c
@@ -1,8 +1,9 @@
 #include "cache.h"
 #include "walker.h"
 
-int cmd_http_fetch(int argc, const char **argv, const char *prefix)
+int main(int argc, const char **argv)
 {
+       const char *prefix;
        struct walker *walker;
        int commits_on_stdin = 0;
        int commits;
@@ -18,6 +19,8 @@ int cmd_http_fetch(int argc, const char **argv, const char *prefix)
        int get_verbosely = 0;
        int get_recover = 0;
 
+       prefix = setup_git_directory();
+
        git_config(git_default_config, NULL);
 
        while (arg < argc && argv[arg][0] == '-') {

이 패치를 한 줄씩 분석해 보겠습니다.

  • 첫번째 줄

    diff --gita/built-built-built-built-built-built-built-
    는 "gitdiff" "gitdiff" 입니다.diff --git a/file1 b/file2.a/그리고.b/파일 이름은 이름 바꾸기/복사가 포함되지 않는 한 동일합니다(우리의 경우처럼).--git형식이라는 합니다. 즉, "git" diff는 "git" diff"입니다.

  • 다음은 하나 이상의 확장 헤더 행입니다.처음 세 개

    유사성 지수 95%내장된 vmdk에서 이름 바꾸기이름을 http-http.c로 변경합니다.
    이 파일이에변알을려다니줍음경었서에서 변경되었음을 알려줍니다.builtin-http-fetch.chttp-fetch.c이 두 파일은 95% 동일합니다(이 이름 변경을 탐지하는 데 사용됨).

    헤더의 "diff"는 "diff", "
    인덱스 f3e63d7..e8f44ba 100644
    파일의 .100644symlink와 같이 일반 파일이며 실행 권한 비트가 없음을 의미하며, 사전 이미지(변경 전 파일 버전)와 사후 이미지(변경 후 파일 버전)의 단축 해시에 대해 설명합니다.이 줄은 다음 사용자가 사용합니다.git am --3way패치 자체를 적용할 수 없는 경우 3방향 병합을 시도합니다.

  • 다음은 두 줄로 된 통합 diff 헤더입니다.

    내장형 에어컨b/sl-sl.c.
    와비여하와 diff -U결과적으로 소스(사전 이미지) 및 대상(사후 이미지) 파일 이름에 from-file-modification-time 또는 to-file-modification-time이 없습니다.는 파이생경소스우입니다./dev/null은 파이삭경우대상입니다./dev/null.
    설정하는 경우diff.mnemonicPrefix로, true, a/그리고.b/이 두줄를 대신 할 수 .c/,i/,w/그리고.o/비교하는 것과 각각 접두사로, git-config(1) 참조

  • 다음으로 하나 이상의 차이가 발생합니다. 각 차이는 파일이 서로 다른 하나의 영역을 나타냅니다.유니파이드 형식의 헝크는 다음과 같은 줄로 시작합니다.

    @@ -1,8 +1,9 @@
    또는
    -18,6 +19,8 @ int cmd_module_module(argc 내, const char **argv, ...
    은 형입니다 입니다.@@ from-file-range to-file-range @@ [header]는 from-file-range 입니다.-<start line>,<number of lines>는 "파일 범위에 대한"입니다.+<start line>,<number of lines>시작 라인과 줄 수는 각각 사전 이미지와 사후 이미지에서 헝크의 위치와 길이를 나타냅니다. 수가 1.0 수 표 시 임 않 으 줄 1 의 합 니 미 다 을 수 가 면 가 되 지 줄 니 다 ▁1 ▁if 합 의 미 ▁not ▁that ▁it ▁it - 임 - ▁shown ▁means

는 C 각 사항이C(예: " 옵헤 더각변나발다는니타냅생 C"). C 파일의 경우 다음과 같습니다.-pGNU diff의 옵션) 또는 다른 유형의 파일에 대한 동등한 옵션입니다.

  • 다음은 파일이 다른 위치에 대한 설명입니다.두 파일에 공통적인 행은 공백 문자로 시작합니다.두 파일 간에 실제로 다른 행은 왼쪽 인쇄 열에 다음 표시 문자 중 하나입니다.

  • -- 첫 번째 파일에 줄이 추가되었습니다.

  • -- 첫 번째 파일에서 줄이 제거되었습니다.


예를 first chunk , 번청째크는.

     #include "cache.h"
     #include "walker.h"
     
    -int cmd_http_fetch(int argc, const char **argv, const char *prefix)
    +int main(int argc, const char **argv)
     {
    +       const char *prefix;
            struct walker *walker;
            int commits_on_stdin = 0;
            int commits;

는 것을 의미합니다.cmd_http_fetch으로 main 그 그에밖const char *prefix;라인이 추가되었습니다.

즉, 변경하기 전에 'built-in-http-fetch.c' 파일의 적절한 fragment는 다음과 같습니다.

    #include "cache.h"
    #include "walker.h"
    
    int cmd_http_fetch(int argc, const char **argv, const char *prefix)
    {
           struct walker *walker;
           int commits_on_stdin = 0;
           int commits;

변경 후 현재 'http-fetch.c' 파일의 이 조각은 대신 다음과 같습니다.

    #include "cache.h"
    #include "walker.h"
     
    int main(int argc, const char **argv)
    {
           const char *prefix;
           struct walker *walker;
           int commits_on_stdin = 0;
           int commits;
  • 있을 수도 있습니다.
    파일 끝에 새 줄이 없습니다.
    라인이 존재합니다(예: diff가 아닙니다).

Donal Fellows가 말했듯이, 여러분이 무엇을 바꿨는지 아는 실제 사례에 대한 차이를 읽는 연습을 하는 것이 가장 좋습니다.

참조:

@@ -1,2 +3,4 @@diff 의

이 부분을 이해하는 데 시간이 좀 걸렸기 때문에 최소한의 예를 만들었습니다.

으로 형은기로동일다니합으본적식과 같습니다.diff -u통일 격차

예를 들어:

diff -u <(seq 16) <(seq 16 | grep -Ev '^(2|3|14|15)$')

여기서 2, 3, 14, 15행을 제거했습니다.출력:

@@ -1,6 +1,4 @@
 1
-2
-3
 4
 5
 6
@@ -11,6 +9,4 @@
 11
 12
 13
-14
-15
 16

@@ -1,6 +1,4 @@평균값:평균값:

  • -1,6첫 번째 파일의 이 부분이 1행에서 시작하여 총 6행을 표시함을 의미합니다.따라서 1~6행이 표시됩니다.

    1
    2
    3
    4
    5
    6
    

    -우리가 보통 그것을 호출하듯이, "오래된"을 의미합니다.diff -u old new.

  • +1,4두 번째 파일의 이 부분이 1행에서 시작하여 총 4행을 표시함을 의미합니다.따라서 1~4행이 표시됩니다.

    +"새롭다"는 뜻입니다.

    2개 라인이 제거되어 6개 라인이 아닌 4개 라인만 있습니다!새로운 촌뜨기는 그냥:

    1
    4
    5
    6
    

@@ -11,6 +9,4 @@합니다: " 번째헝유사합다니는크두다유니".

  • 이전 파일에는 이전 파일의 11행에서 시작하여 6개의 행이 있습니다.

    11
    12
    13
    14
    15
    16
    
  • 새 파일에는 새 파일의 9행에서 시작하는 4개의 행이 있습니다.

    11
    12
    13
    16
    

    그 선을 주의하세요.113줄을 에 새 줄입니다. 왜냐하면 우리는 이미 이전 헝크에서 2줄과 3줄을 제거했기 때문입니다.

헝크 헤더

Git 버전 및 구성에 따라 다음과 같은 코드 행을 얻을 수도 있습니다.@@, 예):func1() {위치:

@@ -4,7 +4,6 @@ func1() {

이는 또한 다음을 통해 얻을 수 있습니다.-pdiff.

예: 이전 파일:

func1() {
    1;
    2;
    3;
    4;
    5;
    6;
    7;
    8;
    9;
}

라인을 제거하면,6다음과 같이 표시됩니다.

@@ -4,7 +4,6 @@ func1() {
     3;
     4;
     5;
-    6;
     7;
     8;
     9;

다음에 대한 올바른 라인이 아닙니다.func1그것은 대사를 건너뛰었습니다.1그리고.2.

이 놀라운 기능은 종종 각 헝크가 정확히 어떤 기능이나 클래스에 속하는지 알려주는데, 이는 차이를 해석하는 데 매우 유용합니다.

헤더를 정확하게 선택하는 알고리즘이 작동하는 방법은 다음에서 논의됩니다: gitdiffunk 헤더의 발췌본은 어디에서 왔습니까?

한 줄 헝크 요약 표기법

이는 매우 드문 일이지만 다음 사항을 고려해 보십시오.

diff -U0 <(seq -w 16) <(seq -w 16 | sed 's/10/hack/')

위치:

  • -U0의 context0을 합니다.
  • 이 두번파교체이일을 대체합니다.10와 함께hack

이 경우 diff 출력은 다음과 같습니다.

@@ -10 +10 @@
-10
+hack

그래서 우리는 한 줄의 변화가 있을 때, 표기법은 다음과 같은 것이 아니라 하나의 숫자만 보여주는 것으로 요약된다는 것을 이해합니다.m,n

이 동작은 Todd의 답변에 인용된 문서에 설명되어 있습니다.

헝크에 줄이 하나만 포함된 경우 시작 줄 번호만 표시됩니다.그렇지 않으면 줄 번호가 시작, 카운트와 같습니다.빈 헝크는 헝크 뒤에 오는 선에서 시작하는 것으로 간주됩니다.

한 줄의 헝크 추가 및 제거는 다음과 같습니다. 제거:

diff -U0  <(seq -w 16) <(seq -w 16 | grep -Ev '^(10)$')

출력:

@@ -10 +9,0 @@
-10

추가:

$ diff -U0 <(seq -w 16 | grep -Ev '^(10)$') <(seq -w 16)

출력:

@@ -9,0 +10 @@
+10

diff 3.8, Ubuntu 22.10에서 테스트되었습니다.

여기 간단한 예가 있습니다.

diff --git a/file b/file 
index 10ff2df..84d4fa2 100644
--- a/file
+++ b/file
@@ -1,5 +1,5 @@
 line1
 line2
-this line will be deleted
 line4
 line5
+this line is added

다음은 설명입니다.

  • --git. diff의 깃 입니다. 이것은 diff의 깃 버전입니다(unix가 아님).
  • a/ b/디렉토리입니다. ▁(. 같은 을 다룰 때 a/는는 작업 에 있습니다.동일한 파일을 처리할 때 편리할 뿐입니다(내 경우 a/는 인덱스에 있고 b/는 작업 디렉토리에 있습니다.
  • 10ff2df..84d4fa2는 이 두 ID입니다.
  • 100644는 " 비트"로, 링크도 )임을 .
  • --- a/file +++ b/file b/된 행을 나타내며, 는 a에는 없지만 내 경우는 b하며 이 디렉터리에 ). a/에 있는 b/ 파일입니다. 더하기 기호는 a/에는 없지만 b/에는 있는 행을 표시합니다(내 경우 ---는 삭제된 행을 의미하며 +++은 b/에 추가된 행을 의미하며 이는 작업 디렉터리에 있는 파일).
  • @@ -1,5 +1,5 @@; 두 당신은 " 을이기더것다니낫이는작습업하파로일것; 얻당다두다당같두음항개과을을목입니다의은만개은변장있서신에이약것소른이의경다면이신해하위해서"와 같은 두 개의 될 입니다.@@ -1,5 +1,5 @@파일 라인1이 있다고 가정합니다...100행과 10행을 삭제하고 100행을 새로 추가하면 다음과 같은 결과를 얻을 수 있습니다.
@@ -7,7 +7,6 @@ line6
 line7
 line8
 line9
-this line10 to be deleted
 line11
 line12
 line13
@@ -98,3 +97,4 @@ line97
 line98
 line99
 line100
+this is new line100

기본 출력 형식(원래는 다음과 같은 프로그램에서 제공됨)diff더 많은 정보를 찾고자 하는 경우)를 "스캐너 디프"라고 합니다.여기에는 기본적으로 4가지 유형의 선이 포함됩니다.

  • 하나의 공백으로 시작하는 컨텍스트 라인,
  • 로, 삽된선보삽입선으로 하는 것+,
  • , 선로시로 행-,그리고.
  • 메타데이터 행은 이 파일이 어떤 파일에 대해 이야기하고 있는지, diff를 생성하는 데 사용된 옵션은 무엇인지, 파일이 권한을 변경했는지 등과 같은 상위 수준을 설명합니다.

변경한 내용을 정확히 알고 있는 파일의 두 버전 간의 차이를 읽는 연습을 하는 것이 좋습니다.그런 식으로 당신은 그것을 볼 때 무슨 일이 일어나고 있는지 알게 될 것입니다.

내 Mac에서:

info diff그런 다음 다음을 선택합니다.Output formats->Context->Unified format->Detailed Unified:

또는 온라인 man diffongnu가 같은 섹션으로 같은 경로를 따라 이동합니다.

파일: diff.info , 노드:세부적인 유니파이드, 다음: 예: 유니파이드, 위쪽: 유니파이드

통합 형식에 대한 자세한 설명 ...................................................................

유니파이드 출력 형식은 다음과 같은 두 줄 헤더로 시작합니다.

 --- FROM-FILE FROM-FILE-MODIFICATION-TIME
 +++ TO-FILE TO-FILE-MODIFICATION-TIME

타임스탬프는 '2002-02-21 23:30:39.942229878-0800'과 같이 날짜, 시간(초) 및 시간대를 나타냅니다.

'--label='을 사용하여 헤더의 내용을 변경할 수 있습니다.LABEL' 옵션. *참고 대체 이름::

다음으로 하나 이상의 차이가 발생합니다. 각 차이는 파일이 서로 다른 하나의 영역을 나타냅니다.유니파이드 형식의 헝크는 다음과 같습니다.

 @@ FROM-FILE-RANGE TO-FILE-RANGE @@
  LINE-FROM-EITHER-FILE
  LINE-FROM-EITHER-FILE...

두 파일에 공통적인 행은 공백 문자로 시작합니다.두 파일 간에 실제로 다른 행은 왼쪽 인쇄 열에 다음 표시 문자 중 하나입니다.

첫 번째 파일에 줄이 추가되었습니다.

첫 번째 파일에서 줄이 제거되었습니다.

당신의 질문에서 당신이 혼란스럽게 생각하는 차이점 중 어느 부분이 실제 차이인지, 추가 헤더 정보가 인쇄되는지는 분명하지 않습니다.만약을 위해, 여기 헤더에 대한 간단한 개요가 있습니다.

번째 은 첫번째줄다같음습다니과은같과 같은 것입니다.diff --git a/path/to/file b/path/to/file분명히 그것은 이 디프 섹션이 어떤 파일을 위한 것인지 알려줄 뿐입니다.부울 구성 변수를 설정하는 경우diff.mnemonic prefix,a그리고.b다음과 같은 더 설명적인 문자로 변경됩니다.c그리고.w(커밋 및 작업 트리).

다음으로, "모드 줄" - 파일의 내용을 변경하지 않는 변경 사항에 대한 설명을 제공하는 줄이 있습니다.여기에는 새/삭제된 파일, 이름 변경/복사된 파일 및 권한 변경이 포함됩니다.

마지막으로, 다음과 같은 줄이 있습니다.index 789bd4..0afb621 100644여러분은 아마 신경 쓰지 않을 것이지만, 이 6자리 16진수 숫자는 이 파일에 대한 이전 및 새 Blob의 약어 SHA1 해시입니다(블롭은 파일의 내용처럼 원시 데이터를 저장하는 Git 개체입니다). 고물론그리, 그.100644파일의 모드입니다. 마지막 세 자리는 분명히 권한입니다. 처음 세 자리는 추가 파일 메타데이터 정보를 제공합니다(이를 설명하는 SO 포스트).

그런 다음 표준 통합 디피 출력이 됩니다(클래식과 동일).diff -U됩니다. 의 한 섹션입니다 Hunk로 분할됩니다. Hunk는 파일의 한 섹션으로 변경사항과 해당 컨텍스트를 포함합니다.에는 한 의 각헝앞한쌍의가 .---그리고.+++ 문의파 나선기는내타일, 차는이로 (양쪽으적) ▁on▁▁side▁of▁lines기▁(▁in▁either▁is▁den다▁context▁of▁then양니쪽▁file의 양쪽에 있는 세 줄의 컨텍스트입니다.-그리고.+제거/추가된 라인을 보여주는 라인

언급URL : https://stackoverflow.com/questions/2529441/how-to-read-the-output-from-git-diff

반응형