2010-09-22 22 views
6

Như hướng dẫn rõ ràng aptly points out (tìm kiếm cho "Thẻ và nhân bản"):Làm cách nào để lấy thẻ changeset sau khi bạn sao chép hoặc kéo vào thẻ bằng cách sử dụng mercurial?

Khi bạn chạy hg clone -r foo nhân bản một kho lưu trữ như các thẻ foo, các bản sao mới sẽ không chứa bất kỳ phiên bản mới hơn một trong những thẻ đề cập đến, bao gồm sửa đổi nơi thẻ được tạo. Kết quả là bạn sẽ nhận đúng tập hợp con của lịch sử của dự án trong kho lưu trữ mới, nhưng không phải là thẻ bạn có thể đã mong đợi.

Có nghĩa là hg tags trong bản sao mới của bạn KHÔNG hiển thị thẻ foo. Điều tương tự cũng xảy ra nếu bạn đã nhân bản trước khi thêm thẻ foo và bạn thực hiện hg pull -r foo.

(Digression: tag là điều duy nhất tôi không hoàn toàn có được trong hg. Tôi hiểu có những lợi thế (ví dụ: merge) khi đặt nó vào một changeset, nhưng nó luôn cảm thấy kỳ lạ khi có dữ liệu meta được trộn với nguồn code.)

Rõ ràng là tôi đang yêu cầu một cách tự động, thay vì kéo thẻ changeset thành một bước thủ công riêng biệt.

Tôi biết tôi có thể kiểm tra trường hợp này trong móc incoming (vì vậy nó hoạt động cho cả bản sao và kéo) hoặc quấn clonepull.

Nhưng có cách nào tốt hơn/dễ hơn không?


CẬP NHẬT trình theo dõi lỗi hg đã có this issue.

+2

thẻ giới thiệu các thay đổi đã trở thành một trong số ít những điều tôi thực sự không thích về Mercurial –

Trả lời

0

Có thể thực hiện bằng móc hậu móc/móc kéo, nhưng có một vài kẻ lừa đảo.

Đầu tiên, nó chỉ hoạt động đối với repo cục bộ, vì bạn không thể lấy danh sách các thẻ trong repo từ xa.

Thứ hai, xử lý các đối số và tùy chọn nhân bản/kéo không phải là nhỏ. (Đối với bản sao tôi cần phải lấy repo mục tiêu, -r, -u, -U. Đối với kéo tôi cần -r-u.) Tôi đã cố gắng sử dụng fancyopts, nhưng nó không thể xử lý các tùy chọn toàn cầu, được xử lý đi trong công văn. Tôi quản lý để hack công văn để cung cấp cho tôi chỉ args và opts của một lệnh, nhưng nó cảm thấy và trông xấu xí.

Sử dụng trình bao bọc lệnh sẽ loại bỏ vấn đề thứ hai.

Tôi hy vọng một ngày nào đó hg sẽ thêm tùy chọn sao chép và kéo để làm sạch.

+1

Nếu bạn đang sử dụng móc, bạn không thể kiểm tra giá trị của biến '$ HG_URL'. –

+0

Tôi cũng cần các loại pats và opts, nhưng đề cập đến $ HG_URL đã giúp tôi tìm ra từ [man hgrc] (http://www.selenic.com/mercurial/hgrc.5.html#hooks) rằng tất cả trước/sau móc có $ HG_PATS và $ HG_OPTS. –

1

Có một móc hậu móc. Nó được gọi là post-clone (manpage HGRC cho thấy một post-ANYCOMMANDpre-ANYCOMMAND tồn tại) mặc dù khi bạn chỉ ra bạn cũng có thể sử dụng *changegroup hoặc update móc quá, vì bản sao sử dụng cả những chức năng (trừ khi bạn ngăn chặn cập nhật với -U).

Còn về việc thêm --localtag để bạn có tên chứ không phải tên thay đổi phụ nếu bạn cần nó để tham khảo. Một cái gì đó như

hg clone -r tagname URL 
hg tag --local tagname 

mà bạn có thể dễ dàng xây dựng thành bí danh vỏ. Ngoài ra, không cần phải bảo đảm là một cách để sửa đổi X và sửa đổi mà bản sửa đổi X được gắn thẻ mà không có các bản sửa đổi khác mà bạn không muốn vì thẻ có thể đã được áp dụng sau khi công việc khác được thực hiện. Bạn có thể, tất nhiên, luôn luôn cập nhật thành 'X' và có các thay đổi tiếp theo trong thư mục làm việc của bạn, nhưng chúng vẫn nằm trong repo của bạn.

Thành thật mà nói, một khi tôi đã tìm ra rằng tên thẻ không đến một thời gian dài khi bạn sao chép vào một thẻ, thứ mà tôi thừa nhận nhầm lẫn với tôi lúc đầu, tôi không thấy cần phải mang theo changeset với thẻ trong đó.

+0

Cảm ơn vì móc hậu móc. Tôi đã xóa "và vì không có móc" postclone' "từ câu hỏi. Tôi không hoàn toàn thích thẻ địa phương vì tôi sẽ kéo thẻ thay đổi một thời gian sau đó. Cũng không có thẻ changeset, tôi có thể tự mình gắn thẻ, sau đó tôi sẽ phải hợp nhất các thẻ. –

+0

Vâng, nó không hoàn hảo nhưng không có cách nào để làm điều đó w/o kéo changesets bổ sung mà bạn có thể chưa muốn (tất cả những người giữa công việc và cset gắn thẻ). Ít nhất thẻ hợp nhất liền mạch và địa phương không thể xung đột hoặc bị đẩy. –

+0

Tôi sẽ chỉ kéo thẻ changeset nếu đó là con duy nhất của thẻ được gắn thẻ. Câu trả lời của @ Richard đã cho tôi ý tưởng để sử dụng một móc trước khi sao chép và kéo trước để kiểm tra trường hợp và thay đổi bản sao/kéo sửa đổi để thay đổi thẻ. Sẽ đăng lại. –

3

Bạn muốn có bản hack khổng lồ với bash và tập lệnh Perl được nhúng? À, đây rồi ...

#!/bin/bash 
if [[ "$1" == "" || "$2" == "" || "$3" == "" ]]; then 
    echo 'hgclonetag <src> <tgt> <tag>' 
    exit 1; 
fi 

REV=`hg log -R $1 --rev $3: --limit=2 | perl -F: -lane 'if (/:([\dA-Fa-f]+)$/) {print $F[2] if defined($flag);$flag=1;}'` 
hg clone --rev $REV $1 $2 

này sẽ khởi chạy hg log lệnh để trích xuất các revision number sau sửa đổi tag liên quan đến đầu tiên và sau đó nhái để sửa đổi này.

Hiện tại, tính năng này không hoạt động trên các bản repos từ xa: -R chuyển đổi chỉ hoạt động trên repos địa phương.

+3

Tôi chắc chắn sẽ chấp nhận nó nếu bạn không bao gồm một cách rõ ràng những từ git-tish như "khổng lồ", "hack" (oops, tôi vừa xúc phạm Chúa Linus? * Thu thập sấm sét từ xa ... *), "bash", và "perl". Tôi hy vọng cho một nhỏ, thanh lịch, hg dựa trên, python giải pháp :) 1 Tuy nhiên. –

+1

Nên đơn giản để Python hóa việc này bằng cách sử dụng 'os.system' và một số đối sánh cụm từ thông dụng. Nice bình luận: 1 mình! –

+2

Điều này sẽ không hoạt động khi bạn gắn thẻ một bản sửa đổi cũ ... nếu tôi làm 'hg tag -r 100 foo', thì tôi có thể đang tạo bản sửa đổi 1000. Vì vậy, tìm nạp bản sửa đổi 101 sẽ không đưa vào thẻ. –

3

Tôi càng nghĩ về nó tôi càng tin chắc câu trả lời đúng là chỉ cần sao chép tất cả mọi thứ và cập nhật cho các thẻ, có thể được thực hiện trong một bước duy nhất:

hg clone http://host/path#tagname 

Đó được bạn tất cả mọi thứ và sau đó làm hg update để tagname đặt thư mục làm việc của bạn để sửa đổi chính xác. Cho nén đồng bằng mà không nhất thiết phải lớn hơn nhiều, và nếu nó là bạn có thể tự động sao chép phần lớn của nó từ một bản sao cục bộ trước đó.

+0

Cảm ơn, tôi không biết tôi cũng có thể sử dụng #. Tuy nhiên vấn đề là, như câu hỏi của tôi nói, không có thẻ changeset trong bản sao, vì vậy tôi không biết tại đó thẻ là bản sao. –

+0

Huh? Có vẻ như bạn biết tên và tên đó là 'foo'. Vì vậy, bạn có thể làm 'hg clone http: // host/path # foo'. Nếu bạn thực sự không biết tên của thẻ, bạn nên sao chép tất cả mọi thứ và sau đó cập nhật - không có hại trong việc có thêm vòng quay trong repo của bạn nhưng không phải là thư mục làm việc của bạn. –

+0

Xin lỗi tôi có nghĩa là "tại đó thẻ ** bản sao ** là", vì bản sao không có thẻ thay đổi 'foo'. Tất nhiên tôi biết ngay sau bản sao, nhưng không phải sau một thời gian (tôi có trí nhớ ngắn hạn khủng khiếp). Như bạn nói, làm một bản sao đầy đủ sau đó cập nhật là một giải pháp rõ ràng, và tôi luôn luôn làm điều đó anyway. Nó chỉ là ngữ nghĩa 'clone parent # foo' cảm thấy hơi kỳ lạ mà không cần thay đổi thẻ. –

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