2009-08-22 14 views

Trả lời

26

Để có được cam kết (tất cả và đầu ra một dòng cho mỗi cam kết):

git rev-list --all --pretty=oneline 

Sau đó chia cam kết bởi không gian với giới hạn 2 và nhận được tất cả các cam kết id và thông điệp

để có được tạo ra bởi các đốm màu cam (recurse để subdirs, chương trình hợp nhất cam kết, phát hiện và đặt lại tên bản, không thể hiện cam kết id trên dòng đầu tiên):

git diff-tree -r -c -M -C --no-commit-id <commit-sha> 

Một chút phân tích cú pháp của mỗi dòng và loại trừ một số trong số họ - và chúng tôi nhận danh sách các đốm màu mới và họ con đường cho cam

cuối là để có được kích thước blob:

git cat-file --batch-check < <list-of-blob-shas> 

Và thời điểm khác một chút của phân tích

+1

Bạn có thể làm điều này nhanh hơn nhiều bằng cách sử dụng tùy chọn '--stdin' thành' diff-tree'. Ví dụ, 'git rev-list --all | git diff-tree -r --root --diff-filter = AMC --pretty = oneline --stdin'. – Jed

+0

Câu trả lời của maxschlepzig dưới đây rất quan trọng: nếu bạn đang cố gắng làm điều gì đó như [xóa một tệp lớn khỏi lịch sử repo] (http://git-scm.com/book/en/Git-Internals-Maintenance-and-Data -Recovery # Loại bỏ các đối tượng), bạn cần phải chắc chắn để tìm tất cả các cam kết, ngay cả khi một số là trên các ngành unmerged! – peterflynn

5

Bạn có thể lấy mọi thứ trừ kích thước ra khỏi hộp. Vấn đề này khá chặt chẽ:

git log --name-status 
3

Một giải pháp dựa trên câu trả lời của TIG:

#!/usr/bin/perl 

foreach my $rev (`git rev-list --all --pretty=oneline`) { 
    my $tot = 0; 
    ($sha = $rev) =~ s/\s.*$//; 
    foreach my $blob (`git diff-tree -r -c -M -C --no-commit-id $sha`) { 
    $blob = (split /\s/, $blob)[3]; 
    next if $blob == "0000000000000000000000000000000000000000"; # Deleted 
    my $size = `echo $blob | git cat-file --batch-check`; 
    $size = (split /\s/, $size)[2]; 
    $tot += int($size); 
    } 
    print "$tot $rev" if $tot > 1000000; # Show only if > 1MiB 
} 

có lẽ không phải là mã tốt nhất, nhưng sẽ giúp bạn có hầu hết đường đi.

11

Dựa vào git rev-list không phải lúc nào đủ vì nó

Danh sách [s] cam kết rằng có thể truy cập bằng cách làm theo các liên kết cha mẹ từ cho cam (s) [..]

(git help rev-list)

Vì vậy, nó không liệt kê các cam kết trên một chi nhánh khác và nó không liệt kê các cam kết không thể truy cập được bởi bất kỳ chi nhánh nào (có thể chúng được tạo bởi vì o f một số rebase và/hoặc hành động tách rời).

Tương tự, git log chỉ theo các liên kết gốc từ cam kết đã kiểm tra hiện tại. Một lần nữa, bạn không thấy các cam kết được tham chiếu bởi các nhánh khác hoặc đang ở trạng thái lơ lửng.

Bạn thực sự có thể nhận được tất cả các cam kết với một lệnh như thế này:

for i in `(find .git/objects -type f | 
      sed '[email protected]^.*objects/\(..\)/\(.\+\)[email protected]\1\[email protected]' ; 
      git verify-pack -v .git/objects/pack/*.idx | 
      grep commit | 
      cut -f1 -d' ';) | sort -u` 
    do 
    git log -1 --pretty=format:'%H %P %ai %s%n' $i 
done 

Để giữ cho nó đơn giản, in thân vòng lặp cho mỗi cam kết một dòng chứa hash của nó, là băm mẹ (es), ngày và môn học. Lưu ý, để lặp lại trên tất cả các cam kết bạn cần xem xét các đối tượng được đóng gói và chưa được đóng gói.

Bạn có thể in các đốm màu được tham chiếu (và chỉ tạo các đốm màu) bằng cách gọi git diff-tree $i (và greping cho số vốn A trong cột thứ năm) từ thân vòng lặp.

+0

Điều gì về việc sử dụng 'git log --all'? Các tài liệu dường như ngụ ý rằng sẽ bao gồm mọi cam kết (có thể truy cập) ... – peterflynn

+0

@ytpete, tôi đề cập rõ ràng các cam kết không thể truy cập trong câu trả lời của tôi. – maxschlepzig

0

Bạn cũng có thể có được một danh sách các tất cả cam kết (bao gồm cả những người lơ lửng) với:

git log --walk-reflogs | grep -E -o '[0-9a-f]{40}'

Bao gồm dòng này trong các thiết lập cho một cái nhìn mới trong gitk (trong lĩnh vực đầu vào cuối cùng , lệnh để tạo thêm các cam kết) và bạn sẽ nhận được một cây cũng hiển thị 'lịch sử bị lãng quên' của dự án.

+1

Không hoạt động với tôi: 'git log --walk-reflogs' cung cấp danh sách _shorter_ hơn là chỉ thực hiện' git log'. Đánh giá bởi [trang người đàn ông] (http://gitmanual.org/git-reflog.html), việc reflog không được bảo đảm là một danh sách đầy đủ của tất cả các cam kết hoặc tất cả các chi nhánh ... – peterflynn

2

Một lệnh hữu dụng khi tìm kiếm

git fsck --lost-found 

sẽ hiển thị tòn ten cam kết. Tôi cần thiết để sử dụng này để tìm một cam kết ai lau với một thiết lập lại không đúng lúc --hard

Nhưng đừng dùng từ ngữ của tôi cho nó:

https://www.kernel.org/pub/software/scm/git/docs/git-fsck.html

+0

Umm bạn có thể bình luận downvote - Tôi sẽ xóa câu trả lời nếu nó sai hoặc gây nhầm lẫn! – starsinmypockets