Sử dụng đầu tiên git remote update
, để cập nhật từ xa của bạn. Sau đó, bạn có thể thực hiện một trong một số điều, chẳng hạn như:
git status -uno
sẽ cho bạn biết liệu chi nhánh bạn đang theo dõi đang ở phía trước, phía sau hoặc đã chuyển hướng. Nếu nó không nói gì, thì local và remote đều giống nhau.
git show-branch *master
sẽ hiển thị cho bạn các cam kết trong tất cả các nhánh có tên kết thúc bằng 'master' (ví dụ: master và origin / master ).
Nếu bạn sử dụng -v
với git remote update
( git remote -v update
), bạn có thể thấy các nhánh nào đã được cập nhật, vì vậy bạn không thực sự cần thêm bất kỳ lệnh nào.
Tuy nhiên, có vẻ như bạn muốn làm điều này trong một kịch bản hoặc chương trình và kết thúc với một giá trị đúng / sai. Nếu vậy, có nhiều cách để kiểm tra mối quan hệ giữa cam kết CHÍNH hiện tại của bạn và người đứng đầu chi nhánh mà bạn đang theo dõi, mặc dù có bốn kết quả có thể xảy ra, bạn không thể giảm câu trả lời thành có / không. Tuy nhiên, nếu bạn chuẩn bị thực hiện pull --rebase
thì bạn có thể coi "cục bộ đứng sau" và "cục bộ đã chuyển hướng" là "cần phải kéo" và hai cái còn lại là "không cần phải kéo".
Bạn có thể lấy id xác nhận của bất kỳ ref nào bằng cách sử dụng git rev-parse <ref>
, vì vậy bạn có thể làm điều này cho master và origin / master và so sánh chúng. Nếu chúng bằng nhau, các nhánh là như nhau. Nếu chúng không bằng nhau, bạn muốn biết cái nào đi trước cái kia. Sử dụng git merge-base master origin/master
sẽ cho bạn biết tổ tiên chung của cả hai nhánh và nếu họ không chuyển hướng thì điều này sẽ giống với cái này hoặc cái kia. Nếu bạn nhận được ba id khác nhau, các nhánh đã chuyển hướng.
Để thực hiện điều này một cách chính xác, ví dụ như trong tập lệnh, bạn cần có thể tham khảo nhánh hiện tại và nhánh từ xa mà nó đang theo dõi. Hàm thiết lập dấu nhắc bash trong /etc/bash_completion.d
có một số mã hữu ích để nhận tên nhánh. Tuy nhiên, có lẽ bạn không thực sự cần phải lấy tên. Git có một số tốc ký gọn gàng để tham khảo các nhánh và cam kết (như được ghi trong tài liệu git rev-parse --help
). Cụ thể, bạn có thể sử dụng @
cho nhánh hiện tại (giả sử bạn không ở trạng thái tách rời) và @{u}
cho nhánh ngược dòng của nó (ví dụ origin/master
). Vì vậy, git merge-base @ @{u}
sẽ trả về cam kết (băm của) tại đó nhánh hiện tại và phân kỳ ngược dòng của nó git rev-parse @
và git rev-parse @{u}
sẽ cung cấp cho bạn các giá trị băm của hai mẹo. Điều này có thể được tóm tắt trong kịch bản sau đây:
#!/bin/sh
UPSTREAM=${1:-'@{u}'}
LOCAL=$(git rev-parse @)
REMOTE=$(git rev-parse "$UPSTREAM")
BASE=$(git merge-base @ "$UPSTREAM")
if [ $LOCAL = $REMOTE ]; then
echo "Up-to-date"
elif [ $LOCAL = $BASE ]; then
echo "Need to pull"
elif [ $REMOTE = $BASE ]; then
echo "Need to push"
else
echo "Diverged"
fi
Lưu ý: phiên bản cũ hơn của git không cho phép @
riêng, vì vậy bạn có thể phải sử dụng @{0}
thay thế.
Dòng này UPSTREAM=${1:-'@{u}'}
cho phép bạn tùy ý vượt qua một nhánh ngược dòng một cách rõ ràng, trong trường hợp bạn muốn kiểm tra một nhánh từ xa khác với nhánh được cấu hình cho nhánh hiện tại. Điều này thường sẽ có dạng remotename / Branchname . Nếu không có tham số nào được đưa ra, giá trị mặc định là @{u}
.
Kịch bản giả định rằng bạn đã thực hiện một git fetch
hoặc git remote update
trước tiên, để cập nhật các nhánh theo dõi. Tôi đã không xây dựng tập lệnh này thành tập lệnh vì nó linh hoạt hơn để có thể thực hiện tìm nạp và so sánh dưới dạng các thao tác riêng biệt, ví dụ nếu bạn muốn so sánh mà không tìm nạp vì bạn đã tìm nạp gần đây.