2011-05-05 30 views
19

Tôi đang cố gắng sử dụng lược đồ hợp nhất subtree của git nơi thư mục con mà tôi muốn hợp nhất được lồng nhau khá sâu - hiện tại có bốn cấp sâu.Git: Subtree Merge vào một thư mục con được lồng ghép sâu?

Tôi làm theo hướng dẫn here để thêm kho lưu trữ mô-đun làm điều khiển từ xa, chạy git read-tree để lấy mã từ xa vào thư mục con trong repo cục bộ của tôi và cam kết những thay đổi đó.

Sự cố của tôi xuất hiện khi tôi cố kéo và hợp nhất các thay đổi từ điều khiển từ xa vào nhánh chính của dự án chính của tôi. Bước 5 ở trang trên cho thấy một git kéo với chuyển đổi -s subtree. Điều này làm việc một cách chính xác cho tôi khi thư mục con của tôi là một, hai hoặc ba cấp độ sâu, nhưng không phải là bốn.

Đây là kết quả của việc hợp nhất vào một thư mục con 2 cấp sâu. Bạn có thể thấy rằng tệp README trong trang/tất cả/đã được cập nhật chính xác. Trong repo từ xa của tôi, README nằm trong thư mục gốc.

$ git pull -s subtree REMOTE_REPO master 
remote: Counting objects: 5, done. 
remote: Compressing objects: 100% (3/3), done. 
remote: Total 3 (delta 2), reused 0 (delta 0) 
Unpacking objects: 100% (3/3), done. 
From /path/to/my/REMOTE_REPO 
* branch   master  -> FETCH_HEAD 
Merge made by subtree. 
sites/all/README | 2 ++ 
1 files changed, 2 insertions(+), 0 deletions(-) 

Ở đây thư mục con là 3 cấp sâu: sites/all/modules /. Điều này làm việc tốt, quá, kéo những thay đổi và cập nhật các tập tin.

$ git pull -s subtree REMOTE_REPO master 
remote: Counting objects: 5, done. 
remote: Compressing objects: 100% (3/3), done. 
remote: Total 3 (delta 2), reused 0 (delta 0) 
Unpacking objects: 100% (3/3), done. 
From /path/to/my/REMOTE_REPO 
* branch   master  -> FETCH_HEAD 
Merge made by subtree. 
sites/all/modules/README | 2 ++ 
1 files changed, 2 insertions(+), 0 deletions(-) 

Nhưng bây giờ mã của tôi nằm trong thư mục con sâu 4 cấp: sites/all/modules/my_module /. Git dường như để kéo các thay đổi từ REMOTE_REPO, nhưng nó không cập nhật các tập tin, thay vào đó nói với tôi rằng nó đã được cập nhật.

$ git pull -s subtree REMOTE_REPO master 
remote: Counting objects: 5, done. 
remote: Compressing objects: 100% (3/3), done. 
remote: Total 3 (delta 2), reused 0 (delta 0) 
Unpacking objects: 100% (3/3), done. 
From /path/to/my/REMOTE_REPO 
* branch   master  -> FETCH_HEAD 
Already up-to-date! 
Merge made by subtree. 

Và nếu tôi chạy lại ngay lập tức, nó không kéo thay đổi hoặc cập nhật tệp.

$ git pull -s subtree REMOTE_REPO master 
From /path/to/my/REMOTE_REPO 
* branch   master  -> FETCH_HEAD 
Already up-to-date. 

Xem nhật ký git tại thời điểm này sẽ cho tôi thấy những thay đổi từ repo từ xa và hợp nhất, nhưng các tệp trong thanh toán của tôi chưa được cập nhật.

Đây có phải là lỗi hay tôi đang làm điều gì đó sai?

Cập nhật: Chris Johnsen cung cấp các tùy chọn sau đây, mà ném một lỗi:

$ git pull -X subtree=sites/all/modules/my_module/ REMOTE_REPO master 
remote: Counting objects: 5, done. 
remote: Compressing objects: 100% (3/3), done. 
remote: Total 3 (delta 2), reused 0 (delta 0) 
Unpacking objects: 100% (3/3), done. 
From /Users/jeff/work/checkouts/compass_suite 
* branch   master  -> FETCH_HEAD 
fatal: entry not found in tree 173d4f16af4d2d61ae5c4b3446c392e8b49cc57d 

Trả lời

10

Chiến lược subtree merge nhân tạo hạn chế độ sâu của tìm kiếm của mình cho nơi cây con “phù hợp” vào cây tổng thể. Rất tiếc, giới hạn này được mã hóa cứng (xem match-trees.c:267).

May mắn thay, Git 1.7.0 đã thêm tùy chọn subtree=… vào (mặc định) recursive chiến lược hợp nhất. Tùy chọn này cho phép bạn xác định chính xác tiền tố để Git không phải đoán (nhiều).

Với Git 1.7.0 hoặc mới hơn, cố gắng này:

git pull -X subtree=sites/all/modules/my_module REMOTE_REPO master 
+0

Cảm ơn câu trả lời của bạn, Chris. Tôi vừa thử nó một lỗi. Vì tôi không thể đăng mã trong các bình luận, tôi đã cập nhật câu hỏi của mình để hiển thị đầu ra của lệnh. – Jeff

+30

Tôi nên chú ý hơn. Hóa ra dấu gạch chéo ở cuối gây ra lỗi. Tôi đã sử dụng subtree = sites/all/modules/my_module/thay vì subtree = sites/all/modules/my_module. Không có dấu gạch chéo, nó hoạt động! Cảm ơn một lần nữa. – Jeff

+0

Cảm ơn câu trả lời. Tôi sử dụng điều này để chia nhỏ một repo git lớn thành nhiều cái nhỏ hơn. –

54

Làm rõ cho độc giả tương lai, giải pháp là trong các ý kiến ​​phản ứng Chris Johnsen của. Nếu bạn nhìn thấy lỗi "không có trong danh mục" không tìm thấy trong cây ", hãy loại bỏ dấu gạch chéo ở cuối tiền tố subtree của bạn.

Ví dụ, nếu bạn đang cố gắng để kéo một cây con GitHub trang với một lệnh như

git subtree --prefix gh-pages/ pull origin gh-pages 

và có những mâu thuẫn, bạn sẽ nhận được một lỗi như

* branch   gh-pages -> FETCH_HEAD 
fatal: entry not found in tree 6e69aa201cad3e5888f1d12af0d910f8a10a8ec3 

Chỉ cần loại bỏ các dấu gạch chéo từ số gh-trang thư mục

git subtree --prefix gh-pages pull origin gh-pages 

Thao tác này sẽ hoạt động và sẽ cố hợp nhất. Kịch bản tồi tệ nhất bạn có thể nhận được là khi quá trình hợp nhất tự động không thành công và bạn gặp lỗi như

Automatic merge failed; fix conflicts and then commit the result. 

nhưng bạn phải giải quyết xung đột theo cách thủ công và bạn đã hoàn tất.

+0

Yikes! Đó là một thông báo lỗi hữu ích. –

+4

+1 lifesaver, cùng một vấn đề đi kèm với git-subtree làm một hợp nhất và câu trả lời tương tự. – Amoss

+1

Điều này giải quyết được vấn đề của tôi. Những gì được chấp nhận nói về? – bentford

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