Git แตกต่างกับหมายเลขบรรทัด (บันทึก Git พร้อมหมายเลขบรรทัด)


93

เมื่อฉันทำ a git diffหรือ a git log -pฉันจะรับหมายเลขบรรทัดของไฟล์ต้นฉบับที่อยู่ในบรรทัดกับผลลัพธ์ได้อย่างไร

ฉันพยายามมองขึ้นไปman git-diff | grep "line numbers"และพยายามใช้ googling แต่ก็ไม่มีอะไรเร็ว

คำตอบ:


92

คุณไม่สามารถรับหมายเลขบรรทัดที่มนุษย์อ่านได้ด้วย git diff

มียังไม่ได้ตัวเลือกใด ๆ git diffที่จะได้รับหมายเลขบรรทัดแสดงในแนวตั้งที่ด้านข้างด้วย

รูปแบบ Unified-diff

ข้อมูลนั้นมีอยู่ในส่วนหัว (c) hunk สำหรับการเปลี่ยนแปลงแต่ละครั้งในความแตกต่าง แต่เป็นเพียงรูปแบบ unified-diff :

@@ -start,count +start,count @@

สถานะดั้งเดิมของไฟล์จะแสดงด้วย-และสถานะใหม่จะแสดงด้วย+(ไม่ได้หมายถึงการเพิ่มและการลบในส่วนหัว hunk startแสดงถึงหมายเลขบรรทัดเริ่มต้นของไฟล์แต่ละเวอร์ชันและcountแสดงจำนวนบรรทัดที่รวมอยู่ด้วย โดยเริ่มจากจุดเริ่มต้น

ตัวอย่าง

diff --git a/osx/.gitconfig b/osx/.gitconfig
index 4fd8f04..fcd220c 100644
--- a/osx/.gitconfig
+++ b/osx/.gitconfig
@@ -11,7 +11,7 @@ <== HERE!
 [color "branch"]
        upstream = cyan
 [color "diff"]
-       meta = yellow
+       meta = cyan
        plain = white dim
        old = red bold
        new = green bold

ส่วนหัวของ hunk

@@ -11,7 +11,7 @@

บอกว่าไฟล์เวอร์ชันก่อนหน้าเริ่มต้นที่บรรทัด 11 และมี 7 บรรทัด:

11  [color "branch"]
12         upstream = cyan
13  [color "diff"]
14 -       meta = yellow
14 +       meta = cyan
15         plain = white dim
16         old = red bold
17         new = green bold

ในขณะที่เวอร์ชันถัดไปของไฟล์จะเริ่มต้นที่บรรทัดที่ 11 และมี 7 บรรทัดด้วย

รูปแบบ Unified-diff ไม่ได้มีไว้สำหรับการบริโภคของมนุษย์จริงๆ

อย่างที่คุณสามารถบอกได้ว่ารูปแบบ Unified-diff ไม่ได้ทำให้ง่ายต่อการหาหมายเลขบรรทัด (อย่างน้อยถ้าคุณไม่ใช่เครื่องจักร) หากคุณต้องการหมายเลขบรรทัดที่อ่านได้จริงๆคุณจะต้องใช้เครื่องมือที่แตกต่างซึ่งจะแสดงให้คุณ

การอ่านเพิ่มเติม


4
นี่คือ grep เพื่อแยกเฉพาะหมายเลขบรรทัดในไฟล์ที่แก้ไขเช่นใช้เพื่อกรองรายงานรูปแบบการตรวจสอบgit diff --unified=0 | grep -Po '^\+\+\+ ./\K.*|^@@ -[0-9]+(,[0-9]+)? \+\K[0-9]+(,[0-9]+)?(?= @@)'
Jakub Bochenski

1
ความคิดเห็นของ @JakubBochenski แก้ปัญหาของฉันได้ดีทีเดียว
0xbe5077ed

สิ่งนี้จะมีประโยชน์มากก็ต่อเมื่อคุณระบุ--unified=0หรือ-U0แม้ว่า
caw

ฉันเพิ่งเสร็จสิ้นgit diffnการแทนที่แบบหล่นลง (กระดาษห่อหุ้ม) git diffซึ่งแสดงหมายเลขบรรทัดและมีความเข้ากันได้อย่างสมบูรณ์กับการใช้งานและตัวเลือกทั้งหมดของgit diff: stackoverflow.com/questions/24455377/…
Gabriel Staples

22

ต่อไปนี้เป็นโซลูชันเพิ่มเติมอีกสองวิธีซึ่งขยายจากโค้ดของ Andy Talkowski

ข้อความธรรมดา:

  git diff | gawk 'match($0,"^@@ -([0-9]+),[0-9]+ [+]([0-9]+),[0-9]+ @@",a){left=a[1];right=a[2];next};\
   /^(---|\+\+\+|[^-+ ])/{print;next};\
   {line=substr($0,2)};\
   /^-/{print "-" left++ ":" line;next};\
   /^[+]/{print "+" right++ ":" line;next};\
   {print "(" left++ "," right++ "):"line}'

ข้อความสีโดยสมมติว่า\033[66mเป็นรูปแบบของรหัสสี:

  git diff --color=always | \
    gawk '{bare=$0;gsub("\033[[][0-9]*m","",bare)};\
      match(bare,"^@@ -([0-9]+),[0-9]+ [+]([0-9]+),[0-9]+ @@",a){left=a[1];right=a[2];next};\
      bare ~ /^(---|\+\+\+|[^-+ ])/{print;next};\
      {line=gensub("^(\033[[][0-9]*m)?(.)","\\2\\1",1,$0)};\
      bare~/^-/{print "-"left++ ":" line;next};\
      bare~/^[+]/{print "+"right++ ":" line;next};\
      {print "("left++","right++"):"line;next}'

รหัสการเปลี่ยนแปลงเส้นที่เริ่มต้นด้วย-และ+ไป-1:-และ+1:+ตามลำดับและเส้นที่เริ่มต้นด้วยอะไรไป (5,6):ตัวเลขคือหมายเลขบรรทัดจากไฟล์ที่เกี่ยวข้อง


ฉันสังเกตเห็นว่ามันแตกการจัดแนว (การเยื้อง) ของโค้ดในขณะที่เนทีฟจะgit diffรักษาการจัดตำแหน่งอย่างระมัดระวัง รหัสนี้อยู่เหนือหัวของฉันในขณะนี้คุณยินดีที่จะแก้ไขหรือไม่ กล่าวอีกนัยหนึ่งคือเมื่อบรรทัดหนึ่งพูด+240:+และบรรทัดถัดไปกล่าวว่า(241,257):คุณต้องเพิ่มช่องว่างพิเศษในบรรทัดบนสุดเพื่อให้โค้ดคงการจัดตำแหน่งและการเยื้องที่เหมาะสมด้วยโค้ดจากบรรทัดล่าง บางทีสิ่งนี้สามารถทำได้อย่างง่ายดายด้วยการพิมพ์?
Gabriel Staples

... printfผมหมายถึงกับ
Gabriel Staples


ไม่เป็นไร; ฉันเข้าใจแล้ว! git diffnฉันเพิ่งเสร็จสิ้น ดูที่นี่: stackoverflow.com/a/61997003/4561887 ขอบคุณ @PFudd สำหรับคำตอบของคุณ git diffnผมเรียนมันและใช้มันในการเรียนรู้จากนั้นก็เริ่มจากรอยขีดข่วนและเขียน เมื่อจัดรูปแบบแล้วฉันก็สามารถอ่านโค้ดของคุณได้ (ขอบคุณ @EdMorton) ฉันสามารถเรียนรู้สิ่งดีๆจากมันซึ่งช่วยฉันได้
Gabriel Staples

6

นี่คือสคริปต์ที่พยายามแก้ไข - ไม่ได้ทดสอบด้วยความโกรธ แต่ดูเหมือนว่าโอเค มันขึ้นอยู่กับความแตกต่างของเร็กคอร์ด git สร้างและใช้ awk เพื่อรักษาการนับบรรทัด

# Massage the @@ counts so they are usable
function prep1() {
   cat | awk -F',' 'BEGIN { convert = 0; }
       /^@@ / { convert=1; }
       /^/  { if ( convert == 1 ) { print $1,$2,$3;
              } else { print $0;
              }
              convert=0;
             }'
}

# Extract all new changes added with the line count
function prep2() {
  cat | awk 'BEGIN { display=0; line=0; left=0; out=1;}
     /^@@ / { out=0; inc=0; line=$4; line--; display=line; left=line;        }
     /^[-]/   { left++; display=left; inc=0; }
     /^[+]/   { line++; display=line; inc=0; }
     /^[-+][-+][-+] / { out=0; inc=0; }
     /^/    { 
               line += inc;
               left += inc;
               display += inc;
               if ( out == 1 ) {
                   print display,$0;
               } else {
                   print $0;
               }
               out = 1;
               inc = 1;
               display = line;
            }'
} 

git diff $1 | prep1 | prep2 

4

คุณสามารถใช้git difftoolเพื่อสร้างความแตกต่างด้วยโปรแกรมแก้ไขภายนอกที่จะแสดงหมายเลขบรรทัด นี่คือวิธีดำเนินการกับ vim / vimdiff:

  1. ตั้ง vimdiff เป็น difftool ของ git:

    git config --global diff.tool vimdiff
    
  2. กำหนดค่า~/.vimrcให้แสดงหมายเลขบรรทัดโดยอัตโนมัติเมื่อใช้ vimdiff:

    if &diff
        set number
    endif
    
  3. เรียกใช้ git difftool ซึ่งจะใช้ vimdiff พร้อมหมายเลขบรรทัด:

    git difftool
    

โดยการทำ git difftool เท่านั้นมันจึงเปิดเครื่องมือ tkdiff ให้ฉันซึ่งมันมีฟังก์ชันหมายเลขบรรทัด ขอบคุณ wisbucky
Richardd

4

git diff -U0วิธีที่รวดเร็วคือการใช้งาน ซึ่งจะกำหนดบรรทัดของบริบทเป็น 0 ซึ่งจะทำให้ค่า @@ ตรงกับบรรทัดที่เปลี่ยนแปลงจริง โดยค่าเริ่มต้นค่า @@ จะรวมบริบทก่อน / หลัง 3 บรรทัดซึ่งไม่สะดวกสำหรับมนุษย์

ตัวอย่าง:

git diff # default
@@ -10,8 +10,8 @@

นี่เป็นการยากที่จะคำนวณหมายเลขบรรทัดของบรรทัดที่เปลี่ยนแปลงเนื่องจากบรรทัด 10 หมายถึงบรรทัดแรกของบริบทก่อน หมายเลขบรรทัดจริงของบรรทัดแรกที่เปลี่ยนแปลงคือ 10 + 3 = 13 ในการคำนวณจำนวนบรรทัดที่เปลี่ยนแปลงคุณต้องลบบริบทก่อนและหลังด้วย: 8-3-3 = 2

git diff -U0
@@ -13,2 +13,2 @@

อย่างที่คุณเห็นการตั้งค่าบริบท = 0 ทำให้มนุษย์อ่านค่า @@ ได้ง่ายขึ้น คุณจะเห็นว่าเส้นที่เปลี่ยนแปลงเริ่มต้นที่บรรทัดที่ 13 และมี 2 บรรทัดที่เปลี่ยนแปลง

สิ่งนี้ไม่สมบูรณ์แบบเนื่องจากจะแสดงเฉพาะหมายเลขบรรทัดสำหรับแต่ละบล็อก หากคุณต้องการดูหมายเลขบรรทัดสำหรับทุกบรรทัดให้ใช้ difftool สำหรับโปรแกรมแก้ไขภายนอก ดูhttps://stackoverflow.com/a/50049752


3

ฉันชอบใช้git difftoolกับmeldเป็น difftool ของฉัน ดูง่ายกว่าgit diffมีการเปรียบเทียบ gui แบบเคียงข้างกันที่ดีและแสดงหมายเลขบรรทัดในแต่ละด้าน

ติดตั้ง:

  1. คำแนะนำเกี่ยวกับวิธีตั้งค่า meld เป็น difftool สำหรับ Windows หรือ Linux

ภาพหน้าจอตัวอย่าง:

ป้อนคำอธิบายภาพที่นี่

อัปเดต 24 พฤษภาคม 2020:

ฉันเพิ่งเขียนgit diffnในช่วงสองสามวันที่ผ่านมาเพื่อเป็นตัวทดแทนgit diffในบรรทัดคำสั่ง ให้มันยิง ดูคำตอบอื่น ๆ ของฉันที่นี่


3

ณ วันที่ 24 พฤษภาคม 2020 คุณสามารถใช้เครื่องมือของบุคคลที่สามได้แล้วgit diffn(การเปิดเผยข้อมูลทั้งหมด: ฉันเขียนไว้แล้ว) เพื่อจุดประสงค์นี้ มันเป็นกระดาษห่อน้ำหนักเบารอบgit diffที่เขียนในawkรูปแบบ / การดำเนินการตามภาษาการเขียนโปรแกรม นี่คือตัวอย่างผลลัพธ์จากการทำงานgit diffn:

ป้อนคำอธิบายภาพที่นี่

1/3: มันคืออะไร?

จากด้านบนของgit-diffn.sh :

คำอธิบาย:

git-diffn.sh

  1. การแทนที่แบบหล่นลงgit diffซึ่งแสดงบรรทัด 'n'umbers ด้วย! ใช้มันตรงเช่นgit diffยกเว้นคุณจะเห็นหมายเลขบรรทัดที่สวยงามเหล่านี้เช่นกันที่จะช่วยให้คุณให้ความรู้สึกของการเปลี่ยนแปลงของคุณ

  2. เนื่องจากเป็นเพียงกระดาษห่อหุ้มที่ใช้ภาษา awk ซึ่งมีน้ำหนักเบาgit diffจึงยอมรับตัวเลือกและพารามิเตอร์ทั้งหมดที่git diffยอมรับ ตัวอย่าง:

  3. git diffn HEAD~

  4. git diffn HEAD~3..HEAD~2

  5. ใช้งานได้กับgit diffการตั้งค่าสีของคุณแม้ว่าคุณจะใช้สีที่กำหนดเองก็ตาม

  6. ดูคำตอบของฉันที่นี่สำหรับวิธีตั้งค่าสีต่างแบบกำหนดเองรวมถึงดูภาพหน้าจอของเอาต์พุตสีที่กำหนดเองจากgit diffn: คุณปรับแต่งสีของส่วนหัว diff ใน git diff ได้อย่างไร

  7. นี่คือตัวอย่างgit configคำสั่งบางส่วนจากคำตอบของฉันด้านบนเพื่อกำหนดgit diffสีและแอตทริบิวต์ที่กำหนดเอง(การจัดรูปแบบข้อความ):

       git config --global color.diff.meta "blue"
       git config --global color.diff.old "black red strike"
       git config --global color.diff.new "black green italic"
       git config --global color.diff.context "yellow bold"
    
  8. ในgit diffnเอาต์พุตสีจะเปิดโดยค่าเริ่มต้น หากคุณต้องการปิดการใช้งานสีของผลลัพธ์คุณต้องใช้--no-colorหรือ--color=never. ดูman git diffรายละเอียด ตัวอย่าง:

     git diffn --color=never HEAD~
     git diffn --no-color HEAD~3..HEAD~2
    

2/3: การติดตั้ง

  1. Windows (ยังไม่ทดสอบ): สิ่งนี้อาจใช้ได้ภายใน bash terminal ที่มาพร้อมกับGit สำหรับ Windowsแต่ยังไม่ได้ทดสอบ ติดตั้ง Git สำหรับ Windows เปิดขั้ว bash ที่มาพร้อมกับและลองทำตามคำแนะนำด้านล่าง ฉันต้องการผู้ทดสอบที่จะทดสอบสิ่งนี้ใน Git สำหรับ Windows โปรดดูและตอบที่นี่: https://github.com/git-for-windows/git/issues/2635
  2. Mac (ยังไม่ทดลอง): ใช้เทอร์มินัลและปฏิบัติตามคำแนะนำด้านล่าง gawkคุณอาจจะต้องติดตั้ง ถ้าเป็นเช่นนั้นลองนี้brew install gawk :
  3. Linux (ทดสอบบน Ubuntu 18.04 และทำงานได้อย่างสมบูรณ์): ทำตามคำแนะนำเทอร์มินัลด้านล่าง

ตัวเลือกที่ 1 (คำแนะนำของฉัน):ดาวน์โหลด repo ทั้งหมดจากนั้นสร้าง symlink ไปยังโปรแกรมเพื่อให้คุณสามารถรับการอัปเดตได้อย่างง่ายดายโดยทำgit pullจาก repo เมื่อใดก็ตามที่คุณต้องการ

ขั้นแรกcdไปที่ใดก็ได้ที่คุณต้องการติดตั้ง จากนั้นเรียกใช้:

git clone https://github.com/ElectricRCAircraftGuy/eRCaGuy_dotfiles.git
cd eRCaGuy_dotfiles/useful_scripts
mkdir -p ~/bin
ln -si "${PWD}/git-diffn.sh" ~/bin/git-diffn

เสร็จแล้ว! ตอนนี้ทำขั้นตอนสุดท้ายด้านล่าง!

ตัวเลือกที่ 2 (สำหรับผู้ที่ต้องการเพียง 1 ไฟล์):ดาวน์โหลดเพียงไฟล์เดียวครั้งเดียว

mkdir -p ~/bin
cd ~/bin
wget https://raw.githubusercontent.com/ElectricRCAircraftGuy/eRCaGuy_dotfiles/master/useful_scripts/git-diffn.sh
chmod +x git-diffn.sh
mv git-diffn.sh git-diffn

เสร็จแล้ว! ตอนนี้ทำขั้นตอนสุดท้ายด้านล่าง!

ขั้นตอนสุดท้าย:

ตอนนี้ปิดและเปิดเทอร์มินัลของคุณใหม่หรือเปลี่ยนแหล่งที่มาใหม่ด้วย . ~/.bashrcและคุณทำเสร็จแล้ว!

git diffn ตอนนี้จะทำงานแทนดรอปอินที่แน่นอนสำหรับ git diff !

นี่คือตัวอย่าง:

3/3: การสาธิตของ git diffn :

สร้างไฟล์นี้:

hello_world.c:

#include <stdio.h>

int main()
{
    printf("Hello World\n");

    return 0;
}

ยอมรับมัน:

git add hello_world.c
git commit -m "add hello_world.c"

เปลี่ยนเป็นสิ่งนี้และบันทึกไฟล์:

hello_world.c:

// Basic hello world example

#include <stdio.h>

int main(int argc, char *argv[])
{
    printf("Hello Gabriel\n");
    
    int i = 700;
    printf("i = %i\n", i);
    return 0;
}

ตอนนี้เรียกใช้:

git diff

นี่คือผลลัพธ์ของgit diffอันดับแรกเพื่อวัตถุประสงค์ในการเปรียบเทียบ:

$ git diff
diff --git a/hello_world.c b/hello_world.c
index e01704a..e971b73 100644
--- a/hello_world.c
+++ b/hello_world.c
@@ -1,8 +1,12 @@
+// Basic hello world example
+
 #include <stdio.h>
 
-int main()
+int main(int argc, char *argv[])
 {
-    printf("Hello World\n");
-
+    printf("Hello Gabriel\n");
+    
+    int i = 700;
+    printf("i = %i\n", i);
     return 0;
-}
\ No newline at end of file
+}

และสกรีนช็อตเพื่อแสดงสี โปรดทราบว่าส่วนที่เน้นสีแดงเป็นเพียงการแสดงช่องว่าง (ช่องว่างในกรณีนี้) ที่สามารถลบได้:

ป้อนคำอธิบายภาพที่นี่

ตอนนี้นี่คือผลลัพธ์ของgit diffn. สังเกตว่ามันแสดงหมายเลขบรรทัดทั้งหมดอย่างสมบูรณ์แบบ!

  • หมายเลขบรรทัดสำหรับบรรทัดที่ถูกลบจะอยู่ทางด้านซ้ายและแสดง-เครื่องหมายทั้งทางซ้ายสุดและทางขวาของ:เพื่อช่วยให้คุณมองเห็นได้ดีขึ้นไม่ว่าดวงตาของคุณจะชอบสแกนลงไปทางขวาของลำไส้ใหญ่หรือด้านล่าง ด้านซ้ายของหน้าจอ
  • หมายเลขบรรทัดสำหรับบรรทัดที่เพิ่มจะอยู่ห่างออกไปทางขวาและแสดง+เครื่องหมายทั้งทางซ้ายสุดและทางขวาของ:สัญญาณทั้งด้านซ้ายสุดและไปทางขวาของ
  • หมายเลขบรรทัดสำหรับบรรทัดที่ไม่เปลี่ยนแปลงที่แสดงสำหรับบริบทจะแสดงสำหรับทั้งด้านซ้าย (ไฟล์เก่า) และด้านขวา (ไฟล์ใหม่) คั่นด้วยไฟล์,.

ผลลัพธ์ของgit diffn:

$ git diffn
diff --git a/hello_world.c b/hello_world.c
index e01704a..e971b73 100644
--- a/hello_world.c
+++ b/hello_world.c
@@ -1,8 +1,12 @@
+        1:+// Basic hello world example
+        2:+
    1,   3: #include <stdio.h>
    2,   4: 
-   3     :-int main()
+        5:+int main(int argc, char *argv[])
    4,   6: {
-   5     :-    printf("Hello World\n");
-   6     :-
+        7:+    printf("Hello Gabriel\n");
+        8:+    
+        9:+    int i = 700;
+       10:+    printf("i = %i\n", i);
    7,  11:     return 0;
-   8     :-}
\ No newline at end of file
+       12:+}

และสกรีนช็อตเพื่อแสดงสี สังเกตว่าเครื่องหมายทวิภาคจะไม่เป็นสีหรือปรับสไตล์ให้ตรงกับข้อความรอบข้างทางซ้ายและขวา นี่คือพฤติกรรมโดยเจตนาและออกแบบมาเพื่อทำหน้าที่เป็นตัวคั่นภาพระหว่างหมายเลขบรรทัดที่เพิ่มทางด้านซ้ายและgit diffเอาต์พุตดั้งเดิมทางด้านขวา

ป้อนคำอธิบายภาพที่นี่


1

คุณสามารถลอง

git blame

บนไฟล์ มันจะแสดงให้คุณเห็นคอมมิตไอดีคอมมิตและหมายเลขบรรทัดสำหรับแต่ละบรรทัดในไฟล์


4
ปัญหานี้คือมันไม่แสดงความแตกต่างซึ่งเป็นสิ่งที่ผู้โพสต์ต้นฉบับขอ git blameจะแสดงสถานะปัจจุบันของไฟล์พร้อมหมายเลขบรรทัด

5
ฉันรู้เกี่ยวกับ git ตำหนิ แต่บางคนอาจไม่มี googling มันอาจช่วยใครบางคนได้ ขอบคุณสำหรับคำตอบ.
Drew LeSueur

git blameไม่มีทางตอบคำถาม; ฉันค่อนข้างงุนงงกับการโหวตเพิ่มที่นี่
Michael Mrozek

โปรดอย่าสแปมสแต็กโอเวอร์โฟลว์ด้วยคำตอบที่ไม่เกี่ยวข้องกับคำถาม
Ahmed

0

ขั้นแรกกำหนดค่าเครื่องมือ git diff ของคุณเช่น Meld

git config --global diff.tool meld

จากนั้นดึง difftool ของคุณในไฟล์บางไฟล์:

git difftool -y config.rb

จำการตั้งค่าหมายเลขบรรทัดในการตั้งค่าเครื่องมือต่างของคุณ

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.