Trang dành cho nam git-diff
khá dài và giải thích nhiều trường hợp dường như không cần thiết cho người mới bắt đầu. Ví dụ:
git diff origin/master
Trang dành cho nam git-diff
khá dài và giải thích nhiều trường hợp dường như không cần thiết cho người mới bắt đầu. Ví dụ:
git diff origin/master
Câu trả lời:
Hãy xem ví dụ nâng cao khác với lịch sử git (trong cam kết 1088261f trong kho git.git ):
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] == '-') {
Hãy phân tích dòng vá này theo từng dòng.
Dòng đầu tiên
diff --git a / buildin-http-fetch.cb / http-fetch.clà một tiêu đề "git diff" trong mẫu
diff --git a/file1 b/file2
. Tên a/
và b/
tên giống nhau trừ khi có liên quan đến đổi tên / sao chép (như trong trường hợp của chúng tôi). Điều --git
này có nghĩa là diff ở định dạng diff "git".Tiếp theo là một hoặc nhiều dòng tiêu đề mở rộng. Ba đầu tiên
chỉ số tương tự 95% đổi tên từ buildin-http-fetch.c đổi tên thành http-fetch.ccho chúng tôi biết rằng tệp đã được đổi tên từ
builtin-http-fetch.c
thành http-fetch.c
và hai tệp đó giống nhau 95% (được sử dụng để phát hiện đổi tên này). chỉ số f3e63d7..e8f44ba 100644cho chúng tôi biết về chế độ của tệp đã cho (
100644
có nghĩa là đó là tệp thông thường chứ không phải là symlink và nó không có bit cấp phép thực thi) và về hàm băm của preimage (phiên bản của tệp trước khi thay đổi đã cho) và postimage ( phiên bản của tập tin sau khi thay đổi). Dòng này được sử dụng git am --3way
để cố gắng thực hiện hợp nhất 3 chiều nếu bản vá không thể được áp dụng.Tiếp theo là tiêu đề diff hai dòng thống nhất
--- a / buildin-http-fetch.c +++ b / http-fetch.cSo với
diff -U
kết quả, nó không có tên tệp từ thời gian sửa đổi tệp cũng như thời gian sửa đổi tệp sau thời gian tên nguồn (tiền tố) và tên đích (bưu chính). Nếu tập tin được tạo, nguồn là /dev/null
; nếu tập tin bị xóa, mục tiêu là /dev/null
. diff.mnemonicPrefix
biến cấu hình là true, ở vị trí của a/
và b/
tiền tố trong tiêu đề hai dòng này bạn có thể có thay c/
, i/
, w/
và o/
như tiền tố, tương ứng với những gì bạn so sánh; xem git-config (1)Tiếp đến là một hoặc nhiều người khác biệt; mỗi hunk hiển thị một khu vực nơi các tệp khác nhau. Hunk định dạng hợp nhất bắt đầu với dòng như
@@ -1,8 +1,9 @@hoặc là
@@ -18,6 +19,8 @@ int cmd_http_fetch (int argc, const char ** argv, ...Nó ở định dạng
@@ from-file-range to-file-range @@ [header]
. Phạm vi từ tệp có dạng và phạm vi -<start line>,<number of lines>
đến tệp là +<start line>,<number of lines>
. Cả hai dòng bắt đầu và số dòng đều tương ứng với vị trí và độ dài của hunk trong preimage và postimage. Nếu số dòng không hiển thị thì có nghĩa là 0.
Tiêu đề tùy chọn hiển thị chức năng C trong đó mỗi thay đổi xảy ra, nếu đó là tệp C (như -p
tùy chọn trong GNU diff) hoặc tương đương, nếu có, đối với các loại tệp khác.
Tiếp đến là mô tả về nơi các tập tin khác nhau. Các dòng chung cho cả hai tệp bắt đầu bằng một ký tự khoảng trắng. Các dòng thực sự khác nhau giữa hai tệp có một trong các ký tự chỉ báo sau trong cột in bên trái:
Vì vậy, ví dụ, chunk đầu tiên
#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;
có nghĩa là cmd_http_fetch
đã được thay thế bởi main
, và const char *prefix;
dòng đó đã được thêm vào.
Nói cách khác, trước khi thay đổi, đoạn thích hợp của tệp 'dựng sẵn-http-fetch.c' trông như thế này:
#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;
Sau khi thay đổi, đoạn này của tệp 'http-fetch.c' trông giống như thế này:
#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;
Có thể có
\ Không có dòng mới ở cuối tệpdòng hiện tại (nó không phải là trong ví dụ khác).
Như Donal Fellows nói rằng tốt nhất là thực hành đọc khác biệt trên các ví dụ thực tế, nơi bạn biết những gì bạn đã thay đổi.
Người giới thiệu:
git blame -C -C
đó, đó là cách nó hoạt động; đó là quyết định thiết kế Git. Định dạng git diff chỉ hiển thị chỉ số tương tự (hoặc không giống nhau) cho người dùng.
[header]
là phần trước gần nhất giống như khi bắt đầu chức năng đi trước một hunk. Trong hầu hết các trường hợp, dòng này bao gồm tên của hàm trong đó khối của diff là. Đây là cấu hình với diff
gitattribution được đặt thành trình điều khiển diff và trình điều khiển diff bao gồm cả xfuncname
biến cấu hình.
@@ -1,2 +3,4 @@
một phần của khác
Phần này khiến tôi mất một lúc để hiểu, vì vậy tôi đã tạo ra một ví dụ tối thiểu.
Các định dạng về cơ bản là giống nhau diff -u
.
Ví dụ:
diff -u <(seq 16) <(seq 16 | grep -Ev '^(2|3|14|15)$')
Ở đây chúng tôi đã loại bỏ các dòng 2, 3, 14 và 15. Kết quả:
@@ -1,6 +1,4 @@
1
-2
-3
4
5
6
@@ -11,6 +9,4 @@
11
12
13
-14
-15
16
@@ -1,6 +1,4 @@
có nghĩa:
-1,6
có nghĩa là phần này của tệp đầu tiên bắt đầu ở dòng 1 và hiển thị tổng cộng 6 dòng. Do đó, nó hiển thị các dòng 1 đến 6.
1
2
3
4
5
6
-
có nghĩa là "cũ", như chúng ta thường gọi nó là diff -u old new
.
+1,4
có nghĩa là đoạn này của tệp thứ hai bắt đầu ở dòng 1 và hiển thị tổng cộng 4 dòng. Do đó, nó hiển thị các dòng 1 đến 4.
+
có nghĩa là "mới".
Chúng tôi chỉ có 4 dòng thay vì 6 vì đã xóa 2 dòng! Hunk mới chỉ là:
1
4
5
6
@@ -11,6 +9,4 @@
cho hunk thứ hai là tương tự:
trên tệp cũ, chúng tôi có 6 dòng, bắt đầu từ dòng 11 của tệp cũ:
11
12
13
14
15
16
trên tệp mới, chúng tôi có 4 dòng, bắt đầu từ dòng 9 của tệp mới:
11
12
13
16
Lưu ý rằng dòng 11
này là dòng thứ 9 của tệp mới vì chúng tôi đã xóa 2 dòng trên hunk trước: 2 và 3.
Tiêu đề Hunk
Tùy thuộc vào phiên bản và cấu hình git của bạn, bạn cũng có thể nhận được một dòng mã bên cạnh @@
dòng, ví dụ func1() {
: trong:
@@ -4,7 +4,6 @@ func1() {
Điều này cũng có thể thu được với -p
cờ của đồng bằng diff
.
Ví dụ: tập tin cũ:
func1() {
1;
2;
3;
4;
5;
6;
7;
8;
9;
}
Nếu chúng tôi loại bỏ dòng 6
, khác biệt hiển thị:
@@ -4,7 +4,6 @@ func1() {
3;
4;
5;
- 6;
7;
8;
9;
Lưu ý rằng đây không phải là dòng chính xác cho func1
: nó bỏ qua các dòng 1
và 2
.
Tính năng tuyệt vời này thường cho biết chính xác chức năng hoặc lớp mà mỗi hunk thuộc về, rất hữu ích để giải thích khác biệt.
Làm thế nào thuật toán để chọn tiêu đề hoạt động chính xác được thảo luận tại: Đoạn trích trong tiêu đề hunk diff đến từ đâu?
@@ -1,6 +1,4 @@
xin đừng đọc -1
như minus one
hoặc +1
là plus one
thay vì đọc như line 1 to 6
ở cũ (đầu tiên) tập tin. Lưu ý ở đây - implies "old"
không trừ. BTW, cảm ơn đã làm rõ ... haash.
+1,4
nói rằng phần này tương ứng với dòng 1 đến 4 của tệp thứ hai ". Điều này là do +1,4
có thể đề cập đến các dòng bối cảnh không dự phòng. Thay vào đó, " +1,4
" thực sự có nghĩa là gì " có 4
các dòng (tức là các dòng ngữ cảnh) trong 'phiên bản' của tệp đó ". Điều quan trọng là phải hiểu ý nghĩa của +
, -
và <whitespace>
vào đầu những dòng này, vì nó áp dụng cho việc giải thích hunks. Một ví dụ trực quan hơn: youtube.com/watch?v=1tqMjJeyKpw
Đây là ví dụ đơn giản.
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
Đây là một lời giải thích (xem chi tiết ở đây ).
--git
không phải là một lệnh, điều này có nghĩa là đây là phiên bản git của diff (không phải unix)a/ b/
là những thư mục, chúng không có thật. thật tiện lợi khi chúng ta xử lý cùng một tệp (trong trường hợp của tôi a / nằm trong chỉ mục và b / nằm trong thư mục làm việc)10ff2df..84d4fa2
là ID blob của 2 tệp này100644
là các bit chế độ của người dùng, có nghĩa là đây là một tệp thông thường (không thể thực thi và không phải là một liên kết tượng trưng)--- a/file +++ b/file
dấu trừ cho thấy các dòng trong phiên bản a / nhưng thiếu từ phiên bản b /; và dấu cộng hiển thị các dòng bị thiếu trong a / nhưng hiện diện trong b / (trong trường hợp của tôi --- có nghĩa là các dòng bị xóa và +++ có nghĩa là các dòng được thêm vào trong b / và đây là tệp trong thư mục làm việc)@@ -1,5 +1,5 @@
để hiểu điều này tốt hơn là làm việc với một tệp lớn; nếu bạn có hai thay đổi ở những nơi khác nhau, bạn sẽ nhận được hai mục như @@ -1,5 +1,5 @@
; giả sử bạn có tệp line1 ... line100 và xóa line10 và thêm dòng mới 100 - bạn sẽ nhận được:@@ -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
) sẽ được đọc theo số bát phân (giá trị: 1, 2, 4 tương ứng là quyền eXecute, Write và Read) và tương ứng theo thứ tự đó cho Chủ sở hữu (Người dùng), sau đó Nhóm, sau đó là các quyền khác. Vì vậy, trong ngắn hạn 644
có nghĩa là nếu được viết tượng trưng u=rw,og=r
, mọi người đều có thể đọc được nhưng chỉ có thể ghi được bởi chủ sở hữu. Các chữ số khác ở bên trái mã hóa thông tin khác, như nếu đó là một liên kết tượng trưng, v.v ... Các giá trị có thể được nhìn thấy github.com/git/git/blob/ , một trong những vị trí đầu tiên ở vị trí này là "tệp thông thường".
Định dạng đầu ra mặc định (ban đầu xuất phát từ một chương trình được biết là diff
nếu bạn muốn tìm kiếm thêm thông tin) được gọi là một tập hợp khác biệt của Hồi giáo. Nó chứa 4 loại đường khác nhau:
+
,-
, vàTôi khuyên bạn nên thực hành đọc khác nhau giữa hai phiên bản của tệp nơi bạn biết chính xác những gì bạn đã thay đổi. Như thế bạn sẽ nhận ra những gì đang diễn ra khi bạn nhìn thấy nó.
Trên máy mac của tôi:
info diff
sau đó chọn: Output formats
-> Context
-> Unified format
-> Detailed Unified
:
Hoặc người đàn ông trực tuyến khác trên gnu theo cùng một đường dẫn đến cùng một phần:
Tệp: diff.info, Nút: Hợp nhất chi tiết, Tiếp theo: Ví dụ Hợp nhất, Lên: Định dạng hợp nhất
Mô tả chi tiết về định dạng hợp nhất ......................................
Định dạng đầu ra hợp nhất bắt đầu bằng tiêu đề hai dòng, trông như thế này:
--- FROM-FILE FROM-FILE-MODIFICATION-TIME +++ TO-FILE TO-FILE-MODIFICATION-TIME
Dấu thời gian trông giống như `2002 / 02-21 23: 30: 39.942229878 -0800 'để chỉ ngày, giờ với giây phân số và múi giờ.
Bạn có thể thay đổi nội dung của tiêu đề bằng tùy chọn `--label = LABEL '; xem * Lưu ý Tên thay thế ::.
Tiếp đến là một hoặc nhiều người khác biệt; mỗi hunk hiển thị một khu vực nơi các tệp khác nhau. Hunk định dạng thống nhất trông như thế này:
@@ FROM-FILE-RANGE TO-FILE-RANGE @@ LINE-FROM-EITHER-FILE LINE-FROM-EITHER-FILE...
Các dòng chung cho cả hai tệp bắt đầu bằng một ký tự khoảng trắng. Các dòng thực sự khác nhau giữa hai tệp có một trong các ký tự chỉ báo sau trong cột in bên trái:
`+ 'Một dòng đã được thêm vào đây vào tệp đầu tiên.
`- 'Một dòng đã bị xóa ở đây từ tệp đầu tiên.
Không rõ từ câu hỏi của bạn phần nào của các khác biệt bạn thấy khó hiểu: thực sự khác biệt, hoặc thông tin tiêu đề bổ sung git in. Chỉ trong trường hợp, đây là một tổng quan nhanh về tiêu đề.
Dòng đầu tiên giống như diff --git a/path/to/file b/path/to/file
- rõ ràng nó chỉ cho bạn biết phần này của diff là dành cho. Nếu bạn đặt biến cấu hình boolean diff.mnemonic prefix
, a
và b
sẽ được thay đổi thành các chữ cái mô tả hơn như c
và w
(cây cam kết và công việc).
Tiếp theo, có "các dòng chế độ" - các dòng cung cấp cho bạn một mô tả về bất kỳ thay đổi nào không liên quan đến việc thay đổi nội dung của tệp. Điều này bao gồm các tệp mới / bị xóa, đổi tên / sao chép tệp và thay đổi quyền.
Cuối cùng, có một dòng như thế index 789bd4..0afb621 100644
. Có thể bạn sẽ không bao giờ quan tâm đến nó, nhưng các số hex gồm 6 chữ số đó là các băm SHA1 viết tắt của các đốm màu cũ và mới cho tệp này (một blob là một đối tượng git lưu trữ dữ liệu thô như nội dung của tệp). Và tất nhiên, 100644
chế độ của tệp - ba chữ số cuối cùng rõ ràng là quyền; ba phần đầu cung cấp thêm thông tin siêu dữ liệu ( bài SO mô tả điều đó ).
Sau đó, bạn tiếp tục với đầu ra khác biệt thống nhất tiêu chuẩn (giống như cổ điển diff -U
). Nó được chia thành nhiều phần - một hunk là một phần của tệp chứa các thay đổi và bối cảnh của chúng. Mỗi hunk được đi trước bởi một cặp ---
và +++
các dòng biểu thị tệp đang được đề cập, sau đó khác biệt thực tế là (theo mặc định) ba dòng ngữ cảnh ở hai bên -
và +
các dòng hiển thị các dòng bị xóa / thêm.
index
dòng. Xác nhận vớigit hash-object ./file