2009-05-14 36 views
51

Tôi có một nhánh chính trong dự án của mình, mà tôi sử dụng để kéo các thay đổi từ những người khác. Từ đó, tôi thường có một số nhánh chủ đề mà tôi hiện đang làm việc.Git: Làm thế nào để rebase nhiều nhánh (với cùng một commit cơ bản) cùng một lúc?

Câu hỏi của tôi là: Có cách nào để tôi kéo các thay đổi mới vào chủ của mình và sau đó rebase TẤT CẢ các nhánh chủ đề của tôi vào cùng một lúc không?

Đây là tình hình:

 D--E topic1 
    /
A--B--C master 
     \ 
     F--G topic2 

Và tôi muốn thực hiện điều này với một lệnh duy nhất (H đến từ thượng nguồn):

 
       D'--E' topic1 
      /
    A--B--C--H master 
       \ 
       F'--G' topic2 

Bây giờ, tôi biết tôi có thể thực hiện điều này bằng cách rebasing topic1 và topic2 vào master, và tôi thậm chí có thể viết một kịch bản để tự động hóa điều này. Nhưng nếu tôi có một số chi nhánh khác, tạo ra những cái mới và xóa những người khác thường xuyên và tôi nhận được những thay đổi ngược dòng tất cả các thời gian?

Thao tác này (một số lần rebases), khi thực hiện bằng tay, vừa mệt mỏi vừa dễ xảy ra lỗi.

Có cách nào dễ dàng hơn không?

Cảm ơn!

+1

[câu hỏi này mới hơn] (http://stackoverflow.com/questions/5600659/rebasing- a-branch-includ ing-all-its-children/5600770 # 5600770) có lẽ là một bản sao, nhưng tôi không chắc chắn nó đã bao giờ thực sự bị đóng như là một bản sao của một câu hỏi cũ mà không có một câu trả lời thực sự. – Cascabel

+1

Xem thêm [cách tôi muốn rebase toàn bộ tiểu sử - một số chi nhánh, với một số liên kết giữa chúng tạo thành từ hợp nhất] (http://stackoverflow.com/a/9706495/94687). –

+0

'git rebase --onto' cũng nên được đề cập trong trường hợp' topic1' hoặc 'topic2' có nhánh con https://coderwall.com/p/xzsr9g/rebasing-dependent-branches-with-git – quimnuss

Trả lời

17

Tôi khá chắc chắn rằng không có cách nào để tự động thực hiện việc này. Hãy nhớ rằng "git rebase master" cũng có thể thả bạn trở lại shell cần bạn giải quyết xung đột hợp nhất, vì vậy nếu bạn muốn viết một kịch bản để tự động hóa tất cả điều này, bạn cần phải tính đến điều đó.

Bạn có thể dễ dàng theo dõi các chi nhánh nào cần cập nhật. Hmm, đối với bất kỳ chi nhánh nào, "git rev-list branch..master" sẽ tạo ra kết quả đầu ra nếu nhánh không được cập nhật (tức là chỉ cam kết trên đầu). Vì vậy, bạn cần phải lặp qua tất cả người đứng đầu địa phương, ngoại trừ tổng thể để tạo ra một báo cáo (nb "git show-chi nhánh" sẽ xấp xỉ làm điều này):

git for-each-ref 'refs/heads/*' | \ 
    while read rev type ref; do 
    branch=$(expr "$ref" : 'refs/heads/\(.*\)') 
    revs=$(git rev-list $rev..master) 
    if [ -n "$revs" ]; then 
     echo $branch needs update 
     git diff --summary --shortstat -M -C -C $rev master 
    fi 
    done 

Vì vậy, nếu bạn đang cảm thấy dũng cảm, bạn có thể thay thế mà "git khác "với một cái gì đó như" git checkout $ branch & & git rebase master "(hoặc có thể chỉ" git pull --rebase "nếu bạn đã thiết lập điều đó). Tôi nghĩ rằng sau đó bạn phải kiểm tra sự tồn tại của thư mục ".git/rebase-apply" hoặc kiểm tra chỉ mục cho các tệp chưa được nhúng ("git ls-files -u") để kiểm tra xem chúng ta có đang đợi hợp nhất.

Tất nhiên, nếu không có xung đột, sau đó nó dễ dàng ... nó sản xuất cái gì đó cũng hoạt động khi nó không phải dễ dàng đó là vấn đề: p

Và điều này không nhất thiết phải giải quyết những gì sẽ xảy ra nếu một trong các nhánh của bạn dựa trên cái gì đó khác ... đó là lý do tại sao tôi đã đề cập bằng cách sử dụng "git pull --rebase" thay vào đó, bởi vì điều đó sẽ rebase theo cấu hình chi nhánh, không mù quáng từ chủ. Mặc dù phát hiện không dựa trên cấu hình chi nhánh ... có thể dễ dàng nhất là kiểm tra từng chi nhánh và thực hiện "git pull" và để cấu hình chi nhánh xử lý mọi thứ, bao gồm cả việc rebase hay merge?

+1

Cảm ơn sự trợ giúp ! Tôi đoán đây chỉ là một vấn đề khó khăn hơn tôi nghĩ, vì vậy tôi sẽ tiếp tục bằng cách rebasing thủ công. :) – malvim

+3

Tôi sử dụng 'git branch --no-merged' để liệt kê các nhánh mà tôi muốn mang đến cho chủ mới nhất. – rjmunro

+1

@rjmunro đẹp, tôi không biết về lá cờ đó. Tuy nhiên, tôi không nghĩ rằng nó phù hợp cho trường hợp các chi nhánh của bạn cần rebasing hơn là sáp nhập. – araqnid

7

Bạn luôn có thể chỉ cần viết một vỏ một lót như thế này:

for branch in topic1 topic2 topic3;do git rebase master $branch;done 

Kể từ khi các chi nhánh chủ đề bạn muốn rebase có thể sẽ thay đổi theo thời gian, đây là một-dir nhanh và^H^H^Hflexible giải pháp :-)

+1

Xem [câu trả lời này] (http://stackoverflow.com/a/5632027/396967) với một câu hỏi liên quan cho một phiên bản "thông minh hơn", tự động xác định các nhánh có chứa một cam kết cơ bản cụ thể. – kynan

0

tôi đã quay này thành một kịch bản mạnh mẽ, duy trì trong my git-extensions repository:

$ git-urebaselocalbr --help 
Rebase all/the last committed N local branches (except for the current branch 
and master) to the updated upstream head. 
Usage: git-urebaselocalbr [--continue|--skip|--abort] [--branches "<branch1> ..."] [N] [-i|--interactive] [options] 
Các vấn đề liên quan