의 매뉴얼 페이지 git-diff
는 다소 길며 초보자에게는 필요하지 않은 많은 경우를 설명합니다. 예를 들면 다음과 같습니다.
git diff origin/master
답변
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 % 동일하다는 것을.확장 된 diff 헤더의 마지막 행
인덱스 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-diff (1) 맨 페이지 , “-p를 사용하여 패치 생성”섹션
- (diff.info) 상세한 통합 노드, “상세한 포맷의 상세한 설명”.
답변
@@ -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 헤더의 발췌 부분은 어디입니까?
답변
다음은 간단한 예입니다.
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
답변
기본 출력 형식 (원래 diff
추가 정보를 찾고자 하는 프로그램에서 나온 것 )을 “통합 diff”라고합니다. 기본적으로 4 가지 유형의 라인이 포함됩니다.
- 단일 공백으로 시작하는 컨텍스트 라인
- 삽입 된 선을 나타내는 삽입 선은로 시작합니다
+
. - 로 시작할 삭제 라인,
-
및 - 어떤 파일에 대해 이야기하고 있는지, diff를 생성하는 데 사용 된 옵션, 파일의 사용 권한 변경 여부 등과 같은 상위 수준의 항목을 설명하는 메타 데이터 줄
변경 한 내용을 정확히 알고있는 두 버전의 파일간에 차이를 읽는 것이 좋습니다. 당신이 그것을 볼 때 무슨 일이 일어나고 있는지 인식 할 수 있습니다.
답변
내 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 세의 양쪽 컨텍스트 라인 (기본값)이다 -
및 +
제거 / 추가 선과 선.