답변:
git history에서 고급 diff 예제를 살펴 봅시다 ( git.git repository의 commit 1088261f에서 ).
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 --git a / builtin-http-fetch.cb / http-fetch.c형식의 "git diff"헤더입니다
diff --git a/file1 b/file2
. a/
및 b/
이름 변경 / 복사가 (우리의 경우처럼) 참여하지 않는 파일 이름은 동일합니다. 는 --git
그 DIFF는 "자식"은 diff 형식으로 의미하는 것입니다.다음은 하나 이상의 확장 된 헤더 행입니다. 처음 세
유사도 95 % builtin-http-fetch.c에서 이름을 바꿉니다. http-fetch.c로 이름을 바꿉니다.파일을 이름을 바꿀 것을 우리에게
builtin-http-fetch.c
로 http-fetch.c
그 두 개의 파일 (이 이름 변경을 감지하는 데 사용 된) 95 % 동일하다는 것을. 인덱스 f3e63d7..e8f44ba 100644주어진 파일의 모드에 대해 알려주십시오 (
100644
예를 들어 파일이 symlink가 아니라 일반 파일이며 실행 권한 비트가 없음을 의미합니다). 변경 후 파일 버전). 이 줄은 git am --3way
패치 자체를 적용 할 수없는 경우 3 방향 병합을 시도하는 데 사용 됩니다.다음은 두 줄의 통합 된 diff 헤더입니다
--- a / builtin-http-fetch.c +++ b / http-fetch.c
diff -U
결과 와 비교하여 소스 (사전 이미지) 및 대상 (사후 이미지) 파일 이름 후 파일 수정 시간 또는 파일 수정 시간이 없습니다. 파일이 작성된 경우 소스는 /dev/null
; 파일이 삭제 된 경우 대상은 /dev/null
입니다. diff.mnemonicPrefix
대신에 true로 구성 변수를, a/
그리고 b/
이 두 줄의 헤더에 접두어 대신 할 수 있습니다 c/
, i/
, w/
과 o/
각각 비교할 무엇을 접두사로; 볼 (1)을 구성 - 자식다음에는 하나 이상의 차이점이 있습니다. 각 덩어리는 파일이 다른 하나의 영역을 보여줍니다. 통합 형식 덩어리는 다음과 같은 줄로 시작합니다.
@@ -1,8 +1,9 @@또는
@@ -18,6 +19,8 @@ int cmd_http_fetch (int argc, const char ** argv, ...형식
@@ from-file-range to-file-range @@ [header]
입니다. 시작 파일 범위는 형식 -<start line>,<number of lines>
이며 종료 파일 범위는 +<start line>,<number of lines>
입니다. 시작 줄과 줄 수는 각각 사전 이미지와 사후 이미지에서 덩어리의 위치와 길이를 나타냅니다. 행 수가 표시되지 않으면 0임을 의미합니다.
선택적 헤더는 C 파일 ( -p
GNU diff의 옵션 과 같은 )이거나 다른 유형의 파일에 해당 하는 경우 각 변경이 발생하는 C 함수를 보여줍니다 .
다음은 파일의 차이점에 대한 설명입니다. 두 파일에 공통 인 줄은 공백 문자로 시작합니다. 두 파일간에 실제로 다른 행은 왼쪽 인쇄 열에 다음 표시기 문자 중 하나를 갖습니다.
예를 들어 첫 덩어리
#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;
줄이 추가 되었음을 의미합니다 .
다시 말해, 변경 전에 'builtin-http-fetch.c'파일의 적절한 조각은 다음과 같습니다.
#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 휄로우 말했다 그것은 당신이 변경 한 것을 알고 실제 사례에 읽기 차이점을 연습하는 것이 가장 좋습니다.
참고 문헌 :
git blame -C -C
작동 방식을 사용합니다. Git 디자인 결정입니다. git diff 형식은 사용자와의 유사성 (또는 비 유사성) 색인을 보여줍니다.
[header]
덩어리 앞에 함수의 시작과 같이 가장 근접한 선행입니다. 대부분의 경우이 줄에는 diff 덩어리가있는 함수의 이름이 포함됩니다. 이렇게하여 구성 할 diff
DIFF 드라이버 gitattribute 세트 포함 DIFF 드라이버 xfuncname
구성 변수.
@@ -1,2 +3,4 @@
diff의 일부
이 부분은 이해하는 데 시간이 걸렸으므로 최소한의 예를 만들었습니다.
형식은 기본적으로 diff -u
통합 된 diff 와 동일합니다 .
예를 들어 :
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
그 선 주 11
2와 3 : 우리는 이미 이전의 덩어리에 2 개 라인을 제거했기 때문에 새 파일의 9 라인입니다.
헝크 헤더
당신의 자식 버전과 구성에 따라, 당신은 또한 옆에 코드 라인을 얻을 수 @@
, 라인 예를 func1() {
에 :
@@ -4,7 +4,6 @@ func1() {
이것은 -p
plain 플래그로 도 얻을 수 있습니다 diff
.
예 : 오래된 파일 :
func1() {
1;
2;
3;
4;
5;
6;
7;
8;
9;
}
line을 제거 6
하면 diff에 다음이 표시됩니다.
@@ -4,7 +4,6 @@ func1() {
3;
4;
5;
- 6;
7;
8;
9;
이에 대한 올바른 라인이 아니라는 것을 참고 func1
:이 라인을 생략 1
하고 2
.
이 멋진 기능은 종종 각 덩어리가 어떤 함수 또는 클래스에 속하는지 정확하게 알려주므로 diff를 해석하는 데 매우 유용합니다.
헤더를 선택하는 알고리즘이 정확히 작동하는 방식은 다음에서 논의됩니다. git diff hunk 헤더의 발췌 부분은 어디입니까?
@@ -1,6 +1,4 @@
PLS 읽지 않는 -1
로 minus one
또는 +1
같은 plus one
대신으로이 글을 읽을 line 1 to 6
오래된 (첫번째) 파일입니다. 여기서 - implies "old"
마이너스가 아닙니다. BTW, 설명해 주셔서 감사합니다 ... 해쉬.
+1,4
이 작품은 두 번째 파일의 1-4 행에 해당합니다 ". +1,4
비 조건부 컨텍스트 라인을 참조 할 수 있기 때문 입니다. 오히려, 무엇을 " +1,4
"실제로 의미하는 것입니다 " 가있는 4
파일의 '버전'의 라인 (즉, 상황에 맞는 라인) ". 의 의미를 이해하는 것이 중요합니다 +
, -
그리고 <whitespace>
그것은 심술쟁이의 해석에 적용, 그 라인의 시작 부분에. 보다 시각적 인 예 : youtube.com/watch?v=1tqMjJeyKpw
다음은 간단한 예입니다.
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의 git 버전임을 의미합니다 (unix 아님).a/ b/
디렉토리는 실제가 아닙니다. 동일한 파일을 처리 할 때 편리합니다 (제 경우에는 a /는 색인에 있고 b /는 작업 디렉토리에 있습니다)10ff2df..84d4fa2
이 두 파일의 BLOB ID입니다100644
"모드 비트"는 파일이 일반 파일 (실행 파일이 아니라 심볼릭 링크가 아님)임을 나타냅니다.--- a/file +++ b/file
빼기 부호는 a / 버전의 행을 표시하지만 b / 버전에서는 누락됩니다. 더하기 기호는 a /에 누락되었지만 b /에있는 줄을 보여줍니다 (제 경우 --- 삭제 된 줄을 의미하고 + ++는 b /에 추가 된 줄을 의미하고 작업 디렉토리의 파일을 의미합니다)@@ -1,5 +1,5 @@
이것을 이해하려면 큰 파일로 작업하는 것이 좋습니다. 다른 장소에 두 가지 변경 사항이 있으면 다음과 같은 두 가지 항목이 표시됩니다 @@ -1,5 +1,5 @@
. line1 ... line100 파일이 있고 line10을 삭제하고 새로운 line100을 추가한다고 가정하면 다음과 같은 이점이 있습니다.@@ -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
644
)는 8 진수 (값 : 각각 1, 2, 4, eXecute, Write 및 Read 권한)로 읽히고 그 순서대로 소유자 (사용자), 그룹, 기타 권한에 해당합니다. 간단히 말해 , 644
symbolicaly u=rw,og=r
라고 쓰면 모든 사람이 읽을 수 있지만 소유자 만 쓸 수 있습니다. 왼쪽의 다른 숫자는 심볼릭 링크와 같은 다른 정보를 인코딩합니다. 값은 github.com/git/git/blob/… 에서 볼 수 있습니다 .이 위치의 첫 번째 1은 "일반 파일"입니다.
기본 출력 형식 (원래 diff
추가 정보를 찾고자 하는 프로그램에서 나온 것 )을 "통합 diff"라고합니다. 기본적으로 4 가지 유형의 라인이 포함됩니다.
+
.-
및변경 한 내용을 정확히 알고있는 두 버전의 파일간에 차이를 읽는 것이 좋습니다. 당신이 그것을 볼 때 무슨 일이 일어나고 있는지 인식 할 수 있습니다.
내 Mac에서 :
info diff
그런 다음 Output formats
-> Context
-> Unified format
-> Detailed Unified
: 를 선택하십시오 .
또는 같은 섹션으로 같은 경로를 따라 gnu에서 온라인 남자 diff :
파일 : 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의 어떤 부분이 혼란 스러울 지 확실하지 않습니다. 실제 diff 또는 추가 헤더 정보 git가 인쇄합니다. 만일을 위해 헤더에 대한 간단한 개요가 있습니다.
첫 번째 줄은 다음과 같습니다 diff --git a/path/to/file b/path/to/file
-분명히 diff 의이 섹션이 어떤 파일인지 알려줍니다. 당신은 부울 설정 변수를 설정하는 경우 diff.mnemonic prefix
는 a
과는 b
같이 더 자세한 설명 문자로 변경됩니다 c
및 w
(커밋 작업 트리).
다음으로, "모드 라인"이 있는데, 파일의 내용을 변경하지 않는 변경 사항에 대한 설명을 제공하는 라인입니다. 여기에는 새 / 삭제 된 파일, 이름이 바뀐 / 복사 된 파일 및 권한 변경이 포함됩니다.
마지막으로와 같은 줄이 index 789bd4..0afb621 100644
있습니다. 당신은 아마 신경 쓰지 않을 것이지만, 6 자리 16 진수는이 파일에 대한 이전 및 새로운 blob의 약식 SHA1 해시입니다 (blob은 파일 내용과 같은 원시 데이터를 저장하는 git 객체입니다). 물론 100644
파일의 모드는 마지막 세 자리는 분명히 권한입니다. 처음 세 개는 추가 파일 메타 데이터 정보를 제공합니다 ( SO post 설명 ).
그 후에는 표준과 같은 표준 통합 diff 출력을 사용 diff -U
합니다. 그것은 덩어리로 나뉘어져 있습니다-덩어리는 변경 사항과 컨텍스트를 포함하는 파일의 섹션입니다. 각 덩어리가 쌍으로 선행 ---
하고 +++
해당 파일을 나타내는 선 후 실제 DIFF 세의 양쪽 컨텍스트 라인 (기본값)이다 -
및 +
제거 / 추가 선과 선.
index
라인. 로 확정git hash-object ./file