2010-03-14 22 views
33

Thông tin cơ bản: Tôi sử dụng một hệ thống xây dựng tự động lấy một git băm làm đầu vào, cũng như tên của nhánh mà băm đó tồn tại và xây dựng nó. Tuy nhiên, hệ thống xây dựng sử dụng băm một mình để kiểm tra mã và xây dựng nó - nó đơn giản lưu trữ tên chi nhánh, như đã cho, trong siêu dữ liệu DB xây dựng.Làm cách nào để xác định liệu một băm git đã có tồn tại trên một nhánh cụ thể?

Tôi lo lắng về việc nhà phát triển vô tình cung cấp tên chi nhánh sai khi họ khởi chạy một bản dựng, gây nhầm lẫn khi mọi người đang xem qua lịch sử xây dựng.

Vậy làm cách nào tôi có thể xác nhận, trước khi chuyển tên băm và chi nhánh sang hệ thống xây dựng, thì băm đã cho trong thực tế đến từ nhánh cụ thể chưa?

+3

tại sao bạn cần tên chi nhánh? nó có vẻ như một phần thông tin vô ích bổ sung cho hệ thống xây dựng. Và tôi không thực sự thấy nó sẽ được sử dụng như thế nào đối với một nhà phát triển đọc nhật ký xây dựng. – hasen

+0

Bạn sẽ cần tên chi nhánh trong trường hợp luồng công việc của bạn có, tôi không biết, một nhánh phát triển và chủ được sử dụng để triển khai và bạn muốn biết liệu các cam kết có thành một nhánh cụ thể không? Nhân tiện, hãy chấp nhận câu trả lời thực sự. –

+0

@Pinko Tôi nghĩ câu trả lời đã chọn nên là [this one] (https://stackoverflow.com/a/2444924/161278). Vì nó có nhiều phiếu bầu hơn và đơn giản hơn nhiều do việc sử dụng chức năng git bản địa. –

Trả lời

10

Hmm, sử dụng này của một tên chi nhánh dường như tanh. Như trong câu trả lời của Dustin, có thể có nhiều nhánh chứa cam kết. Tại sao bất kỳ một trong những tên chi nhánh này tốt hơn tên khác cho mục đích này?


Nếu bạn chỉ quan tâm đến một chi nhánh cụ thể, bạn có thể tính “cơ sở hợp nhất” giữa chi nhánh và cam kết.

Trong các biểu đồ sau, cam kết xây dựng là C, đầu chi nhánh được xác nhận là T và cơ sở hợp nhất được gắn nhãn M phía trên nó.

  • Nếu M bằng C bằng T, sau đó các cam kết để xây dựng là đỉnh của chi nhánh tuyên bố.

       M 
           ↓ 
    o--o--o--o--o--x branch # x is both C and T 
    
  • Nếu M bằng C, sau đó là đỉnh của chi nhánh tuyên bố là một hậu duệ của các cam kết để xây dựng.

     M 
         ↓ 
    o--o--C--o--o--T branch 
    
  • Nếu M bằng T, sau đó cam kết để xây dựng là một hậu duệ của các đỉnh của chi nhánh tuyên bố.

     M 
         ↓ 
    o--o--T   branch 
         \ 
         o--o--C 
    
  • Nếu M bằng cái gì khác, sau đó C là một hậu duệ của một số tổ tiên của T.

     M 
         ↓ 
    o--o--o--o--o--T branch 
         \ 
         o--o--C 
    
  • Nếu không có M, sau đó cam kết để xây dựng không liên quan đến các chi nhánh tuyên bố.

    o--o--o--o--o--T branch 
    
    o--o--o--o--C 
    

Bạn có thể thực hiện việc kiểm tra này như thế này:

#!/bin/sh 

# Usage: is-ancestor-of <branch> <commit> 

if test $# -ne 2; then 
    echo "$0"': invalid arguments' 
    exit 128 
fi 
claimed_branch="$1" 
commit="$2" 

merge_base="$(git merge-base "$commit" "$claimed_branch")" && 
    test -n "$merge_base" && 
    test "$merge_base" = "$(git rev-parse --verify "$commit")" && 
    exit 0 

echo "$commit is not an ancestor of $claimed_branch" 1>&2 
exit 1 

Các kịch bản trên không thực sự đòi hỏi hoặc kiểm tra xem đối số 'chi nhánh' là một chi nhánh (nó có thể là bất kỳ các uỷ ban ish). Để kiểm tra xem một cái gì đó thực sự là một chi nhánh, bạn có thể sử dụng một cái gì đó như thế này:

#!/bin/sh 

# Usage: is-branch <branch> 

if test $# -ne 1; then 
    echo "$0"': invalid arguments' 
    exit 128 
fi 
branch="$1" 

# check various branch hierarchies, adjust as needed 
git show-ref --verify refs/heads/"$branch" || 
git show-ref --verify refs/remotes/"$branch" || { 
    echo "not a branch name: $branch" 1>&2 
    exit 1 
} 

Vì vậy, bạn có thể sử dụng chúng lại với nhau để xác minh cái gì đó là một chi nhánh và một số cam kết là trong ngành rằng:

is-branch "$claimed_branch" && is-ancestor-of "$claimed_branch" "$commit_to_build" 
+0

Rất thú vị. +1 – VonC

+2

Giải pháp đơn giản @ http://stackoverflow.com/a/2444924/292408 –

+6

Tại sao bạn lại làm điều này khi git có giải pháp tốt hơn? Tại sao trên trái đất này là câu trả lời vô lý phức tạp được chấp nhận khi nó rõ ràng không phải là tốt nhất? Tôi lãng phí thời gian chọn lọc thông qua điều này thay vì di chuyển xuống câu trả lời mà nên ở đầu trang. Wow ... –

1

Một thể phi giải pháp sẽ được phân tích kết quả của:

$ git reflog show myBranch 

và xem nếu băm của bạn là ở trong đó.

C:\Prog\Git\tests\rep\main>git reflog show patches 
786a190 [email protected]{0}: rebase finished: refs/heads/patches onto 74630b983db476c323b1d3f6771e57484551240e 
8448d0f [email protected]{1}: master~1: updating HEAD 
74630b9 [email protected]{2}: commit: test2 
1e73e36 [email protected]{3}: branch: Created from master 

tôi giữ điều này như một câu trả lời cộng đồng Wiki nhớ Igor ZevakaChris Johnsen 's nhận xét:

Sẽ rằng công việc sau khi một bản sao?
Chắc chắn rằng quá trình cập nhật của bạn bắt đầu sau khi bạn sao chép từ xa. Vì vậy, nếu một chi nhánh đã có một cam kết trước khi bản sao, nó sẽ không hiển thị trong reflog.

Ngoài ra còn có vấn đề với push, rebases, fetches (đối với 'remote tracking' branch), và kéo (merge hoặc rebase type), nơi chỉ commit mới kết thúc uplog.
Ngoài ra, các lần reflog bị tắt theo mặc định trong kho trống (điểm đến phổ biến nhất cho các lần đẩy).
Ngoài ra, nếu "gian lận" là một vấn đề, nó chỉ là vấn đề chỉnh sửa một tập tin văn bản để thêm hoặc xóa các mục nhập lại, nhưng nó là một thử thách lớn hơn để thay đổi chính đồ thị lịch sử.

+0

Điều đó có hiệu quả sau khi sao chép không? Khá chắc chắn reflog của bạn bắt đầu sau khi bạn sao chép từ xa. Vì vậy, nếu một chi nhánh đã có một cam kết trước khi bản sao, nó sẽ không hiển thị trong reflog. –

+0

Phải, @Igor Zevaka. Ngoài ra còn có vấn đề với push và rebases (chỉ có mẹo mới cam kết kết thúc uplog). Ngoài ra reflogs được vô hiệu hóa theo mặc định trong kho trần (điểm đến phổ biến nhất cho push). Ngoài ra, nếu "gian lận" là một vấn đề, nó chỉ là một vấn đề chỉnh sửa một tập tin văn bản để thêm hoặc xóa các mục nhập reflog, nhưng nó là một thử thách lớn hơn để thay đổi đồ thị lịch sử chính nó. –

114

Bạn có thể hỏi trực tiếp git branch mà chi nhánh có các cam kết trong câu hỏi:

% git branch -a --contains 4f08c85ad 
* master 
    remotes/origin/bug_872 
    remotes/origin/bug_898 
    remotes/origin/master 
+5

Xóa tùy chọn '-a' để liệt kê từ chi nhánh địa phương của bạn chỉ – ismailsunni

+0

Chi nhánh cụ thể có thể được sử dụng thay cho' -a' ví dụ: '$ git branch phát triển - chứa 4f08c85ad' –

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