2011-01-15 52 views
8

Tôi đang cố gắng duy trì một bản sao trống của kho lưu trữ Git và có một số vấn đề giữ cho các chi nhánh theo dõi từ xa luôn được cập nhật. Tôi tạo các chi nhánh theo dõi từ xa như sau:Làm thế nào để có được một chi nhánh theo dõi từ xa để luôn được cập nhật với nguồn gốc từ xa trong một kho Git trống?

git branch -t 0.1 origin/0.1 

Điều này dường như làm những gì tôi cần làm cho thời điểm đó. Tuy nhiên, nếu tôi thực hiện các thay đổi cho origin và sau đó tìm nạp với repo trần, mọi thứ bắt đầu sụp đổ. Luồng công việc của tôi trông giống như sau:

git fetch origin 

Dường như tất cả các cam kết đều đến vào thời điểm đó, nhưng bản sao cục bộ 0,1 của tôi chưa được cập nhật. Tôi có thể thấy rằng những thay đổi đã được đưa vào kho lưu trữ bằng cách thực hiện như sau:

git diff 0.1 refs/remotes/origin/0.1 

Tôi cần làm gì để cập nhật chi nhánh theo dõi cập nhật của từ xa? Tôi cảm thấy như tôi phải bỏ lỡ một bước hoặc một lá cờ ở đâu đó.

Cập nhật: Làm rõ bổ sung

Thông thường người ta sẽ đẩy vào một kho lưu trữ trần, chứ không phải chạy git fetch từ bên trong nó. Nếu bạn có thể sắp xếp để làm điều đó, cuộc sống sẽ dễ dàng hơn nhiều.

Dưới đây là một chút làm rõ về quy trình làm việc.

Kho lưu trữ git công khai của dự án được lưu trữ trên GitHub. Tôi đang quản lý dự án (wiki, các vấn đề, diễn đàn) bằng Redmine. Redmine yêu cầu một kho lưu trữ trần cục bộ để hoạt động. Khi GitHub nhận được thay đổi nó ping Redmine. Redmine sau đó cố gắng tìm nạp các thay đổi từ nguồn gốc của nó (GitHub).

Điều này rất hữu ích nếu tôi chỉ làm việc với tổng thể nhưng nó không hoạt động với các nhánh theo dõi của tôi. Các thay đổi đã được nhập nhưng không được liệt kê trong nhánh trong trình duyệt kho lưu trữ Redmine vì các nhánh địa phương không được cập nhật.

Tôi chắc chắn rằng tôi có thể đã làm việc này theo cách khác nhưng tìm một giải pháp chung để nhận các nhánh theo dõi và chạy chắc chắn là sở thích của tôi vì hầu hết các plugin liên quan đến Redmine đều cho rằng những thứ như "git fetch" nguồn gốc "là tất cả những gì cần phải làm.

Xem câu trả lời được chấp nhận cho giải pháp hoàn chỉnh. Giải pháp --mirror có vẻ là chính xác những gì cần thiết trong trường hợp này.

Trả lời

17

Thông thường người ta sẽ chuyển vào kho lưu trữ trống, thay vì chạy git fetch từ bên trong nó. Nếu bạn có thể sắp xếp để làm điều đó, cuộc sống sẽ dễ dàng hơn nhiều.

Nếu bạn để tìm nạp thay vì đẩy và bạn chỉ muốn tạo bản sao gốc trong kho trống, bạn có thể tránh hoàn toàn việc theo dõi chi nhánh từ xa. Nếu bạn đang bắt đầu gương này từ đầu, Charles Bailey chỉ ra dưới đây git sẽ thực hiện tất cả các thiết lập này cho bạn nếu ban đầu bạn sao chép kho lưu trữ với git clone --mirror.

Nếu không, bạn có thể nhận được một hiệu ứng tương tự với:

git fetch origin +refs/heads/*:refs/heads/* 

Các + có nghĩa rằng điều này sẽ ghi đè lên trạng thái của chi nhánh địa phương của bạn với những người từ xa. Nếu không có +, các bản cập nhật không hợp nhất chuyển tiếp nhanh sẽ bị từ chối. Tuy nhiên, nếu đây chỉ là một tấm gương, điều đó không quan trọng. (Bạn có thể cấu hình này là hành động mặc định trên git fetch origin bằng cách thiết lập các biến cấu hình remote.origin.fetch-+refs/heads/*:refs/heads/*. Nếu bạn muốn phản ánh thẻ và các chi nhánh từ xa theo dõi từ nguồn gốc là tốt, bạn có thể sử dụng +refs/*:refs/* thay thế.)

Tuy nhiên, nếu bạn muốn duy trì các nhánh theo dõi từ xa và chọn lọc hợp nhất chúng thành các nhánh địa phương, bạn có thể sử dụng các bước sau, nhưng tôi không nhất thiết khuyên bạn trừ khi bạn là người duy nhất sử dụng kho lưu trữ trống này. (Lưu ý: ban đầu ở đây tôi đề xuất sử dụng "git symbolic-ref HEAD refs/heads/anything" để chuyển nhánh và "git reset --soft" để thay đổi nhánh ref - tuy nhiên, Charles Bailey chỉ ra trong phần nhận xét mà người ta có thể sử dụng "git update-ref refs/heads/bất kỳ refs/remotes/origin/anything", mà không yêu cầu một để chuyển đổi chi nhánh đầu tiên.)

Trước tiên, bạn có thể muốn kiểm tra rằng việc cập nhật chi nhánh sẽ có là sự hợp nhất nhanh về phía trước và sau đó cập nhật chi nhánh. Lưu ý rằng có một điều kiện chủng tộc ở đây, đó là lý do tại sao tôi nói bạn chỉ nên làm điều này nếu bạn là người duy nhất sử dụng kho lưu trữ trống cục bộ của bạn - kiểm tra sẽ vô dụng nếu ai đó di chuyển trên nhánh giữa các bước đó.

  1. Bạn có thể kiểm tra xem một hợp nhất tương đương sẽ là một nhanh về phía trước (ví dụ rằng lịch sử của origin/master bao gồm master) bằng cách so sánh với git merge-base master origin/mastergit show-ref master - họ cần phải giống nhau. Hoặc bạn có thể sử dụng kịch bản is-ancestor trong this question, mà làm những lệnh với một số kiểm tra bổ sung.)
  2. Cuối cùng, bạn có thể cập nhật chi nhánh hiện tại của bạn (master trong trường hợp này) để trỏ đến origin/master với git update-ref refs/heads/master refs/remotes/origin/master

Tuy nhiên , như tôi đã nói ngay từ đầu, tôi tưởng tượng rằng các giải pháp thực tế bạn muốn là một trong hai:

  • Đẩy vào kho trần của bạn thay vì hoặc
  • Mirroring các reposi trần từ xa tory chính xác, như tôi đã mô tả ở trên

Tôi hy vọng đó là một số sử dụng.

+1

'git merge' luôn đòi hỏi một cây làm việc, bạn phải sử dụng' git update-ref' thay vào đó trong một kho lưu trữ trống.Tôi nghĩ rằng bạn là chính xác mà một tấm gương có vẻ giống như một giải pháp tốt hơn. Nó có thể là giá trị thêm một không về 'git clone --mirror'. –

+0

@Charles Bailey: lý do tôi nghĩ rằng nó có thể là một lỗi là trong nguồn của builtin-merge.c có một bình luận bắt đầu "Tại thời điểm này, chúng ta cần một hợp nhất thực sự ..." sau khi một nơi nhanh chuyển tiếp đã được thực hiện - Tôi không nghĩ rằng chỉ số hoặc cây làm việc là cần thiết cho đến thời điểm đó. Tôi sẽ loại bỏ nhận xét đó. –

+0

Bạn có thể yêu cầu trên danh sách gửi thư git, nhưng tôi không tin rằng nó sẽ được coi là một lỗi. Tôi nghĩ rằng, nói chung, nó nhất quán hơn để có một sự phân biệt rõ ràng giữa các lệnh không đòi hỏi một cây làm việc và những người làm. Có một lệnh mà _might_ cần một cây làm việc là một giao diện phức tạp hơn có khả năng gây ra một số hiểu lầm. –

1

Khi bạn fetch, thay đổi từ xa đang cập nhật tham chiếu cục bộ của riêng bạn cho điều khiển từ xa, origin/0.1 (điều này không bao giờ gây ra bất kỳ xung đột nào, vì origin/0.1 không bao giờ lưu trữ bất kỳ thay đổi cục bộ nào). Để nhập các thay đổi đó, bạn có thể git reset refs/remotes/origin/0.1 từ 0.1, sẽ làm cho nhánh HEAD (0.1) trỏ đến cùng một cam kết như nhánh từ xa.

Lưu ý rằng khi làm như vậy bạn sẽ mất mọi thay đổi đối với 0.1 không đến từ xa.

+1

Nếu tôi hiểu câu hỏi một cách chính xác, điều đó sẽ không hoạt động, vì câu hỏi hỏi về kho lưu trữ trống và 'git merge' và' git pull' yêu cầu một cây đang hoạt động. –

+0

Ồ, bạn nói đúng! Tôi đã sửa đổi câu trả lời của mình cho phù hợp. – huitseeker

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