2012-02-23 28 views
10

Trong công việc git ngày-to-ngày của tôi, tôi có nhiều chi nhánh chủ đề, như vậy:Git: duy trì nhiều chi nhánh chủ đề trên cơ sở thường xuyên di chuyển

 
       o--o--o (t2) 
      /
     o--o (t1) 
     /
o--o--o (master) 
     \ 
     o--o--o (t3) 

Khi tôi kéo từ thượng nguồn,

 
       o--o--o (t2) 
      /
     o--o (t1) 
     /
o--o--o--n--n--n (master) 
     \ 
     o--o--o (t3) 

tôi muốn rebase tất cả các chi nhánh chủ đề của tôi trên đầu trang của chủ mới:

 
         o'--o'--o' (t2) 
        /
        o'--o' (t1) 
       /
o--o--o--n--n--n (master) 
       \ 
        o'--o'--o' (t3) 

Hiện tại tôi làm điều này bằng tay, sử dụng git rebase --onto. Trong trường hợp này, toàn bộ quá trình cập nhật sẽ là:

$ git checkout master 
$ git pull 
$ git rebase master t1 
$ git rebase --onto t1 t2~3 t2 
$ git rebase master t3 

Điều này thậm chí còn tăng lên khi nhảy giữa các nhánh chủ đề khác nhau và thêm cam kết.

Sự phụ thuộc giữa các nhánh chủ đề trong trường hợp của tôi hoàn toàn giống như cây: không nhánh nào phụ thuộc vào nhiều hơn một nhánh khác. (Tôi phải cuối cùng cập nhật các bản vá lỗi phụ thuộc vào một số thứ tự cụ thể, vì vậy tôi chọn thứ tự ưu tiên đó.)

Có công cụ nào có thể giúp tôi quản lý quy trình làm việc này không? Tôi đã thấy TopGit, nhưng dường như nó được gắn khá nhiều với luồng công việc dựa trên email tg patch, điều này không liên quan đến tôi.

+0

Tại sao các bạn rebasing 't2' vào 'master' thay vì chỉ rebasing nó vào' t1', như bạn thấy trong biểu đồ của bạn? Tương tự, với 't3', cờ' --onto' không phù hợp. –

+0

Ngoài ra, hãy xem câu hỏi [chi nhánh git rebase với tất cả các nhánh con] (http://stackoverflow.com/q/2730866/112968) – knittl

+0

Kevin: Rất tiếc, có - typo :) – nornagon

Trả lời

4

Khá nhiều câu hỏi tương tự đã được hỏi về danh sách git chỉ gửi thư: Rebasing Multiple branches at once... Các phản ứng liên kết đã một kịch bản perl kèm theo mà tạo ra các lệnh bạn sẽ cần .

Nếu bạn muốn tập lệnh này chạy nhanh và tránh để chữ chạy trên ngón chân, hãy cân nhắc sử dụng git-new-workdir để thiết lập bản sao làm việc chỉ để tự động rebasing.

Nếu bạn thấy mình giải quyết các xung đột tương tự nhiều lần, hãy xem xét bật git rerere.

Có nói tất cả những gì, đây là một công thức thay thế:

# Construct a placeholder commit that has all topics as parent. 
HEADS="$(git for-each-ref refs/heads/\*)" && 
MAGIC_COMMIT=$(echo "Magic Octopus"$'\n\n'"$HEADS" | 
    git commit-tree \ 
    $(git merge-base $(echo "$HEADS" | sed 's/ .*//'))^{tree} \ 
    $(echo "$HEADS" | sed 's/ .*//;s/^/-p /')) && 
git update-ref refs/hidden/all $MAGIC_COMMIT 

# Rebase the whole lot at once. 
git rebase --preserve-merges master refs/hidden/all 

# Resolve conflicts and all that jazz. 

# Update topic refs from the rebased placeholder. 
PARENT= 
echo "$HEADS" | 
while read HASH TYPE REF 
do 
    let ++PARENT 
    git update-ref -m 'Mass rebase' "$REF" refs/hidden/all^$PARENT "$HASH" 
done 
+1

Tuyệt vời, cảm ơn! : D Tôi đã sử dụng một phiên bản được sửa đổi đôi chút của kỹ thuật này để tạo một tập lệnh mà chỉ khởi động lại một cây con: https://github.com/nornagon/git-rebase-all – nornagon

+0

Lý do bỏ phiếu xuống? –

-2

Không rebase. Bắt đầu các tính năng của bạn từ một điểm chung. Hợp nhất là cách ít hoạt động cuối cùng.

Đây là những gì chúng tôi làm:

http://dymitruk.com/blog/2012/02/05/branch-per-feature/

+0

Thật tuyệt, nhưng tôi đang tích hợp với quy trình làm việc Chromium, tuyến tính. Các nhánh chủ đề này chỉ là địa phương, nhỏ (thường là 1-5 commit mỗi cái) và ngắn ngủi. – nornagon

+0

Ồ, đây là một bài viết hay để đọc. +1 Lời khuyên hợp lý về việc rebasing là tốt, mặc dù sẽ có lý do để làm như vậy trong những trường hợp cụ thể. – jupp0r

+0

@nornagon trong luồng công việc tôi đã phác thảo, nó áp dụng cho các tính năng nhỏ. Không có sự khác biệt.Việc hợp nhất tốt hơn nói chung vì bạn sẽ xem xét các thay đổi mã và nơi chúng đến từ việc bao gồm các tệp di chuyển. –

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