Cập nhật chi nhánh Git từ chủ


674

Tôi mới sử dụng Git và hiện tại tôi đang ở trong tình huống này:

  • Tôi có bốn nhánh (chủ, b1, b2 và b3).
  • Sau khi tôi làm việc trên b1-b3, tôi nhận ra rằng tôi có một cái gì đó để thay đổi trên nhánh chủ nên có trong tất cả các nhánh khác.
  • Tôi đã thay đổi những gì tôi cần mastervà ... đây là vấn đề của tôi:

Làm cách nào để cập nhật tất cả các chi nhánh khác với mastermã chi nhánh?


3
Tôi tìm thấy câu trả lời của mình ở đây: Làm thế nào để bạn hợp nhất các tệp chọn lọc với git-merge?
wjandrea

58
Một nhiệm vụ đơn giản khác đã gây khó khăn cho Git. Các nhà phát triển Git nên sử dụng Stack Overflow làm phản hồi trong vòng SDLC của họ. 300.000 người nên chỉ ra điều gì đó sai nghiêm trọng với quy trình làm việc của Git. Họ cần phải thuê một chuyên gia về UX bởi vì họ rõ ràng không thể tự mình git nó.
jww

Câu trả lời:


619

Bạn có hai lựa chọn:

Đầu tiên là hợp nhất, nhưng điều này tạo ra một cam kết bổ sung cho hợp nhất.

Thanh toán từng chi nhánh:

git checkout b1

Sau đó hợp nhất:

git merge origin/master

Sau đó đẩy:

git push origin b1

Ngoài ra, bạn có thể thực hiện một rebase:

git fetch
git rebase origin/master

14
Tôi có một mối quan tâm về phương pháp này. Khi tôi chạy git log --graph, biểu đồ hiển thị bản gốc thực sự được hợp nhất với nhánh chủ đề. Điều này sẽ gây ra bất kỳ vấn đề trong thời gian dài? Tôi nghĩ cách thực hành tốt nhất là luôn hợp nhất nhánh chủ đề trở lại thành chủ. Hãy bình luận.
Patrick

2
Hãy xem xét vấn đề này nếu bạn đang thực hiện quy trình hợp nhất: randyfay.com/node/89
Hampus Ahlgren

22
Bạn đang sáp nhập chủ vào b1. Tại sao bạn got push origin master... không có ý nghĩa. Bạn không thay đổi chi nhánh chính. Tôi nghĩ đó là một sai lầm với 119 upvote: /
Yves Lange

22
Không sử dụng phương thức hợp nhất, sử dụng git rebase masterlà câu trả lời đúng
Weston Ganger

6
Đối với những người trong chúng ta đọc sau - mối quan tâm của @Kursion về lỗi đánh máy đã được giải quyết bằng bản chỉnh sửa của tác giả. Ngoài ra, câu trả lời nâng cao thứ hai dưới đây về cơ bản giống như câu trả lời này nhưng với sơ đồ cấu trúc nhánh và cảnh báo về lý do tại sao bạn không muốn phản ứng.
beyondtheteal

494

Về cơ bản, bạn có hai tùy chọn:

  1. Bạn hợp nhất. Điều đó thực sự khá đơn giản và một hoạt động hoàn toàn cục bộ:

    git checkout b1
    git merge master
    # repeat for b2 and b3
    

    Điều này để lại lịch sử chính xác như nó đã xảy ra: Bạn rẽ nhánh từ chủ, bạn đã thực hiện thay đổi cho tất cả các chi nhánh và cuối cùng bạn kết hợp các thay đổi từ chủ vào cả ba nhánh.

    gitcó thể xử lý tình huống này thực sự tốt, nó được thiết kế để hợp nhất xảy ra theo mọi hướng, cùng một lúc. Bạn có thể tin tưởng rằng nó có thể có được tất cả các chủ đề với nhau một cách chính xác. Nó chỉ đơn giản là không quan tâm đến việc b1hợp nhất chi nhánh master, hoặc masterhợp nhất b1, cam kết hợp nhất trông giống như git. Sự khác biệt duy nhất là, nhánh nào kết thúc chỉ vào cam kết hợp nhất này.

  2. Bạn nổi loạn. Những người có SVN hoặc nền tương tự tìm thấy điều này trực quan hơn. Các lệnh tương tự như trường hợp hợp nhất:

    git checkout b1
    git rebase master
    # repeat for b2 and b3
    

    Mọi người thích cách tiếp cận này vì nó giữ lại một lịch sử tuyến tính trong tất cả các chi nhánh. Tuy nhiên, lịch sử tuyến tính này là một lời nói dối, và bạn nên biết rằng nó là. Xem xét biểu đồ cam kết này:

    A --- B --- C --- D <-- master
     \
      \-- E --- F --- G <-- b1
    

    Kết quả hợp nhất trong lịch sử thực sự:

    A --- B --- C --- D <-- master
     \                 \
      \-- E --- F --- G +-- H <-- b1
    

    Cuộc nổi loạn, tuy nhiên, cung cấp cho bạn lịch sử này:

    A --- B --- C --- D <-- master
                       \
                        \-- E' --- F' --- G' <-- b1
    

    Vấn đề là, rằng các cam kết E', F'G'không bao giờ thực sự tồn tại, và đã có thể không bao giờ được thử nghiệm. Họ thậm chí có thể không biên dịch. Thực sự khá dễ dàng để tạo ra các cam kết vô nghĩa thông qua một rebase, đặc biệt là khi những thay đổi masterquan trọng đối với sự phát triển trong b1.

    Hậu quả của việc này có thể được, mà bạn không thể phân biệt đó trong ba cam kết E, FGthực sự đã giới thiệu một hồi quy, giảm dần giá trị của git bisect.

    Tôi không nói rằng bạn không nên sử dụng git rebase. Nó có công dụng của nó. Nhưng bất cứ khi nào bạn sử dụng nó, bạn cần phải nhận thức được thực tế rằng bạn đang nói dối về lịch sử. Và ít nhất bạn nên biên dịch thử nghiệm các cam kết mới.


Tôi đã hợp nhất một nhánh nguồn khác (không phải chủ) và các bước bổ sung để thêm vào câu trả lời hay này là cập nhật nó trên repo cục bộ của tôi trước khi hợp nhất (để có mã mới nhất cục bộ) : git checkout <source branch> git pull. Sau đó tiếp tục với phần trên: git checkout b1...
Rod

3
Là người dùng SVN lâu năm, tôi thích tùy chọn hợp nhất với rebase: sử dụng bất kỳ phiên bản điều khiển nào, điều rất quan trọng là phải giữ hồ sơ chính xác về những thay đổi bạn đã thực hiện và tại sao. Tôi có thể thấy sự hấp dẫn của rebase để đơn giản hóa lịch sử rõ ràng, nhưng sau đó bạn nên quay lại và thêm vào các nhận xét cam kết của E ', F', G '- và tốt nhất là tự động thêm rebase vào các bình luận đó. Mặt khác, nếu quá trình xây dựng / kiểm tra / triển khai thử nghiệm bị hỏng trên G ', bạn phải tìm ra lý do tại sao các thay đổi được thực hiện mà không có thông tin đầy đủ.
WillC

12
Lịch sử là một lời nói dối
cướp biển

Cảm ơn tôi sử dụng "git merge any-Branch-name" để hợp nhất một mã nhánh với một nhánh khác. Tại địa phương tôi có thể kiểm tra mã của chi nhánh 1 trong khi tôi ở chi nhánh 2
Priti

1
@blamb Xung đột hợp nhất xảy ra với cả hai git mergegit rebase. Không có cách nào tránh khỏi những điều đó. git rebasecó lợi thế là cho phép bạn ẩn một số giai đoạn nổi loạn (nghĩa là khởi động lại cùng một nhánh vào một số cam kết khác nhau theo trình tự để giảm số lượng xung đột trong từng giai đoạn). Tuy nhiên, thực tế là một cuộc nổi loạn đang nói dối về lịch sử làm cho nó dễ dàng hơn rất nhiều trong một cuộc nổi loạn nhiều tầng như vậy ... Đó là lý do tại sao tôi luôn thích hợp nhất, ngay cả khi điều đó có nghĩa là tôi cần phải làm lộn xộn lịch sử với một số cam kết hợp nhất .
cmaster - phục hồi monica

238

git rebase masterlà cách thích hợp để làm điều này. Hợp nhất sẽ có nghĩa là một cam kết sẽ được tạo ra để hợp nhất, trong khi việc đánh lại thì không.


52
Điều gì về khi bạn đã được đẩy về nguồn gốc, nếu bạn nổi loạn, bạn sẽ viết lại lịch sử cam kết và điều này sẽ xung đột với chi nhánh từ xa của bạn. Tôi nghĩ rebase chỉ nên được sử dụng khi kéo hoặc khi bạn không bị đẩy đến một nhánh xa.
Matt Smith

6
Nếu bạn là người duy nhất làm việc trên nhánh từ xa, bạn có thể thực hiện tính năng gốc git push --force để cập nhật nhánh từ xa của mình với nhánh cục bộ bị từ chối. stackoverflow.com/questions/8939977/ cường
bão

7
rebase và hợp nhất cả hai công trình, rebase là tốt nhất cho các nhánh riêng, bởi vì nó cho một biểu đồ lịch sử sạch hơn. câu trả lời này là tốt nhất
Junchen Liu

5
Cần phải rõ ràng hơn về sự đánh đổi giữa sự rõ ràng (tuyệt vời cho người dùng đơn lẻ hoặc nhóm nhỏ) hoặc sự thật lộn xộn (đối với các nhánh mã nhiều người đóng góp - cần thiết cho khả năng duy trì (theo kinh nghiệm của tôi - YMMV)).
WillC


53

Nếu bạn đã và đang làm việc trên một chi nhánh, hoặc rất nhiều điều đã xảy ra ở các chi nhánh khác trong khi bạn đang làm việc gì đó, tốt nhất là bạn nên từ chối chi nhánh của mình thành chủ nhân. Điều này giữ cho lịch sử gọn gàng và làm cho mọi thứ dễ dàng hơn để làm theo.

git checkout master
git pull
git checkout local_branch_name
git rebase master
git push --force # force required if you've already pushed

Ghi chú:

  • Đừng từ chối các chi nhánh mà bạn đã cộng tác với những người khác.
  • Bạn nên rebase trên nhánh mà bạn sẽ hợp nhất mà không phải lúc nào cũng là chủ.

Có một chương về việc nổi loạn tại http://git-scm.com/book/ch3-6.html và vô số tài nguyên khác trên mạng.


Cảm ơn giải pháp đơn giản
anh chàng cao lớn khác

18

@cmaster đã đưa ra câu trả lời công phu nhất. Tóm lại:

git checkout master #
git pull # update local master from remote master
git checkout <your_branch>
git merge master # solve merge conflicts if you have`

Bạn không nên viết lại lịch sử chi nhánh thay vào đó giữ chúng ở trạng thái thực tế để tham khảo trong tương lai. Trong khi hợp nhất với chủ, nó tạo thêm một cam kết nhưng đó là giá rẻ. Cam kết không mất phí.


13

Để cập nhật các nhánh khác như (sao lưu) với bản sao nhánh chính của bạn. Bạn có thể làm theo một trong hai cách (rebase hoặc merge) ...

  1. Thực hiện rebase (sẽ không có bất kỳ cam kết bổ sung nào được thực hiện cho nhánh dự phòng).
  2. Hợp nhất các nhánh (sẽ có một cam kết bổ sung tự động cho nhánh dự phòng).

    Lưu ý: Rebase không là gì ngoài việc thiết lập một cơ sở mới (một bản sao mới)

git checkout backup
git merge master
git push

(Lặp lại cho các chi nhánh khác nếu có như backup2 & vv ..,)

git checkout backup
git rebase master
git push

(Lặp lại cho các chi nhánh khác nếu có như backup2 & vv ..,)


9

Bạn có thể hợp nhất hoặc bạn có thể áp dụng các cam kết riêng lẻ trên các chi nhánh bằng cách sử dụng git cherry-pick .


1

Có hai lựa chọn cho vấn đề này.

1) git rebase

2) hợp nhất git

Chỉ khác với ở trên cả hai trong trường hợp hợp nhất, sẽ có thêm cam kết trong lịch sử

1) chi nhánh kiểm tra git (b1, b2, b3)

2) git rebase origin / master (Trong trường hợp có xung đột giải quyết cục bộ bằng cách thực hiện git rebase --continue)

3) git đẩy

Ngoài ra, tùy chọn hợp nhất git là thời trang tương tự

1) kiểm tra git "your_branch" (b1, b2, b3)

2) git merge master

3) git đẩy


0

để cập nhật chi nhánh của bạn từ chủ:

  git checkout master
  git pull
  git checkout your_branch
  git merge master
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.