Làm cách nào để tôi 'git fetch' và 'git merge' từ một nhánh theo dõi từ xa (như 'git pull')


111

Tôi đã thiết lập một số nhánh theo dõi từ xa trong git, nhưng dường như tôi không bao giờ có thể hợp nhất chúng vào nhánh cục bộ khi tôi đã cập nhật chúng bằng 'git fetch'.

Ví dụ: giả sử tôi có nhánh từ xa được gọi là 'an-nhánh-khác'. Tôi thiết lập cục bộ làm chi nhánh theo dõi bằng cách sử dụng

git branch --track an-other-branch origin/an-other-branch

Càng xa càng tốt. Nhưng nếu nhánh đó được cập nhật (thường là do tôi di chuyển máy và kích hoạt từ máy đó) và tôi muốn cập nhật nó trên máy gốc, tôi sẽ gặp sự cố với tìm nạp / hợp nhất:

git fetch origin an-other-branch
git merge origin/an-other-branch

Bất cứ khi nào tôi làm điều này, tôi nhận được thông báo 'Đã cập nhật' và không có gì hợp nhất.

Tuy nhiên, một

git pull origin an-other-branch

luôn cập nhật nó như bạn mong đợi.

Ngoài ra, chạy git diff

git diff origin/an-other-branch

cho thấy rằng có sự khác biệt, vì vậy tôi nghĩ rằng tôi đã sai cú pháp của mình.

Tôi đang làm gì sai?

EDIT [2010-04-09]: Tôi đã kiểm tra một vài lần và chắc chắn tôi không ở trên một chi nhánh khác. Liệu 'git fetch' của tôi được theo sau bởi một 'git merge' (như được hiển thị ở trên) có thực hiện điều tương tự như một git pull không? Tôi sẽ nhận được một số quy trình làm việc hiển thị kết quả của trạng thái git, v.v.

Câu trả lời:


170

Bạn không tìm nạp một nhánh, bạn tìm nạp toàn bộ điều khiển từ xa:

git fetch origin
git merge origin/an-other-branch

8
Chi tiết hơn: git fetch origin an-other-branchlưu trữ mẹo đã tìm nạp vào FETCH_HEAD, nhưng không lưu trữ origin/an-other-branch(tức là 'chi nhánh theo dõi từ xa' thông thường). Vì vậy, người ta có thể làm git fetch origin an-other-branch && git merge FETCH_HEAD, nhưng làm như @Gareth nói thì tốt hơn (hoặc chỉ sử dụng git pull ).
Chris Johnsen

vì vậy nếu origin có 1000 chi nhánh, bạn sẽ có một chi nhánh từ xa cho tất cả chúng?
Gauthier

4
Chắc chắn rồi. Nếu tôi đã thêm một kho lưu trữ từ xa với 1000 chi nhánh để khai thác, và tôi hỏi những gì các chi nhánh điều khiển từ xa có, nó chết tiệt cũng tốt hơn cho tôi tất cả 1000
Gareth

sẽ git merge origin/an-other-branchhợp nhất origin/an-other-branchvào tất cả các chi nhánh cục bộ được thiết lập để theo dõi nó? làm cách nào để tôi có thể hợp nhất thành một chi nhánh cục bộ?
lưỡng cư

1
Vậy git pull(không có đối số) làm gì - nó hợp nhất với nhánh nào? Nó có hợp nhất nhánh theo dõi từ xa tương ứng với nhánh hiện tại không?
The Red Pea

69

Chỉ chọn một nhánh: fetch/ merge vs. pull

Mọi người thường khuyên bạn nên tách "tìm nạp" khỏi "hợp nhất". Họ nói thay vì điều này:

    git pull remoteR branchB

làm cái này:

    git fetch remoteR
    git merge remoteR branchB

Những gì họ không đề cập đến là một lệnh tìm nạp như vậy sẽ thực sự tìm nạp tất cả các nhánh từ kho lưu trữ từ xa, đây không phải là những gì lệnh kéo đó làm. Nếu bạn có hàng nghìn chi nhánh trong kho lưu trữ từ xa, nhưng bạn không muốn xem tất cả chúng, bạn có thể chạy lệnh khó hiểu này:

    git fetch remoteR refs/heads/branchB:refs/remotes/remoteR/branchB
    git branch -a  # to verify
    git branch -t branchB remoteR/branchB

Tất nhiên, điều đó thật khó nhớ, vì vậy nếu bạn thực sự muốn tránh tìm nạp tất cả các nhánh, tốt hơn là thay đổi của bạn .git/confignhư được mô tả trong ProGit.

Huh?

Lời giải thích tốt nhất về tất cả điều này là trong Chương 9-5 của ProGit, Git Internals - The Refspec ( hoặc qua github ). Điều đó thật đáng kinh ngạc khó tìm thấy qua Google.

Đầu tiên, chúng ta cần làm rõ một số thuật ngữ. Đối với theo dõi chi nhánh từ xa, thường có 3 nhánh khác nhau cần lưu ý:

  1. Nhánh trên repo từ xa: refs/heads/branchBbên trong repo khác
  2. Chi nhánh theo dõi từ xa của bạn : refs/remotes/remoteR/branchBtrong repo của bạn
  3. Chi nhánh của riêng bạn: refs/heads/branchBbên trong kho của bạn

Các nhánh theo dõi từ xa (trong refs/remotes) là chỉ đọc. Bạn không trực tiếp sửa đổi chúng. Bạn sửa đổi chi nhánh của riêng mình, sau đó bạn đẩy đến chi nhánh tương ứng tại đại diện từ xa. Kết quả không được phản ánh trong của bạn refs/remotescho đến sau khi kéo hoặc tìm nạp thích hợp. Sự phân biệt đó đối với tôi rất khó hiểu từ git man-pages, chủ yếu là do nhánh cục bộ ( refs/heads/branchB) được cho là "theo dõi" nhánh theo dõi từ xa khi .git/configđịnh nghĩa branch.branchB.remote = remoteR.

Hãy nghĩ về 'refs' như con trỏ C ++. Về mặt vật lý, chúng là các tệp chứa SHA-digest, nhưng về cơ bản chúng chỉ là các con trỏ vào cây cam kết. git fetchsẽ thêm nhiều nút vào cây cam kết của bạn, nhưng cách git quyết định con trỏ nào sẽ di chuyển hơi phức tạp.

Như đã đề cập trong một câu trả lời khác ,

    git pull remoteR branchB

cũng không

    git fetch remoteR branchB

sẽ di chuyển refs/remotes/branches/branchB, và sau này chắc chắn không thể di chuyển refs/heads/branchB. Tuy nhiên, cả hai đều di chuyển FETCH_HEAD. (Bạn có thể catbất kỳ tệp nào trong số các tệp này bên trong .git/để xem khi nào chúng thay đổi.) Và git mergesẽ tham chiếu đến FETCH_HEAD, trong khi thiết lập MERGE_ORIG, v.v.


1
Bạn có biết rằng liên kết của bạn tới Git Internals là liên kết đến cùng câu hỏi này không?
Shahbaz

9

Bạn có chắc chắn bạn đang ở trên địa phương an-other-branchkhi bạn hợp nhất?

git fetch origin an-other-branch
git checkout an-other-branch
git merge origin/an-other-branch

Giải thích khác :

tất cả các thay đổi từ nhánh bạn đang cố gắng hợp nhất đã được hợp nhất với nhánh bạn hiện đang ở.
Cụ thể hơn, điều đó có nghĩa là chi nhánh bạn đang cố gắng hợp nhất là một chi nhánh mẹ của chi nhánh hiện tại của bạn

nếu bạn vượt trước repo từ xa bởi một lần cam kết, đó là repo từ xa đã lỗi thời, không phải bạn.

Nhưng trong trường hợp của bạn, nếu git pullhoạt động, điều đó chỉ có nghĩa là bạn không ở đúng nhánh.


3

Git pull thực sự là một công cụ kết hợp: nó chạy git fetch (nhận các thay đổi) và git merge (hợp nhất chúng với bản sao hiện tại của bạn)

Bạn có chắc mình đang đi đúng nhánh không?


Tôi nghĩ rằng OP là khác nhau. chi nhánh, xảy ra với tôi.
Chaklader Asfak Arefe

1

đây là các lệnh:

git fetch origin
git merge origin/somebranch somebranch

nếu bạn làm điều này trên dòng thứ hai:

git merge origin somebranch

nó sẽ cố gắng hợp nhất cái cục bộ vào nhánh hiện tại của bạn.

Câu hỏi, như tôi đã hiểu, bạn đã tìm nạp cục bộ và muốn hợp nhất chi nhánh của mình với chi nhánh mới nhất của cùng một chi nhánh.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.