2010-04-06 17 views
66

Có thể sao chép chỉ một nhánh (hoặc từ một cam kết nhất định) trong Git và Mercurial không? Ý tôi là, tôi muốn sao chép một repo trung tâm nhưng vì nó rất lớn tôi muốn chỉ nhận được một phần của nó và vẫn có thể đóng góp lại những thay đổi của tôi. Có thể không? Giống như, tôi chỉ muốn từ Tag 130 trở đi hoặc một cái gì đó như thế?Bản sao một phần với Git và Mercurial

Nếu có, làm cách nào?

Trả lời

67

Trong đất Git bạn đang nói về ba loại khác nhau bắt chước một phần:

  • nhái cạn: Tôi muốn lịch sử từ sửa đổi điểm X trở đi.

    Sử dụng git clone --depth <n> <url> cho điều đó, nhưng hãy nhớ rằng dòng vô tính nông có phần hạn chế trong tương tác với các kho lưu trữ khác. Bạn sẽ có thể tạo bản vá và gửi chúng qua email.

  • bản sao một phần bởi filepath: Tôi muốn tất cả lịch sử lịch sử sửa đổi trong một số thư mục /path.

    Không thể trong Git. Với Git hiện đại mặc dù bạn có thể có thanh toán thưa thớt, tức là bạn có toàn bộ lịch sử nhưng bạn hãy kiểm tra (có trong khu vực làm việc) chỉ tập hợp con của tất cả các tệp.

  • nhân bản chỉ được lựa chọn chi nhánh: Tôi muốn nhân bản chỉ có một chi nhánh (hoặc tập hợp con chọn chi nhánh).

    có thể, và

    trước git 1.7.10 không đơn giản: bạn sẽ cần phải làm những gì bản sao làm bằng tay, tức là git init [<directory>], sau đó git remote add origin <url>, sửa .git/config thay thế * trong remote.origin.fetch theo ngành yêu cầu (có thể là 'bậc thầy '), sau đó git fetch.

    as of git 1.7.10git clone cung cấp tùy chọn --single-branch có vẻ như đã được thêm vào chỉ cho mục đích này và có vẻ khá dễ dàng. Tuy nhiên, hãy lưu ý rằng vì các nhánh thường chia sẻ phần lớn lịch sử của chúng, thu được từ việc sao chép chỉ một tập con của nhánh có thể nhỏ hơn bạn nghĩ.

Bạn cũng có thể tạo bản sao nông của một nhóm con được chọn duy nhất.

Nếu bạn biết cách mọi người muốn chia nhỏ mọi thứ bằng filepath (nhiều dự án trong cùng một kho lưu trữ), bạn có thể sử dụng các mô-đun con (kiểu như svn: externals) để phân chia lại thành các phần riêng biệt.

+0

Vì vậy, nếu tôi nhân bản chi nhánh "XX", nó sẽ nhận được tất cả các phụ huynh cam kết từ "chủ", phải không? Hoặc chỉ có một cam kết duy nhất tôi đã thực hiện trên nhánh đó? – pablo

+1

Nếu bạn sao chép (tìm nạp) chỉ nhánh "XX", bạn sẽ nhận được tất cả các cam kết của nó, bao gồm các cam kết đó nhánh "XX" có chung với nhánh "chính". Trong cam kết Git không '* thuộc *' cho một chi nhánh. –

+0

Ok, sau đó nó không phải là một bản sao một phần nào kể từ khi bạn nhận được tất cả các bậc cha mẹ và do đó toàn bộ repos (ok, phần lớn nhất mà là trên chủ) – pablo

41

Trong đất lanh bạn đang nói về ba loại khác nhau bắt chước một phần:

  • nhái cạn: Tôi muốn lịch sử từ sửa đổi điểm X trở đi sử dụng remotefilelog extension
  • nhái một phần bởi filepath: Tôi muốn tất cả lịch sử sửa đổi trong thư mục/đường dẫn có thử nghiệm narrowhg extension hoặc tôi chỉ muốn các tệp trong thư mục/đường dẫn nằm trong thư mục làm việc của mình với tiện ích mở rộng thử nghiệm (được chuyển từ phiên bản 4.3, xem hg help sparse).
  • nhái một phần theo ngành: Tôi muốn tất cả lịch sử sửa đổi về chi nhánh Y: sử dụng bản sao -r

Nếu bạn biết làm thế nào mọi người sẽ muốn phá vỡ mọi thứ xuống bởi filepath (nhiều dự án trong repo cùng (xấu hổ với bạn)) bạn có thể sử dụng subrepositories (loại giống như externals svn) để phân chia trước các repo thành các phần riêng biệt cloneeable

Ngoài ra, với "rất lớn tôi muốn chỉ nhận được một phần của nó" : Bạn thực sự chỉ phải làm điều đó một lần. Chỉ cần sao chép nó trong khi bạn ăn trưa, và sau đó bạn có nó mãi mãi hơn. Sau đó, bạn có thể pull và nhận được các vùng đồng bằng có hiệu quả trong tương lai. Và nếu bạn muốn một bản sao khác của nó, chỉ cần sao chép bản sao đầu tiên của bạn. Trường hợp bạn có một bản sao không quan trọng (và các bản sao cục bộ không mất thêm không gian đĩa vì chúng là các liên kết cứng bên dưới bìa).

+1

cũng thẻ không giống như chi nhánh không giống như trong một số VCS vì vậy điều này đi kèm theo điểm đầu tiên –

+0

Có lịch sử cắt tỉa (http://mercurial.selenic.com/wiki/TrimmingHistory) và bản sao nông (http://mercurial.selenic.com/wiki/ShallowClone) plugins cho mercurial. Mặc dù vậy, tôi không biết họ giỏi như thế nào. – panzi

+8

Cả hai đề xuất này đều bị từ chối mà không cần triển khai. –

-1

Trong lanh lợi, bạn sẽ có thể vì vậy một số này sử dụng:

hg convert --banchmap FILE SOURCEDEST REVMAP 

Bạn cũng có thể muốn:

--config convert.hg.startrev=REV 

Nguồn có thể git, lanh lợi, hoặc một loạt các khác hệ thống.

Tôi chưa thử, nhưng chuyển đổi khá phong phú.

+3

Chuyển đổi phần mở rộng ghi đè các băm do đó đây không phải là một phần bản sao của repo hiện có mà là một bản mới. Có nghĩa là nó sẽ là một kho lưu trữ riêng biệt mà không thể kéo hoặc đẩy từ bản gốc. – Priit

5

Phương pháp này tạo ra một kho lưu trữ không phiên bản mà không subrepositories:

hg clone -U ssh://machine//directory/path/to/repo/project projecttemp 

cd projecttemp 

hg archive -r tip ../project-no-subrepos 

Mã nguồn không phiên bản mà không có sự subrepositoies là trong thư mục dự án-no-subrepos

2

Về Git nó có thể là một ý nghĩa lịch sử mà Linus Torvalds đã trả lời câu hỏi này từ quan điểm khái niệm vào năm 2007 trong một cuộc nói chuyện đã được ghi lại và có sẵn trực tuyến.

Câu hỏi đặt ra là liệu có thể kiểm tra chỉ một số tệp trong kho lưu trữ Git hay không.

Tech Talk: Linus Torvalds on git t=43:10

Nói tóm lại, ông nói rằng một trong những quyết định thiết kế của Git mà đặt nó ngoài từ hệ thống quản lý nguồn khác (ông trích dẫn BitKeeper và SVN) là Git quản lý nội dung, không tập tin. Các hàm ý là ví dụ một khác biệt của một tập hợp con của các tập tin trong hai phiên bản được tính bằng cách đầu tiên lấy toàn bộ khác biệt và sau đó cắt tỉa nó chỉ để các tập tin được yêu cầu. Khác là bạn phải kiểm tra toàn bộ lịch sử; trong một thời trang tất cả hoặc không có gì. Vì lý do này, ông đề nghị chia các thành phần liên quan lỏng lẻo giữa nhiều kho và đề cập đến một nỗ lực liên tục để thực hiện một giao diện người dùng để quản lý một kho lưu trữ được cấu trúc như một siêu dự án chứa các kho nhỏ hơn.

Theo như tôi biết quyết định thiết kế cơ bản này vẫn còn táo hôm nay. Điều siêu dự án có thể trở thành những gì bây giờ là submodules.

+1

Tôi biết bài đăng ... Ban đầu tôi đã gửi nó tới slashdot: P – pablo

6

Câu trả lời được chọn cung cấp tổng quan tốt, nhưng thiếu một ví dụ hoàn chỉnh.

Minimize tải về và thanh toán của bạn dấu chân (a), (b):

git clone --no-checkout --depth 1 --single-branch --branch (name) (repo) (folder) 
cd (folder) 
git config core.sparseCheckout true 
echo "target/path/1" >>.git/info/sparse-checkout 
echo "target/path/2" >>.git/info/sparse-checkout 
git checkout 

Định kỳ tối ưu hóa kho chân địa phương của bạn (c) (không bắt buộc, sử dụng một cách cẩn thận):

git clean --dry-run # consider and tweak results then switch to --force 
git gc 
git repack -Ad 
git prune 

Xem thêm : How to handle big repositories with git

+0

Ví dụ rất hay/thực tiễn tốt nhất. +1 – VonC

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