2012-05-24 40 views
13

Giả sử tôi có hai phiên bản trong kho của tôi ... từng đã được gắn thẻ như sau:Bao gồm submodule bài viết cam kết với "git log"

  • Tag1
  • TAG2

Bây giờ giả sử rằng một cam kết cập nhật một tham chiếu submodule để trỏ đến một submodule mới cam kết giữa Tag1 và Tag2. Tôi chạy lệnh sau và nhận được lệnh sau:

# show commits between these two tags 
git log Tag1..Tag2 


commit be3d0357b93322f472e8f03285cb3e1e0592eabd 
Author: James Johnston <snip> 
Date: Wed Jan 25 19:42:56 2012 +0000 

    Updated submodule references. 

Trong trường hợp này, thay đổi duy nhất là bản cập nhật của mô-đun con. Làm thế nào để tôi nhận được mô-đun con cam kết được xen kẽ với các cam kết kho lưu trữ gốc?

Cụ thể, trong ví dụ này, giả sử rằng kho lưu trữ mẹ trỏ đến thẻ SubTag5 trong mô-đun con. Hai commit sau này trong submodule là một thẻ SubTag6. Cam kết hiển thị cập nhật con trỏ mô-đun con trỏ đến SubTag6 thay vì SubTag5. Những gì tôi muốn làm là có git log, ngoài cam kết nó đã được in, in cả hai submodule cam kết cũng mang lại submodule từ SubTag5 để SubTag6.

Trả lời

6

Bạn có thể hiển thị các thay đổi mô-đun con, nhưng chỉ khi sử dụng git log -p. Lệnh sau đây cho thấy sự khác biệt đầy đủ của mỗi thay đổi commit và submodule.

git log -p --submodule=log 

submodule bài viết cam kết sẽ được liệt kê như sau:

Submodule <submodule-name> <starting-commit>..<ending-commit>: 
> Commit message 1 
> Commit message 2 
... 
> Commit message n 
+1

Sắp xếp các chức năng, nhưng là có một cách để có được một sản lượng sạch hơn nhiều cho các môđun con tương tự như kho lưu trữ chính, mà không lội qua toàn bộ diff ? Ví dụ, git log in tác giả và ngày tháng và thông điệp cam kết đầy đủ trên kho lưu trữ chính. Sẽ được tốt đẹp để có các mục như thế cho submodules được liệt kê bên dưới cam kết trong kho chính, không có bản vá khác biệt. –

+0

Theo như tôi biết có bây giờ cách. Tuy nhiên, bạn vẫn có thể chạy một số cụm từ thông dụng trên đầu ra, bộ lọc sẽ loại bỏ tất cả nội dung bạn không muốn xem. – iblue

0

Nếu bạn đang làm việc trên Windows, bạn có thể sử dụng kịch bản PowerShell này:

function Parse-SubmoduleDiff($rawDiffLines) { 
    $prefix = "Subproject commit " 
    $oldCommitLine = $($rawDiffLines | where { $_.StartsWith("-" + $prefix) } | select -First 1) 
    $newCommitLine = $($rawDiffLines | where { $_.StartsWith("+" + $prefix) } | select -First 1) 

    if ($newCommitLine -eq $null) { 
     return $null 
    } 

    $oldCommit = $null 
    if ($oldCommitLine -ne $null) { 
     $oldCommit = $oldCommitLine.Substring($prefix.Length + 1) 
    } 
    $newCommit = $newCommitLine.Substring($prefix.Length + 1) 
    return @{ OldCommit = $oldCommit; NewCommit = $newCommit } 
} 

# Get the paths of all submodules 
$submodulePaths = $(git submodule foreach --quiet 'echo $path') 
if ($submodulePaths -eq $null) { 
    $submodulePaths = @() 
} 

# Get the log of the parent repository (only SHA1) 
$log = $(git log --format="%H %P" $args) 
foreach ($line in $log) { 

    $parts = $line.Split() 
    $commit = $parts[0] 
    $parents = $parts[1..$parts.Length] 

    # Print the summary for this commit 
    git show --format=medium --no-patch $commit 
    echo "" 

    # Can be more than one parent if it's a merge 
    foreach ($parent in $parents) { 
     # List the paths that changed in this commit 
     $changes = $(git diff --name-only $parent $commit) 

     if ([System.String]::IsNullOrWhiteSpace($parent)) { 
      continue; 
     } 

     foreach ($path in $changes) { 

      if ($submodulePaths.Contains($path)) { 
       # if it's a submodule, the diff should look like this: 
       # -Subproject commit 1486adc5c0c37ad3fa2f2e373e125f4000e4235f 
       # +Subproject commit a208e767afd0a51c961654d3693893bbb4605902 
       # from that we can extract the old and new submodule reference 

       $subDiff = $(git diff $parent $commit -- $path) 
       $parsed = Parse-SubmoduleDiff($subDiff) 
       if ($parsed -eq $null) { 
        continue; 
       } 

       # Now get the log between the old and new submodule commit 
       $oldCommit = $parsed.OldCommit 
       $newCommit = $parsed.NewCommit 
       echo "Submodule '$path'" 
       if ($oldCommit -ne $null) { 
        $range = $($oldCommit + ".." + $newCommit) 
       } else { 
        $range = $newCommit 
       } 

       git --git-dir $path/.git log $range | foreach { " | " + $_ } 
       echo "" 
      } 
     } 
    } 
} 

Rõ ràng nó có thể được dịch để bash để sử dụng trên Linux. Nguyên tắc chung là thế này:

for each commit in the parent repo 
    print the commit summary 
    for each submodule that has changed in this commit 
     get the old and new commit hashes of the submodule 
     print the log of the submodule between those commits 
    end for 
end for 
9

Dưới đây là một lệnh bash đơn giản mà tạo ra một ASCII cam kết đồ thị (tương tự như gitk) mà interleaves các submodule có liên quan cam kết khi một submodule bị thay đổi trong superproject. Nó in ra các bản vá đầy đủ cho mỗi cam kết và sau đó sử dụng grep để lọc ra các nội dung bản vá chỉ để lại các dòng tóm tắt và thay đổi submodule.

git log --graph --oneline -U0 --submodule Tag1..Tag2 | grep -E '^[*| /\\]+([0-9a-f]{7} |Submodule |> |$)' 

Nó tạo ra sản lượng tương tự như sau:

* 854407e Update submodule 
| Submodule SUB 8ebf7c8..521fc49: 
| > Commit C 
* 99df57c Commit B 
* 79e4075 Commit A 
+0

nó sẽ là tuyệt vời để có điều này vào gitk! –

Các vấn đề liên quan