Trước khi bạn có thể trả lời câu hỏi về chi nhánh nào chứa cam kết tương đương, bạn phải xác định "cam kết tương đương". Một khi bạn có điều đó, bạn chỉ cần sử dụng git branch --contains
trên mỗi cam kết.
Thật không may, không có cách nào đáng tin cậy 100% để xác định các cam kết tương đương.
Phương pháp đáng tin cậy nhất là kiểm tra id bản vá của changeset được giới thiệu bởi cam kết. Đây là những gì git cherry
, git log --cherry
và git log --cherry-mark
dựa vào. Trong nội bộ, tất cả họ gọi git patch-id
. Id bản vá chỉ là SHA1 của các thay đổi được chuẩn hóa. Bất kỳ cam kết nào giới thiệu các thay đổi giống hệt nhau sẽ có cùng một id bản vá. Ngoài ra, bất kỳ cam kết nào giới thiệu chủ yếu là các thay đổi giống nhau chỉ khác nhau về khoảng trắng hoặc số dòng mà chúng áp dụng trong tệp sẽ có cùng một id bản vá. Nếu hai cam kết có cùng một ID bản vá, nó gần như được đảm bảo rằng chúng tương đương - bạn sẽ hầu như không bao giờ nhận được kết quả dương tính giả thông qua id bản vá. Sai âm tính xảy ra thường xuyên mặc dù. Bất cứ lúc nào bạn làm git cherry-pick
và phải tự giải quyết xung đột hợp nhất bạn có thể đã giới thiệu sự khác biệt trong changeset. Ngay cả một thay đổi 1 ký tự sẽ gây ra một bản vá lỗi khác nhau được tạo ra.
Kiểm tra ID bản vá yêu cầu phải có kịch bản như lời khuyên của Chronial. Đầu tiên tính id vá của gốc Cam kết với cái gì đó như
(lưu ý - các kịch bản chưa được thử nghiệm, nên được hợp lý gần làm việc mặc dù)
origCommitPatchId=$(git diff ORIG_COMMIT^! | git patch-id | awk '{print $1}')
Bây giờ bạn sẽ phải tìm kiếm thông qua tất cả các khác cam kết trong lịch sử của bạn và tính toán ID bản vá cho chúng và xem có bất kỳ ID nào giống nhau hay không.
for rev in $(git rev-list --all)
do
testPatchId=$(git diff ${rev}^1..${rev} | git patch-id | awk '{print $1}')
if [ "${origCommitPatchId}" = "${testPatchId}" ]; then
echo "${rev}"
fi
done
Bây giờ bạn có danh sách các Shas, và bạn có thể vượt qua những để git branch -a --contains
gì nếu ở trên không làm việc cho bạn mặc dù, vì xung đột nhập?
Vâng, có một vài điều khác bạn có thể thử. Thông thường khi bạn chọn cherry, hãy chọn cam kết tên của tác giả, email và ngày tháng ban đầu trong cam kết được giữ nguyên. Vì vậy, bạn sẽ nhận được một cam kết mới, nhưng thông tin tác giả sẽ giống nhau.
Vì vậy, bạn có thể nhận được thông tin này từ ban đầu của bạn cam kết với
git log -1 --pretty="%an %ae %ad" ORIG_COMMIT
Sau đó, như trước đây bạn sẽ phải đi qua tất cả các cam kết trong lịch sử của mình, in thông tin cùng ra và so sánh. Điều đó có thể cung cấp cho bạn một số kết quả trùng khớp bổ sung.
Bạn cũng có thể sử dụng git log --grep=ORIG_COMMIT
để tìm bất kỳ cam kết nào tham khảo ORIG_COMMIT trong thông báo cam kết.
Nếu không có tác phẩm nào trong số đó hoạt động, bạn có thể tìm kiếm một dòng cụ thể đã được giới thiệu với cuốc, hoặc có thể git log --grep
cho một thứ khác có thể là duy nhất trong thư cam kết.
Nếu tất cả điều này nghe có vẻ phức tạp, đúng vậy. Đó là lý do tại sao tôi bảo mọi người tránh sử dụng lựa chọn anh đào bất cứ khi nào có thể. git branch --contains
cực kỳ có giá trị và dễ sử dụng và đáng tin cậy 100%. Không ai trong số các giải pháp khác thậm chí đến gần.
Tôi khuyên bạn nên viết một tập lệnh sử dụng 'git rev-list' và' git patch-id' để xác định điều đó. Bạn cũng có thể muốn phân tích cú pháp các chú thích mà 'git cherry-pick' để lại trong các thư cam kết, vì bản vá-id (cũng là cơ sở của' git cherry') không hoàn hảo và sẽ phá vỡ nếu bạn giải quyết bất kỳ xung đột nào. – Chronial
Không có nghĩa là +1 nhận xét đó: Tôi không biết bạn nói gì hay nó giúp tôi như thế nào. Tôi sử dụng chúng để tạo danh sách? Cho phép giả định xung đột được giải quyết của một ai đó và đồng đội của tôi không đủ thông minh để sử dụng cherrypick -x vì tôi phải chỉ ra cho họ. – UpAndAdam
Vâng, sau đó bạn bị say. Nếu bạn muốn biết chính xác nhánh nào chứa cam kết nào, chỉ sử dụng các kết hợp và không bao giờ chọn cherry.Bạn có thể giả định rằng các cam kết với cùng một thông điệp cam kết có lẽ là giống nhau và làm một số chẩn đoán sôi nổi về sự khác biệt của chúng để xác nhận giả định đó. Nhưng quá trình đó sẽ dễ bị lỗi và bạn sẽ phải tự viết mã đó. – Chronial