ตำหนิ Git - กระทำก่อนหน้า?


390

เป็นไปได้หรือไม่ที่จะดูว่าใครแก้ไขบรรทัดที่ระบุไว้ก่อนหน้าคอมมิชชันที่รายงานโดยgit blameเช่นประวัติการคอมมิชชันของบรรทัดที่กำหนด?

ตัวอย่างเช่นฉันเรียกใช้สิ่งต่อไปนี้ (ในuncrustifyโครงการที่ยอดเยี่ยม):

$ git blame -L10,+1 src/options.cpp
^fe25b6d (Ben Gardner 2009-10-17 13:13:55 -0500 10) #include "prototypes.h"

ฉันจะรู้ได้อย่างไรว่าใครแก้ไขบรรทัดก่อนที่จะส่งมอบfe25b6d? และที่แก้ไขมันก่อนที่กระทำ?


7
หากเหตุผลที่คุณกำลังมองหาการกระทำก่อนหน้านี้เป็นการเปลี่ยนแปลงช่องว่างใช้-wตัวเลือก นอกจากนี้ยัง-Mมีรหัสสำหรับย้าย / คัดลอก
brita_

หากต้องการค้นหาการกระทำทั้งหมดที่เกี่ยวข้องกับคำที่กำหนดให้ดูสคริปต์ของฉันด้านล่าง
VonC

นี่เป็นสคริปต์ที่มีประโยชน์ในการเพิ่มฟังก์ชั่นนี้ใน github greasyfork.org/en/scripts/ …
Aaron Hoffman

3
ไม่แน่ใจว่าสิ่ง GitHub ดูเหมือนเมื่อ @AaronHoffman โพสต์ แต่มันเป็นเรื่องง่ายที่จะ mucho ตำหนิ - และได้รับโทษสำหรับรุ่นก่อนหน้า - ใน GitHub ในขณะนี้
ruffin

คำตอบ:


389
git blame -L 10,+1 fe25b6d^ -- src/options.cpp

คุณสามารถระบุการแก้ไขสำหรับตำหนิ git เพื่อมองย้อนกลับไปเริ่มต้นได้ (แทนที่จะเป็นค่าเริ่มต้นHEAD) เป็นแม่ของfe25b6d^fe25b6d


106
คุณสามารถรับประวัติที่สมบูรณ์โดยไม่ต้องป้อนคำสั่งซ้ำหลายครั้งด้วยแฮชที่แตกต่างกันได้หรือไม่
Anders Zommarin

13
ฉันไม่เชื่อว่า Git มีวิธีการรับโทษทุกอย่างในตัวที่แตะต้องหมายเลขบรรทัด (ชนิดใดที่เหมาะสมเนื่องจากบรรทัดที่กำหนดอาจไม่มีหมายเลขบรรทัดที่สอดคล้องกันตลอดประวัติศาสตร์ของไฟล์เนื่องจากการแทรกและการลบ ของบรรทัด)
เหลืองอำพัน

17
@Amber: ค่อนข้างแน่ใจว่าคุณไม่มีคุณสมบัติ แต่ดูเหมือนว่ามันจะถูกนำไปใช้อย่างไร้เดียงสาโดยทำในสิ่งที่มนุษย์ทำ: โทษเพียงครั้งเดียวคว้าข้อมูลที่รายงานมาตำหนิว่า และอื่น ๆ
Cascabel

15
git gui ช่วยให้ง่ายต่อการตรวจสอบประวัติของบรรทัดเนื่องจากเวอร์ชั่นสามารถคลิกได้
Zitrax

5
@shadyabhi --มักใช้เป็นตัวคั่นในอาร์กิวเมนต์บรรทัดคำสั่ง - ในกรณีของ Git มักใช้เพื่อแยกสิ่งต่าง ๆ เช่นคอมมิชชันแฮชจากรายการชื่อไฟล์
แอมเบอร์

191

คุณสามารถใช้git log -Lเพื่อดูวิวัฒนาการของช่วงของเส้น

ตัวอย่างเช่น :

git log -L 15,23:filename.txt

หมายถึง "ติดตามวิวัฒนาการของบรรทัดที่ 15 ถึง 23 ในไฟล์ชื่อ filename.txt"


12
นี่เป็นคำตอบที่ชัดเจนและตอบคำถามของ Anders Zommarin ด้านบนเกี่ยวกับวิธีดูการเปลี่ยนแปลงของบรรทัดที่ระบุในช่วงเวลาหนึ่ง
bigtex777

4
FYI: เข้าสู่ระบบคอมไพล์ -L <start> <ปลาย>: <ไฟล์> ต้อง Git 1.8.4+ ดู: git-scm.com/docs/git-log#git-log--Lltstartgtltendgtltfilegtสำหรับตัวเลือกไวยากรณ์
นีออน

30

คำตอบของแอมเบอร์นั้นถูกต้อง แต่ฉันพบว่าไม่ชัดเจน ไวยากรณ์คือ:

git blame {commit_id} -- {path/to/file}

หมายเหตุ: --ถูกใช้เพื่อแยก tree-ish sha1 ออกจากพา ธ ไฟล์แบบสัมพันธ์ 1

ตัวอย่างเช่น:

git blame master -- index.html

ให้เครดิตกับแอมเบอร์อย่างเต็มที่สำหรับการรู้ทุกสิ่ง! :)


1
ฉันเห็นด้วยกับความรู้สึกของคุณ อย่างไรก็ตามระบบการแสดงความคิดเห็นนั้นถูก จำกัด เกินไปที่จะนำเสนอข้อมูลทั้งหมดอย่างชัดเจน ฉันได้เพิ่มเนื้อหาของคำตอบนี้ในความคิดเห็น; แม้ว่าฉันยืนยันที่จะออกคำตอบนี้เป็นสถานที่เพื่อความสะดวกในการเข้าถึง
ThorSummoner

1
ควรเป็นโพสต์แยกต่างหากหรือแก้ไข ฉันชอบสิ่งนี้มันเป็นคำตอบที่แยกต่างหาก
Flimm

27

คุณอาจต้องการตรวจสอบ:

git gui blame <filename>

แสดงภาพการเปลี่ยนแปลงที่ดีเช่น "git blame" แต่มีลิงก์แบบคลิกได้ต่อบรรทัดเพื่อย้ายไปยังคอมมิชชันก่อนหน้า เลื่อนเมาส์ไปที่ลิงก์เพื่อรับป๊อปอัปพร้อมรายละเอียดการส่งมอบ ไม่ใช่เครดิตของฉัน ... พบที่นี่:

http://zsoltfabok.com/blog/2012/02/git-blame-line-history/

git guiเป็นส่วนต่อประสานกราฟิก Tcl / Tc เพื่อคอมไพล์ หากไม่มีพารามิเตอร์อื่น ๆ มันจะเริ่มต้นแอปกราฟิกที่เรียบง่าย แต่มีประโยชน์สำหรับการส่งไฟล์, การล่าสัตว์หรือแม้แต่บรรทัดเดียวและคำสั่งที่คล้ายกันอื่น ๆ เช่นการแก้ไข, ย้อนกลับ, ดัน ... เป็นส่วนหนึ่งของชุดหุ้น git ใน windows จะรวมอยู่ในโปรแกรมติดตั้ง บนเดเบียน - ฉันไม่รู้เกี่ยวกับระบบ * nix อื่น ๆ - ต้องติดตั้งแยกต่างหาก:

apt-get install git-gui

จากเอกสาร:

https://git-scm.com/docs/git-gui

รายละเอียด

ส่วนต่อประสานกราฟิกกับผู้ใช้แบบ Tcl / Tk กับ Git git gui มุ่งเน้นไปที่การอนุญาตให้ผู้ใช้ทำการเปลี่ยนแปลงที่เก็บข้อมูลของพวกเขาโดยการทำคอมมิชชันใหม่แก้ไขที่มีอยู่สร้างสาขาดำเนินการผสานท้องถิ่นและดึง / ผลักดันไปยังที่เก็บระยะไกล

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

git gui เป็นที่รู้จักกันดีว่าทำงานได้กับระบบ UNIX ยอดนิยมทั้งหมด, Mac OS X และ Windows (ภายใต้ทั้ง Cygwin และ MSYS) เท่าที่เป็นไปได้มีการปฏิบัติตามแนวทางอินเทอร์เฟซผู้ใช้เฉพาะ OS ทำให้ git gui เป็นอินเตอร์เฟสดั้งเดิมสำหรับผู้ใช้

คำสั่ง

ตำหนิ

เริ่มวิวเวอร์ตำหนิบนไฟล์ที่ระบุบนเวอร์ชันที่กำหนด (หรือไดเร็กทอรีการทำงานหากไม่ได้ระบุ)

เบราว์เซอร์

เริ่มต้นเบราว์เซอร์ต้นไม้แสดงไฟล์ทั้งหมดในการกระทำที่ระบุ ไฟล์ที่เลือกผ่านเบราว์เซอร์จะเปิดขึ้นในตัวแสดงการตำหนิ

citool

เริ่ม git gui และจัดการเพื่อให้คอมมิชชันหนึ่งคอมมิชชันก่อนที่จะออกและกลับไปที่เชลล์ อินเทอร์เฟซถูก จำกัด ให้กระทำการเท่านั้นลดเวลาเริ่มต้นของแอปพลิเคชั่นเล็กน้อยและทำให้แถบเมนูเรียบง่ายขึ้น

รุ่น

แสดง git gui เวอร์ชันที่กำลังทำงานอยู่


มันไม่ทำงานสำหรับฉัน ฉันสามารถคลิกที่การเปลี่ยนแปลงในบรรทัดที่กำหนด แต่นั่นแค่เปลี่ยนมุมมองสำหรับการคอมมิชชันนั้นและตอนนี้บรรทัดปัจจุบันแสดงเป็นthis: แต่ฉันจะดูเวอร์ชันก่อนหน้าของบรรทัดและเมื่อมีการเพิ่มได้อย่างไร
BeeOnRope

นี่เป็นกรณีการใช้งานหนึ่งที่ฉันรู้ว่าที่ git gui เป็นทางออกที่ดีที่สุด
cambunctious

17

เมื่อสร้างจากคำตอบก่อนหน้านี้หนึ่งทุบตีควรให้สิ่งที่คุณกำลังมองหา จะแสดงประวัติตำหนิตำหนิสำหรับบรรทัดเฉพาะของไฟล์โดยเฉพาะผ่านการแก้ไข 5 ครั้งล่าสุด:

LINE=10 FILE=src/options.cpp REVS=5; for commit in $(git rev-list -n $REVS HEAD $FILE); do git blame -n -L$LINE,+1 $commit -- $FILE; done

ในเอาต์พุตของคำสั่งนี้คุณอาจเห็นเนื้อหาของการเปลี่ยนแปลงบรรทัดหรือหมายเลขบรรทัดที่แสดงอาจเปลี่ยนแปลงแม้กระทั่งสำหรับการคอมมิตโดยเฉพาะ

สิ่งนี้มักจะบ่งบอกว่ามีการเพิ่มบรรทัดนั้นเป็นครั้งแรกหลังจากการส่งคำสั่งนั้น ๆ นอกจากนี้ยังสามารถระบุได้ว่าบรรทัดนั้นถูกย้ายจากส่วนอื่นของไฟล์


5
โปรดทราบว่านี่เป็นการแก้ไข $ REVS ครั้งล่าสุดที่มีการเปลี่ยนแปลง $ FILE แทนที่จะเป็น $ REVS ครั้งล่าสุดที่มีการเปลี่ยนแปลง $ LINE
Max Nanasy

คุณหมายถึงคำตอบใด
Flimm

ฉันจำไม่ได้อีกแล้ว อาจเป็นไปได้ว่าฉันสามารถพิสูจน์คำตอบได้ดีขึ้นในอนาคต
Sheppard Will


11

ทางออกที่พิเศษมากสำหรับปัญหานี้คือการใช้บันทึก git:

git log -p -M --follow --stat - path / to / your / file

ตามที่อธิบายโดย Andre ที่นี่


1
ฉันสร้างนามแฝงเพื่อใช้สิ่งนี้git config --global alias.changes 'log -p -M --follow --stat --'แล้วฉันก็สามารถพิมพ์ได้git changes path/to/your/file
Tizio Fittizio

นี่คือคำตอบที่ดีที่สุดและสิ่งที่ฉันกำลังมองหา เรียบง่ายและสง่างาม
maesk

10

หากคุณใช้ JetBrains Idea IDE (และสัญญาซื้อขายล่วงหน้า) คุณสามารถเลือกหลายบรรทัดคลิกขวาสำหรับเมนูบริบทจากนั้นเลือก Git -> แสดงประวัติสำหรับการเลือก คุณจะเห็นรายการการกระทำที่มีผลต่อบรรทัดที่เลือก:

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


สิ่งนี้ใช้ได้ดีกว่าคำตอบอื่น ๆ สำหรับฉัน (ใช้ IntelliJ) ใช้เวลาสักครู่ในการโหลดการแก้ไขทั้งหมด แต่คุ้มค่ากับการรอ
Steve Chambers

1

เมื่อสร้างคำตอบของ Will Shepard ผลลัพธ์ของเขาจะรวมบรรทัดที่ซ้ำกันสำหรับคอมมิทที่ไม่มีการเปลี่ยนแปลงดังนั้นคุณสามารถกรองเหล่านั้นได้ดังต่อไปนี้ (ใช้คำตอบนี้)

LINE=1 FILE=a; for commit in $(git rev-list HEAD $FILE); do git blame -n -L$LINE,+1 $commit -- $FILE; done | sed '$!N; /^\(.*\)\n\1$/!P; D'

โปรดทราบว่าฉันลบอาร์กิวเมนต์ REVS และสิ่งนี้จะกลับไปที่รูทการส่ง นี่เป็นเพราะการสังเกตของ Max Nanasy ด้านบน


1

การสร้างตามคำตอบของ DavidN และฉันต้องการติดตามไฟล์ที่ถูกเปลี่ยนชื่อ:

LINE=8 FILE=Info.plist; for commit in $(git log --format='%h%%' --name-only --follow -- $FILE | xargs echo | perl -pe 's/\%\s/,/g'); do hash=$(echo $commit | cut -f1 -d ','); fileMayRenamed=$(echo $commit | cut -f2 -d ','); git blame -n -L$LINE,+1 $hash -- $fileMayRenamed; done | sed '$!N; /^\(.*\)\n\1$/!P; D'

ref: แสดงประวัติการเปลี่ยนชื่อไฟล์เป็นอย่างดีในบันทึก git


1

ตั้งแต่ Git 2.23 คุณสามารถใช้git blame --ignore-rev

สำหรับตัวอย่างที่ให้ไว้ในคำถามนี้จะเป็น:

git blame -L10,+1 src/options.cpp --ignore-rev fe25b6d

(อย่างไรก็ตามมันเป็นคำถามที่หลอกลวงเพราะ fe25b6d เป็นการแก้ไขครั้งแรกของไฟล์!)


0

ฉันใช้สคริปต์ทุบตีเล็ก ๆ น้อย ๆ นี้เพื่อดูประวัติความผิด

พารามิเตอร์แรก: ไฟล์ที่จะดู

พารามิเตอร์ที่ตามมา: ผ่านไปยังตำหนิคอมไพล์

#!/bin/bash
f=$1
shift
{ git log --pretty=format:%H -- "$f"; echo; } | {
  while read hash; do
    echo "--- $hash"
    git blame $@ $hash -- "$f" | sed 's/^/  /'
  done
}

คุณอาจระบุพารามิเตอร์การตำหนิเช่น-L 70, + 10แต่จะดีกว่าถ้าใช้ regex-search ของ git blame เพราะหมายเลขบรรทัดมักจะ "เปลี่ยน" เมื่อเวลาผ่านไป


0

สร้างจากคำตอบของstanglsฉันวางสคริปต์นี้ไว้ใน PATH ของฉัน (แม้แต่บน Windows) เป็น git-bh:

ที่ช่วยให้ฉันมองหาการกระทำทั้งหมดที่เกี่ยวข้องกับคำ:

git bh path/to/myfile myWord

สคริปต์:

#!/bin/bash
f=$1
shift
csha=""
{ git log --pretty=format:%H -- "$f"; echo; } | {
  while read hash; do
    res=$(git blame -L"/$1/",+1 $hash -- "$f" 2>/dev/null | sed 's/^/  /')
    sha=${res%% (*}
    if [[ "${res}" != "" && "${csha}" != "${sha}" ]]; then
      echo "--- ${hash}"
      echo "${res}"
      csha="${sha}"
    fi
  done
}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.