หน้าคนสำหรับgit-diff
ค่อนข้างยาวและอธิบายหลายกรณีซึ่งดูเหมือนจะไม่จำเป็นสำหรับผู้เริ่มต้น ตัวอย่างเช่น:
git diff origin/master
หน้าคนสำหรับgit-diff
ค่อนข้างยาวและอธิบายหลายกรณีซึ่งดูเหมือนจะไม่จำเป็นสำหรับผู้เริ่มต้น ตัวอย่างเช่น:
git diff origin/master
คำตอบ:
ให้ดูตัวอย่างขั้นสูงต่างจากประวัติ git (ในการกระทำ 1088261f ในที่เก็บ 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] == '-') {
ให้วิเคราะห์ชุดข้อมูลแก้ไขนี้เป็นรายบรรทัด
บรรทัดแรก
diff --git a / builtin-http-fetch.cb / http-fetch.cคือ "คอมไพล์ diff"
diff --git a/file1 b/file2
ส่วนหัวในรูปแบบ a/
และb/
ชื่อไฟล์เหมือนกันเว้นแต่การเปลี่ยนชื่อ / คัดลอกมีส่วนเกี่ยวข้อง (เช่นในกรณีของเรา) --git
คือหมายถึงความแตกต่างที่อยู่ใน "คอมไพล์" รูปแบบต่างถัดไปเป็นบรรทัดส่วนหัวที่ขยายอย่างน้อยหนึ่งบรรทัด สามคนแรก
ดัชนีความคล้ายคลึงกัน 95% เปลี่ยนชื่อจาก builtin-http-fetch.c เปลี่ยนชื่อเป็น http-fetch.cแจ้งให้เราทราบว่าไฟล์ถูกเปลี่ยนชื่อจาก
builtin-http-fetch.c
เป็นhttp-fetch.c
และทั้งสองไฟล์นั้นเหมือนกัน 95% (ซึ่งใช้ในการตรวจจับการเปลี่ยนชื่อนี้) ดัชนี f3e63d7..e8f44ba 100644บอกเราเกี่ยวกับโหมดของไฟล์ที่กำหนด (
100644
หมายความว่ามันเป็นไฟล์ธรรมดาและไม่ใช่เช่น symlink และมันไม่มีบิตอนุญาตให้ใช้งานได้) และแฮชของ preimage ที่สั้นลง (เวอร์ชันของไฟล์ก่อนการเปลี่ยนแปลงที่กำหนด) และ postimage ( รุ่นของไฟล์หลังจากการเปลี่ยนแปลง) บรรทัดนี้ใช้git am --3way
เพื่อพยายามทำแบบ 3 ทางถ้าไม่สามารถใช้โปรแกรมแก้ไขได้ถัดไปคือส่วนหัว diff แบบรวมสองบรรทัด
--- a / builtin-http-fetch.c +++ b / http-fetch.cเมื่อเปรียบเทียบกับ
diff -U
ผลลัพธ์จะไม่มีชื่อไฟล์จากการแก้ไขเวลาหรือแก้ไขไฟล์เวลาหลังจากแหล่งที่มา (preimage) และชื่อปลายทาง (postimage) หากไฟล์ถูกสร้างขึ้นแหล่งที่มาคือ/dev/null
; /dev/null
หากไฟล์ถูกลบไปแล้วเป้าหมายคือ diff.mnemonicPrefix
ตัวแปรการกำหนดค่าให้เป็นจริงในสถานที่a/
และb/
คำนำหน้าในส่วนหัวของสองบรรทัดนี้คุณสามารถมีแทนc/
, i/
, w/
และo/
เป็นคำนำหน้าตามลำดับกับสิ่งที่คุณเปรียบเทียบ; ดูgit-config (1)ถัดไปมาหนึ่งหรือมากกว่าของความแตกต่าง ก้อนใหญ่แต่ละอันจะแสดงพื้นที่หนึ่งที่ไฟล์ต่างกัน hunks รูปแบบแบบรวมเริ่มด้วยบรรทัดเหมือน
@@ -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>
ทั้งบรรทัดเริ่มต้นและจำนวนบรรทัดอ้างอิงตำแหน่งและความยาวของก้อนใหญ่ใน preimage และ postimage ตามลำดับ หากจำนวนบรรทัดไม่แสดงก็หมายความว่ามันเป็น 0
ส่วนหัวที่เป็นทางเลือกจะแสดงฟังก์ชั่น C ที่การเปลี่ยนแปลงแต่ละอย่างเกิดขึ้นถ้าเป็นไฟล์ C (เช่น-p
ตัวเลือกใน GNU diff) หรือเทียบเท่าถ้ามีสำหรับไฟล์ประเภทอื่น ๆ
ถัดไปคือคำอธิบายของไฟล์ที่แตกต่างกัน บรรทัดที่ใช้ร่วมกันของทั้งสองไฟล์เริ่มต้นด้วยอักขระเว้นวรรค บรรทัดที่แตกต่างกันระหว่างสองไฟล์มีหนึ่งในตัวบ่งชี้ต่อไปนี้ในคอลัมน์พิมพ์ด้านซ้าย:
ตัวอย่างเช่นอันแรก
#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;
อาจจะมี
\ ไม่มีการขึ้นบรรทัดใหม่เมื่อสิ้นสุดไฟล์บรรทัดปัจจุบัน (ไม่อยู่ในตัวอย่างต่าง)
ดังที่Donal Fellows กล่าวว่าเป็นการดีที่สุดที่จะฝึกฝนการอ่านแตกต่างจากตัวอย่างในชีวิตจริงที่คุณรู้ว่าคุณเปลี่ยนแปลงอะไร
อ้างอิง:
git blame -C -C
ซึ่งเป็นวิธีการทำงาน มันคือการตัดสินใจออกแบบ Git รูปแบบ git diff เพียงแสดงความคล้ายคลึงกัน (หรือความแตกต่าง) ดัชนีให้กับผู้ใช้
[header]
เป็นสิ่งที่ใกล้เคียงที่สุดกับการเริ่มต้นของฟังก์ชันที่นำหน้าก้อนใหญ่ ในกรณีส่วนใหญ่บรรทัดนี้รวมถึงชื่อของฟังก์ชั่นซึ่งเป็นส่วนต่างของ สิ่งนี้สามารถกำหนดค่าได้ด้วยdiff
gitattribute ที่ตั้งค่าเป็นไดรเวอร์ diff และไดรเวอร์ diff รวมถึงxfuncname
ตัวแปรการกำหนดค่า
@@ -1,2 +3,4 @@
ส่วนหนึ่งของความแตกต่าง
ส่วนนี้ทำให้ฉันเข้าใจในขณะที่ดังนั้นฉันได้สร้างตัวอย่างที่น้อยที่สุด
รูปแบบนั้นเหมือนกันกับ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
+
หมายถึง "ใหม่"
เรามีเพียง 4 บรรทัดแทน 6 เพราะลบ 2 บรรทัดออก! ก้อนใหญ่ใหม่เป็นเพียง:
1
4
5
6
@@ -11,6 +9,4 @@
สำหรับก้อนที่สองนั้นคล้ายคลึงกัน:
บนไฟล์เก่าเรามี 6 บรรทัดเริ่มต้นที่บรรทัดที่ 11 ของไฟล์เก่า:
11
12
13
14
15
16
ในไฟล์ใหม่เรามี 4 บรรทัดเริ่มต้นที่บรรทัดที่ 9 ของไฟล์ใหม่:
11
12
13
16
โปรดทราบว่าบรรทัด11
นั้นเป็นบรรทัดที่ 9 ของไฟล์ใหม่เนื่องจากเราได้ลบ 2 บรรทัดในก้อนใหญ่ก่อนหน้านี้: 2 และ 3
ส่วนหัวก้อนใหญ่
คุณสามารถรับรหัสบรรทัดถัดจาก@@
บรรทัดได้เช่นfunc1() {
ใน:
@@ -4,7 +4,6 @@ func1() {
นอกจากนี้ยังสามารถรับได้กับธงของธรรมดา-p
diff
ตัวอย่าง: ไฟล์เก่า:
func1() {
1;
2;
3;
4;
5;
6;
7;
8;
9;
}
หากเราลบบรรทัด6
diff จะแสดง:
@@ -4,7 +4,6 @@ func1() {
3;
4;
5;
- 6;
7;
8;
9;
โปรดทราบว่านี้ไม่ได้เป็นสายที่ถูกต้องสำหรับfunc1
: มันข้ามเส้นและ1
2
คุณสมบัติที่ยอดเยี่ยมนี้มักจะบอกได้อย่างชัดเจนว่าฟังก์ชันหรือคลาสใดที่อยู่ในแต่ละก้อนซึ่งมีประโยชน์มากในการแปลความแตกต่าง
อัลกอริทึมในการเลือกส่วนหัวทำงานตรงตามที่ได้กล่าวไว้ที่: ข้อความที่ตัดตอนมาในส่วนหัว diff diff git มาจากไหน
@@ -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>
ที่จุดเริ่มต้นของเส้นเหล่านั้นมันใช้กับการตีความของ hunks ตัวอย่างที่ชัดเจนยิ่งขึ้น: 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
ไม่ใช่คำสั่งซึ่งหมายความว่าเป็นรุ่น git ของ diff (ไม่ใช่ unix)a/ b/
เป็นไดเรกทอรีพวกเขาไม่ใช่ของจริง เป็นเพียงความสะดวกสบายเมื่อเราจัดการกับไฟล์เดียวกัน (ในกรณีของฉัน a / อยู่ในดัชนีและ b / อยู่ในไดเรกทอรีทำงาน)10ff2df..84d4fa2
เป็น ID หยดของ 2 ไฟล์เหล่านี้100644
คือ“ บิตโหมด” ซึ่งบ่งชี้ว่านี่เป็นไฟล์ปกติ (ไม่สามารถเรียกใช้งานได้และไม่ใช่ลิงก์สัญลักษณ์)--- a/file +++ b/file
เครื่องหมายลบแสดงบรรทัดใน a / version แต่หายไปจาก b / version และเครื่องหมายบวกแสดงบรรทัดที่ขาดหายไปใน / แต่ปรากฏใน 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
) จะต้องอ่านในฐานแปด (ค่า: 1, 2, 4 ตามลำดับ eXecute, เขียนและอ่านสิทธิ์) และสอดคล้องในลำดับที่เจ้าของ (ผู้ใช้) จากนั้นกลุ่มแล้วสิทธิ์อื่น ๆ ดังนั้นในระยะสั้น644
จะหมายถึงถ้าเขียนสัญลักษณ์u=rw,og=r
ที่ทุกคนสามารถอ่านได้ แต่เขียนโดยเจ้าของเท่านั้น ตัวเลขอื่น ๆ ที่อยู่ด้านซ้ายเข้ารหัสข้อมูลอื่น ๆ เช่นถ้าเป็น symlink เป็นต้นสามารถดูค่าได้github.com/git/git/blob/ ...... 1 อันดับแรกในตำแหน่งนี้คือ "ไฟล์ปกติ"
รูปแบบเอาต์พุตเริ่มต้น (ซึ่ง แต่เดิมมาจากโปรแกรมที่รู้จักกันในชื่อdiff
หากคุณต้องการค้นหาข้อมูลเพิ่มเติม) เรียกว่า "diff แบบรวม" มันมีสายที่แตกต่างกัน 4 ประเภท:
+
,-
, และฉันแนะนำให้คุณฝึกอ่านความแตกต่างระหว่างสองเวอร์ชันของไฟล์ที่คุณรู้ว่าคุณเปลี่ยนแปลงอะไร เช่นเดียวกับที่คุณจะรับรู้สิ่งที่เกิดขึ้นเมื่อคุณเห็นมัน
ใน mac ของฉัน:
info diff
จากนั้นเลือก: Output formats
-> Context
-> Unified format
-> Detailed Unified
:
หรือคนออนไลน์แตกต่าง gnu ตามเส้นทางเดียวกันไปยังส่วนเดียวกัน:
ไฟล์: diff.info, โหนด: Detailed Unified, ถัดไป: ตัวอย่าง Unified, Up: Unified Format
คำอธิบายโดยละเอียดของรูปแบบ Unified ......................................
รูปแบบเอาต์พุตแบบรวมเริ่มต้นด้วยส่วนหัวสองบรรทัดซึ่งมีลักษณะดังนี้:
--- FROM-FILE FROM-FILE-MODIFICATION-TIME +++ TO-FILE TO-FILE-MODIFICATION-TIME
การประทับเวลาดูเหมือนว่า `2002-02-21 23: 30: 39.942229878 -0800 'เพื่อระบุวันที่เวลาที่มีเศษส่วนวินาทีและเขตเวลา
คุณสามารถเปลี่ยนเนื้อหาส่วนหัวด้วยตัวเลือก `--label = LABEL ' โปรดดู * หมายเหตุชื่อสำรอง ::
ถัดไปมาหนึ่งหรือมากกว่าของความแตกต่าง ก้อนใหญ่แต่ละอันจะแสดงพื้นที่หนึ่งที่ไฟล์ต่างกัน hunks รูปแบบรวมมีลักษณะดังนี้:
@@ FROM-FILE-RANGE TO-FILE-RANGE @@ LINE-FROM-EITHER-FILE LINE-FROM-EITHER-FILE...
บรรทัดที่ใช้ร่วมกันของทั้งสองไฟล์เริ่มต้นด้วยอักขระเว้นวรรค บรรทัดที่แตกต่างกันระหว่างสองไฟล์มีหนึ่งในตัวบ่งชี้ต่อไปนี้ในคอลัมน์พิมพ์ด้านซ้าย:
`+ 'มีการเพิ่มบรรทัดในไฟล์แรก
`- 'มีการลบบรรทัดออกจากไฟล์แรก
ไม่ชัดเจนจากคำถามของคุณว่าส่วนใดของ diffs ที่คุณสับสน: 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 หลักเหล่านี้เป็นตัวย่อของ SHA1 hash ของ blobs เก่าและใหม่สำหรับไฟล์นี้ (blob เป็นวัตถุ git ที่เก็บข้อมูลดิบเช่นเนื้อหาของไฟล์) และแน่นอน100644
โหมดของไฟล์คือ - ตัวเลขสามหลักสุดท้ายคือการอนุญาตที่ชัดเจน สามคนแรกให้ข้อมูลเมตาดาต้าไฟล์เพิ่มเติม ( ดังนั้นโพสต์อธิบายว่า )
หลังจากนั้นคุณก็จะได้เอาต์พุตมาตรฐานแบบรวม (เช่นเดียวกับแบบคลาสสิคdiff -U
) มันแบ่งออกเป็น hunks - ก้อนใหญ่เป็นส่วนของไฟล์ที่มีการเปลี่ยนแปลงและบริบทของมัน แต่ละก้อนใหญ่นำหน้าด้วยคู่ของ---
และ+++
บรรทัดที่แสดงถึงไฟล์ที่เป็นปัญหาจากนั้น diff ที่แท้จริงคือ (โดยค่าเริ่มต้น) บริบทสามบรรทัดที่ด้านใดด้านหนึ่งของ-
และ+
บรรทัดที่แสดงบรรทัดที่ถูกลบ / เพิ่ม
index
บรรทัด ยืนยันด้วยgit hash-object ./file