2011-05-16 22 views
8

Tôi đang sử dụng chi nhánh default để phát triển liên tục và bây giờ sẽ tạo nhánh mới có tên để đánh dấu bản phát hành. Mọi sự phát triển hơn nữa sẽ được chi nhánh mặc định, tất cả các sửa lỗi sản xuất sẽ được thực hiện trên một mới (với hợp nhất tiếp theo để default), như thế này:Mercurial: cho phép hợp nhất từ ​​nhánh phát hành vào nhánh mặc định, nhưng không ngược lại

#>hg branches 
    aristotle 42:dbd... 
    default  41:da5... 
#>hg branch 
    default 
#>echo "Feature #1 for the next release" >> feature1.txt 
#>hg add 
#>hg commit -m "Implement feature #1 for the next release" 

...... eek, need to make an urgent fix on Production ..... 

#>hg update aristotle 
#>echo "Fixed urgent bug #123 on Production" >> fix123.txt 
#>hg add 
#>hg commit -m "Fixed bug #123 on Production" 
    created new head 
#>hg update default 
#>hg merge aristotle 
    1 files updated, 0 files merged, 0 files removed, 0 files unresolved 
    (branch merge, dont forget to commit) 
#>hg commit -m "Merge in the fix for bug #123" 
#>hg push 

này dường như trên con đường để đi, tuy nhiên có vẻ như dễ dàng làm hỏng mọi thứ và hợp nhất theo cách khác xung quanh (từ default đến aristotle có nghĩa là tất cả các tính năng mới sẽ xuất hiện trong chi nhánh sản xuất).

Có thể nỗi sợ hãi của tôi là vô căn cứ vì người ta sẽ nhận thấy sự lộn xộn trước khi đẩy cam kết vào repo trung tâm, nhưng tôi muốn xem liệu có thể làm cho phương pháp tiếp cận dễ dàng hơn không.

Vì vậy, tôi bắt đầu nhìn vào lưỡi câu:

[hooks] 
pretxnchangegroup.branch = hg heads --template "{branches} " | find "aristotle" && exit 1 || exit 0 

..nhưng sau đó nhận ra nó không phải là những gì tôi cần, vì điều này sẽ không cho phép tôi để đẩy những thay đổi Aristotle ở tất cả.

Vì vậy, tôi không biết phải làm gì. Lý tưởng nhất, tôi muốn các nhà phát triển thấy thông báo "hợp nhất cách sai" khi họ cố gắng hợp nhất từ ​​default đến aristotletại địa phương (rõ ràng, cần có một kiểm tra kép trên repo trung tâm), trong khi hợp nhất từ ​​chi nhánh sản xuất đến mặc định là có thể.

Cảm ơn!

+0

Có lẽ bạn có thể làm điều gì đó nếu cam kết nằm trên nhánh sản xuất, và cam kết đó có nhiều hơn một phụ huynh (một cam kết hợp nhất), và một trong những phụ huynh đó là nhánh mặc định, thất bại. Bạn có thể muốn xem xét phần mở rộng có chứa để giúp một số điều này: http://mercurial.selenic.com/wiki/ContainsExtension Chúng tôi không có bất kỳ biện pháp bảo vệ thực sự nào chống lại điều này, nhưng chúng tôi có một móc hậu cam kết in ra những gì thực sự đã xảy ra trong quá trình commit (bạn đang hợp nhất branch1 vào branch2), mà nhà phát triển có thể đọc để xác minh rằng họ đã làm đúng. –

+0

Đánh dấu, cảm ơn nhiều nhận xét nhưng "hg update default" theo sau là "hg merge aristotle" có vẻ giống như "merging branch1 into branch2" (và than ôi, một thông điệp không ngăn cản push/commit sai). Ngoài ra tôi không chắc làm thế nào mà "có phần mở rộng" có thể giúp đỡ trong trường hợp của tôi: (Có lẽ bạn có thể xây dựng trên làm thế nào bạn chính xác thực hiện móc hậu cam kết của bạn? – andreister

+0

Hook sau cam kết của tôi không thực sự ngăn chặn bất cứ điều gì xảy ra, nhưng Nó giống như khi bạn đọc một số điện thoại cho ai đó và sau đó yêu cầu họ đọc lại cho bạn để đảm bảo rằng họ hiểu bạn. và sau đó mercurial giải thích các hành động lại cho bạn, do đó bạn có cơ hội để nắm bắt một sai lầm –

Trả lời

0

này là khá nhiều một bản sao chính xác của một câu hỏi từ một vài ngày trước Ensuring a merge between branches happens in one direction

nhưng tôi không thích câu trả lời của tôi cho rằng một trong, vậy làm thế nào về vấn đề này một:

Giữ nhái riêng cho các bản phát hành trước đây. Khi nào, trong ví dụ của bạn ở trên, bạn quyết định bạn cần phải làm một sửa chữa khẩn cấp trên Aristotle làm điều này thay vì:

cd .. 
hg clone -r aristotle myrepo myrepo-aristotle 

sau đó bạn có một bản sao chỉ với Aristotle trong đó và bạn có thể không vô tình kết hợp nó để mặc định trong bản sao đó.

Điều đó nói rằng, nó vẫn không phải là một câu trả lời tuyệt vời. Sự an ủi thực sự duy nhất là nếu bạn nhập vào một hướng mà bạn không thích bạn luôn có thể sao chép hai đầu và hợp nhất theo một hướng khác.

+0

Vâng, tôi xem. Cảm ơn. Vấn đề là, tôi quyết định đi cho các chi nhánh thay vì nhân bản, ngay từ đầu :) Vẫn muốn thử một lần .. Bạn có nghĩ "pretxncommit" có thể giúp đỡ không? – andreister

+0

Bạn ccan sử dụng các nhánh vô danh, nhái-như-chi nhánh, và các chi nhánh có tên trong bất kỳ sự kết hợp nào, do đó, không quá muộn. Chỉ cần làm lệnh clone tôi đưa ra ở trên và bạn sẽ có một bản sao với chỉ có tên của chi nhánh đầu trong nó, vì vậy bạn không thể vô tình hợp nhất theo cách khác. Một hook pretxncommit có thể làm chậm bạn xuống, nhưng bạn không thể lưu trữ nó trong kho lưu trữ (.hg/hgrc không được nhân bản) để người khác sẽ chỉ phạm sai lầm cho bạn. –

0

Tôi đã tìm thấy câu hỏi này trong khi tìm kiếm giải pháp cho một vấn đề liên quan, tôi biết câu hỏi cũ của nó, nhưng tôi nghĩ tôi sẽ chia sẻ giải pháp của mình.

Chúng tôi có các nhánh phát hành được gọi là release-x.y.z và phát triển liên tục theo mặc định. Chúng tôi sử dụng móc dựa trên ví dụ precommit_badbranch_badmerge được tìm thấy tại https://www.mercurial-scm.org/wiki/HookExamples. Về cơ bản, chúng tôi trích xuất số phiên bản cho từng chi nhánh liên quan đến bất kỳ hợp nhất nào và đảm bảo rằng nó đang đi đúng hướng (mặc định được coi là 9999.9999.9999 bất kỳ thứ gì không phải là bản phát hành hoặc nhánh mặc định được -1, -1 , -1 (có thể được hợp nhất vào bất kỳ thứ gì)

Lưu ý rằng điều này chỉ thực hiện kiểm tra 'ngay lập tức' đơn giản. Nó không bắt gặp vấn đề khi ai đó hợp nhất từ ​​chi nhánh blah sang nhánh phát hành.Một lưu ý phụ, chúng tôi cũng có chính sách hợp nhất mặc định phải được đẩy cùng lúc với thay đổi ban đầu trên nhánh phát hành, điều này tránh người khác phải thực hiện hợp nhất để hợp nhất thay đổi - đó là thực thi rằng tôi đang tìm kiếm một giải pháp cho.

Lưu ý, bạn gọi này bằng cách sử dụng móc phần của máy chủ/repo trung ương

[hooks] 
pretxnchangegroup.prevent_bad_merges = python:<path_to_hook>\prevent_bad_merges.py:prevent_bad_merges 

python móc dưới đây:

# based on precommit_badbranch_badmerge 
# at https://www.mercurial-scm.org/wiki/HookExamples 
import re 

# this isnt a proper compare, it will just return numbers > 0 if source is after target 
def compare_versions(source_version, target_version): 
    # if either side is -1, ignore it 
    if (source_version[0] == -1) or (target_version[0] == -1): 
     return 0; 

    if source_version[0] > target_version[0]: 
     return 1 
    elif source_version[0] == target_version[0]: 
     if source_version[1] > target_version[1]: 
      return 2 
     elif source_version[1] == target_version[1]: 
      if source_version[2] > target_version[2]: 
       return 3   
    return 0 

def get_version(branch): 
    if branch == 'default': 
     major=9999 
     minor=9999 
     revision=9999   
    else:  
     # note python uses ?P for named matches 
     match = re.match('(release-(?P<major>\d)\.(?P<minor>\d)\.(?P<revision>\d))', branch) 
     if match: 
      major = int(match.group('major')) 
      minor = int(match.group('minor')) 
      revision = int(match.group('revision')) 
     else: 
      major = -1 
      minor = -1 
      revision = -1 

    return [major,minor,revision] 

def prevent_bad_merges(ui, repo, node, **kwargs): 
    ui.debug("in hook\n") 
    for rev in xrange(repo[node].rev(), len(repo)): 
     ui.debug("in loop\n") 
     # get context (change) 
     ctx = repo[rev] 
     ui.debug("got ctx\n") 
     if len(ctx.parents()) > 1: 
      ui.debug("got a merge\n") 
      branch = ctx.branch() 
      ui.debug(branch +"\n") 
      parent1 = ctx.parents()[0] 
      ui.debug("got parent1\n") 
      parent2 = ctx.parents()[1] 
      ui.debug("got parent2\n") 

      target_branch = repo[parent1.node()].branch() 
      ui.debug("got parent1 branch\n") 
      target_version = get_version(target_branch) 
      ui.debug("got parent1 version\n") 

      source_branch = repo[parent2.node()].branch() 
      ui.debug("got parent2 branch\n") 
      source_version = get_version(source_branch) 
      ui.debug("got parent2 version\n") 

      # This could happen if someone does 
      # hg update 1.1-branch 
      # hg branch 1.2-branch 
      # hg merge 1.0-branch 
      # which is a strange thing to do. So disallow it. 
      if target_branch != branch: 
       ui.warn('PREVENT BAD MERGE HOOK FAILED : \n' 
         'merging to a different branch from first parent ' 
         'is just weird: please don\'t do that\n') 
       return True 

      ui.debug(source_branch, "\n") 
      ui.debug(str(source_version[0]), "\n") 
      #ui.debug("major:", source_version[0], "\n") 
      #ui.debug("minor:", source_version[1], "\n") 
      #ui.debug("revn :", source_version[2], "\n") 

      ui.debug(target_branch, "\n") 
      ui.debug(str(target_version[0]), "\n") 
      #ui.debug("major:", target_version[0], "\n") 
      #ui.debug("minor:", target_version[1], "\n") 
      #ui.debug("revn :", target_version[2], "\n") 

      # Check for backwards merge. 
      if compare_versions(source_version, target_version) > 0: 
       ui.warn('PREVENT BAD MERGE HOOK FAILED : \n' 
         'invalid backwards merge from %r to %r\n' 
         % (source_branch, target_branch)) 
       return True 
     else: 
      ui.debug("Not a merge\n") 
      # Not merging: nothing more to check. 


    return False 
1

này nên làm điều đó. Nó sử dụng số revset query để tìm bất kỳ hợp nhất nào vào aristotle từ default.

hg log -r 'children(p2(::aristotle and ::default and merge()) and branch(default)) and branch(aristotle)' 
  • ::aristotle and ::default and merge() tìm tất cả các ô hợp nhất là tổ tiên của cả hai aristotledefault chi nhánh
  • p2(...) and branch(default) lấy phụ huynh thứ hai (changeset đến) đó là trên cành default.
  • children(...) and branch(aristotle) sau đó lấy bộ thay đổi hợp nhất thực tế nằm trên chi nhánh aristotle.

I recently needed to figure this out myself mà còn cần thiết để đảm bảo rằng default không gián tiếp sáp nhập vào chi nhánh phát hành của tôi, ví dụ mặc định -> Tính năng -> phát hành.

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