Git đổ lỗi - cam kết trước?


391

Có thể xem ai đã chỉnh sửa một dòng cụ thể trước khi cam kết được báo cáo bởi git blame, như lịch sử cam kết cho một dòng nhất định không?

Ví dụ: tôi chạy như sau (về uncrustifydự án tuyệt vời ):

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

Làm thế nào tôi có thể tìm ra ai đã chỉnh sửa dòng đó trước khi cam kết fe25b6d? Và ai sửa nó trước đó cam kết?


7
nếu lý do bạn đang tìm kiếm các cam kết trước đó là thay đổi khoảng trắng, hãy sử dụng -wtùy chọn. Ngoài ra còn có -Mmã di chuyển / sao chép
brita_

Để tìm tất cả các cam kết liên quan đến một từ nhất định, hãy xem kịch bản của tôi bên dưới
VonC

Đây là một đoạn script hữu ích để thêm chức năng này trên github greasyfork.org/en/scripts/ mẹo
Aaron Hoffman

3
Không chắc chắn github trông như thế nào khi @AaronHoffman đăng, nhưng thật dễ để đổ lỗi - và nhận lỗi cho các phiên bản trước - ngay bây giờ trong github .
ruffin

Câu trả lời:


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

Bạn có thể chỉ định một bản sửa đổi cho git đổ lỗi để nhìn lại bắt đầu từ (thay vì mặc định của HEAD); fe25b6d^là cha mẹ của fe25b6d.


107
Bạn có thể có được một lịch sử đầy đủ, mà không phải nhập lại lệnh nhiều lần với các giá trị băm khác nhau không?
Anders Zommarin

13
Tôi không tin rằng Git có cách tích hợp để nhận mọi lỗi đổ lỗi khi chạm vào số dòng (điều này có ý nghĩa, vì một dòng nhất định có thể không có số dòng nhất quán trong suốt lịch sử của tệp do chèn và xóa của dòng).
Amber

17
@Amber: Khá chắc chắn rằng bạn đúng rằng tính năng này không tồn tại, nhưng có vẻ như nó có thể được triển khai một cách ngây thơ, chỉ bằng cách làm những gì con người sẽ làm: đổ lỗi một lần, lấy thông tin được báo cáo, đổ lỗi rằng , và như thế.
Cascabel

15
git gui làm cho nó khá dễ dàng để kiểm tra lịch sử của một dòng vì các phiên bản có thể nhấp được.
Zitrax

5
@shadyabhi --thường được sử dụng như một dấu phân cách trong các đối số dòng lệnh - trong trường hợp của Git, nó thường được sử dụng để phân tách những thứ như băm xác nhận từ danh sách tên tệp.
Amber

191

Bạn có thể sử dụng git log -L để xem sự phát triển của một loạt các dòng.

Ví dụ :

git log -L 15,23:filename.txt

có nghĩa là "theo dõi sự phát triển của dòng 15 đến 23 trong tệp có tên filename.txt".


12
Đây là một câu trả lời chắc chắn và giải quyết câu hỏi của Anders Zommarin ở trên về cách xem các thay đổi đối với các dòng cụ thể theo thời gian.
bigtex777

4
FYI: git log -L <start>, <end>: <file> yêu cầu Git 1.8.4+ xem: git-scm.com/docs/git-log#git-log--Lltstartgtltendgtltfilegt cho các tùy chọn cú pháp
neon

30

Câu trả lời của Amber là đúng nhưng tôi thấy nó không rõ ràng; Cú pháp là:

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

Lưu ý: --được sử dụng để tách cây-ish sha1 khỏi đường dẫn tệp tương đối. 1

Ví dụ:

git blame master -- index.html

Tín dụng đầy đủ cho Amber để biết tất cả mọi thứ! :)


1
Tôi đồng ý với tình cảm của bạn. Tuy nhiên, hệ thống bình luận quá hạn chế để trình bày tất cả các thông tin rõ ràng. Tôi đã thêm nội dung của câu trả lời này trong một bình luận; Mặc dù vậy, tôi nhấn mạnh để lại câu trả lời này là nơi dễ truy cập.
ThorSummoner

1
Nó nên là một bài viết riêng biệt hoặc chỉnh sửa. Tôi thích nó như là một câu trả lời riêng biệt.
Flimm

27

Bạn có thể muốn kiểm tra:

git gui blame <filename>

Cung cấp cho bạn một màn hình đồ họa đẹp mắt về các thay đổi như "git đổ lỗi" nhưng với các liên kết có thể nhấp trên mỗi dòng, để chuyển sang các cam kết trước đó. Di chuột qua các liên kết để có được một cửa sổ bật lên với các chi tiết cam kết. Không phải khoản tín dụng của tôi ... đã tìm thấy nó ở đây:

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

git guilà một giao diện Tcl / Tc đồ họa cho git. Không có bất kỳ thông số nào khác, nó khởi động một ứng dụng đồ họa khá đơn giản nhưng hữu ích để thực hiện các tệp, hunk hoặc thậm chí các dòng đơn và các lệnh tương tự khác như sửa đổi, hoàn nguyên, đẩy ... Đây là một phần của bộ git stock. Trên cửa sổ, nó được bao gồm trong trình cài đặt. Trên debian - Tôi không biết về các hệ thống * nix khác - nó phải được cài đặt riêng:

apt-get install git-gui

Từ các tài liệu:

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

SỰ MIÊU TẢ

Giao diện người dùng đồ họa dựa trên Tcl / Tk cho Git. git gui tập trung vào việc cho phép người dùng thực hiện các thay đổi đối với kho lưu trữ của họ bằng cách thực hiện các cam kết mới, sửa đổi các hiện có, tạo các nhánh, thực hiện hợp nhất cục bộ và tìm nạp / đẩy vào các kho lưu trữ từ xa.

Không giống như gitk, git gui tập trung vào việc tạo cam kết và chú thích tập tin duy nhất và không hiển thị lịch sử dự án. Tuy nhiên, nó cung cấp các hành động trình đơn để bắt đầu một phiên gitk từ bên trong git gui.

git gui được biết là hoạt động trên tất cả các hệ thống UNIX phổ biến, Mac OS X và Windows (dưới cả Cygwin và MSYS). Trong phạm vi có thể hướng dẫn giao diện người dùng cụ thể của hệ điều hành, làm cho git gui trở thành một giao diện khá tự nhiên cho người dùng.

THÔNG TIN

khiển trách

Bắt đầu một trình xem đổ lỗi cho tệp được chỉ định trên phiên bản đã cho (hoặc thư mục làm việc nếu không được chỉ định).

trình duyệt

Bắt đầu một trình duyệt cây hiển thị tất cả các tệp trong cam kết đã chỉ định. Các tệp được chọn thông qua trình duyệt được mở trong trình xem đổ lỗi.

citool

Bắt đầu git gui và sắp xếp để thực hiện chính xác một cam kết trước khi thoát và trở về vỏ. Giao diện được giới hạn chỉ thực hiện các hành động, giảm nhẹ thời gian khởi động của ứng dụng và đơn giản hóa thanh thực đơn.

phiên bản

Hiển thị phiên bản hiện đang chạy của git gui.


Nó không làm việc cho tôi. Tôi có thể nhấp vào thay đổi trên dòng đã cho, nhưng điều đó chỉ thay đổi chế độ xem dành cho cam kết đó và dòng hiện tại hiển thị là this: nhưng làm cách nào để xem phiên bản trước của dòng và khi được thêm?
BeeOnRope

Đây là trường hợp một sử dụng tôi biết nơi gui git là giải pháp tốt nhất
cambunctious

17

Dựa trên câu trả lời trước, bash one-liner này sẽ cung cấp cho bạn những gì bạn đang tìm kiếm. Nó hiển thị lịch sử đổ lỗi git cho một dòng cụ thể của một tệp cụ thể, qua 5 phiên bản mới nhất:

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

Trong đầu ra của lệnh này, bạn có thể thấy nội dung của dòng thay đổi hoặc số dòng được hiển thị thậm chí có thể thay đổi, đối với một cam kết cụ thể.

Điều này thường chỉ ra rằng dòng đã được thêm lần đầu tiên, sau lần cam kết cụ thể đó. Nó cũng có thể chỉ ra dòng đã được di chuyển từ một phần khác của tệp.


5
Lưu ý rằng đây là lần sửa đổi $ REVS cuối cùng trong đó $ FILE thay đổi, thay vì lần sửa đổi $ REVS cuối cùng trong đó $ LINE đã thay đổi.
Max Nanasy

Câu trả lời nào bạn đang đề cập đến?
Flimm

Tôi không nhớ nữa. Có lẽ tôi có thể chứng minh được câu trả lời của mình trong tương lai tốt hơn.
Will Sheppard


11

Một giải pháp rất độc đáo cho vấn đề này là sử dụng git log:

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

Theo giải thích của Andre tại đây


1
Tôi đã tạo một bí danh để sử dụng điều này: git config --global alias.changes 'log -p -M --follow --stat --'và sau đó tôi có thể chỉ cần gõgit changes path/to/your/file
Tizio Fittizio

Đây là câu trả lời tốt nhất và chính xác những gì tôi đang tìm kiếm. Đơn giản và thanh lịch.
maesk

10

Nếu bạn đang sử dụng JetBrains Idea IDE (và các dẫn xuất), bạn có thể chọn một vài dòng, nhấp chuột phải vào menu ngữ cảnh, sau đó Git -> Hiển thị lịch sử để lựa chọn. Bạn sẽ thấy danh sách các cam kết ảnh hưởng đến các dòng đã chọn:

nhập mô tả hình ảnh ở đây


Điều này làm việc tốt hơn so với các câu trả lời khác cho tôi (sử dụng IntelliJ). Mất một lúc để tải tất cả các sửa đổi nhưng đáng để chờ đợi.
Steve Chambers

2

Kể từ Git 2.23, bạn có thể sử dụng git blame --ignore-rev

Đối với ví dụ được đưa ra trong câu hỏi này sẽ là:

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

(tuy nhiên đó là một câu hỏi mẹo vì fe25b6d là bản sửa đổi đầu tiên của tệp!)


1

Dựa trên câu trả lời của Will Shepard, đầu ra của anh ta sẽ bao gồm các dòng trùng lặp cho các cam kết khi không có thay đổi, vì vậy bạn có thể lọc các câu như sau (sử dụng câu trả lời này )

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'

Lưu ý rằng tôi đã xóa đối số REVS và điều này quay trở lại cam kết gốc. Điều này là do quan sát của Max Nanasy ở trên.


1

Dựa trên câu trả lời của DavidN và tôi muốn theo dõi tập tin được đổi tên:

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: hiển thị lịch sử đổi tên tập tin độc đáo trong nhật ký git


0

Tôi sử dụng kịch bản bash nhỏ này để xem xét một lịch sử đổ lỗi.

Tham số đầu tiên: tập tin để xem xét

Các tham số tiếp theo: Đã chuyển sang git đổ lỗi

#!/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
}

Bạn có thể cung cấp các tham số đổ lỗi như -L 70, + 10 nhưng tốt hơn là sử dụng regex-search của git đổ lỗi vì các số dòng thường "thay đổi" theo thời gian.


0

Xây dựng trên câu trả lời của stangls , tôi đặt đoạn script này trong PATH của mình (ngay cả trên Windows) là git-bh:

Điều đó cho phép tôi tìm kiếm tất cả các cam kết có liên quan đến một từ:

git bh path/to/myfile myWord

Kịch bản:

#!/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
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.