Trước khi đưa một bản sửa vào nhánh phát hành, bạn muốn biết commit gốc đã nằm trong lịch sử nhánh đó chưa. Tìm cùng một đoạn code trong file có thể hữu ích, nhưng nó không trả lời chính xác câu hỏi về quan hệ commit.
git merge-base --is-ancestor A B kiểm tra A có là tổ tiên của B hay không. Bài dùng Git 2.54.0, đối chiếu tài liệu ngày 31/10/2026. Ví dụ đã chạy trong repository tạm, không fetch, push hoặc thay đổi checkout hiện tại của workspace.
1. Đọc đúng ba loại kết quả
Mã thoát 0 nghĩa là quan hệ tổ tiên đúng; 1 nghĩa là không đúng. Một mã khác báo lỗi thực thi hoặc đầu vào và cần được xử lý riêng. Lệnh kiểm tra này không cần in một chuỗi “true” ra màn hình để bạn sử dụng kết quả.
Thứ tự A và B quan trọng: hỏi commit cũ có nằm trong lịch sử commit mới không khác với hỏi chiều ngược lại. Cùng một commit được so với chính nó cũng đạt phép kiểm tra.
2. Tạo lịch sử nhỏ để thử
Chạy nguyên khối Bash sau. Nó tạo thư mục mới bằng mktemp, chỉ cấu hình danh tính trong repo thử và in đường dẫn để bạn có thể xem lại. Không dùng thư mục project thật thay cho biến này.
#!/usr/bin/env bash
set -eu
demo_dir=$(mktemp -d)
git init -q --template= "$demo_dir"
git -C "$demo_dir" config user.name 'AeDev Demo'
git -C "$demo_dir" config user.email '[email protected]'
printf 'base\n' > "$demo_dir/note.txt"
git -C "$demo_dir" add note.txt
git -C "$demo_dir" -c commit.gpgsign=false commit -qm base
base_commit=$(git -C "$demo_dir" rev-parse HEAD)
printf 'fix\n' >> "$demo_dir/note.txt"
git -C "$demo_dir" add note.txt
git -C "$demo_dir" -c commit.gpgsign=false commit -qm fix
tip_commit=$(git -C "$demo_dir" rev-parse HEAD)
if git -C "$demo_dir" merge-base --is-ancestor "$base_commit" "$tip_commit"; then
printf 'base nam trong lich su tip\n'
else
exit "$?"
fi
if git -C "$demo_dir" merge-base --is-ancestor "$tip_commit" "$base_commit"; then
printf 'Ket qua bat ngo\n' >&2
exit 2
else
ancestor_status=$?
test "$ancestor_status" -eq 1
printf 'tip chua nam trong lich su base\n'
fi
printf 'Repo thu: %s\n' "$demo_dir"
Phép thử đã xác nhận hai hướng cho kết quả khác nhau. Nó cố ý giữ repo tạm để bạn có thể chạy git log --oneline tại đường dẫn được in; không tự xóa dữ liệu ngoài repo thử.
3. Áp dụng cho tham chiếu thực tế
Trong project của bạn, thay FIX_REF và TARGET_REF bằng commit hoặc tên nhánh có thật. Đây là placeholder, không phải hai branch bắt buộc phải tạo. Có thể xác minh chúng trỏ tới commit trước khi kiểm tra quan hệ.
git rev-parse --verify 'FIX_REF^{commit}'
git rev-parse --verify 'TARGET_REF^{commit}'
Sau khi thay tên, dùng hai tham chiếu đó làm A và B. Chỉ đọc trạng thái refs local không tự cập nhật dữ liệu từ remote. Nếu đang kiểm tra origin/main, trước hết xác định remote-tracking ref đó được cập nhật khi nào theo workflow của team.
Đừng biến mọi lỗi thành câu “chưa có commit”. Branch gõ sai, object chưa tải hoặc repository lỗi đều cần được phân biệt với mã 1. Trong automation, xử lý 0, 1 và nhánh lỗi còn lại tách bạch để tránh tạo quyết định sai từ dữ liệu thiếu.
4. Không đồng nhất lịch sử với nội dung
Nếu bản sửa được cherry-pick, commit mới thường có ID khác. Nhánh có thể đã chứa thay đổi tương đương nhưng không chứa commit gốc theo quan hệ tổ tiên. Squash merge cũng là một tình huống không nên suy ngược từ phép kiểm tra này ra sự hiện diện của từng commit gốc.
Ở chiều còn lại, một commit có thể là tổ tiên nhưng thay đổi của nó đã bị revert sau đó. Kết quả 0 không chứng minh hành vi sản phẩm hiện tại vẫn mang bản sửa. Khi câu hỏi là “bug đã hết chưa”, cần xem lịch sử liên quan và chạy phép kiểm tra hành vi.
Kiểm tra và bước tiếp theo
Thử thêm trường hợp A bằng B và một tham chiếu không tồn tại trong repo tạm. Trường hợp đầu phải đạt, trường hợp sau phải rơi vào lỗi chứ không phải câu trả lời quan hệ âm tính. Các trường hợp này đã được kiểm tra thêm cùng fixture của bài.
Với shallow clone, lịch sử chưa đầy đủ có thể làm giới hạn khả năng suy luận về tổ tiên. Kiểm tra độ đầy đủ của lịch sử trước khi dùng kết quả làm điều kiện phát hành. Không tự động merge hoặc cherry-pick chỉ vì một kiểm tra trả 1; đây là một bằng chứng cho quyết định, không thay thế quy trình review.


