Câu hỏi Cách tốt nhất (và an toàn nhất) để hợp nhất một nhánh git vào master


Chi nhánh mới từ master được tạo ra, chúng tôi gọi nó là test.

Có một số nhà phát triển hoặc cam kết master hoặc tạo các chi nhánh khác và sau đó hợp nhất thành master.

Hãy nói về công việc test đang mất vài ngày và bạn muốn tiếp tục giữ test cập nhật với các cam kết bên trong master.

tôi sẽ làm git pull origin master từ test.

Câu hỏi 1: Đây có phải là cách tiếp cận đúng? Các nhà phát triển khác có thể dễ dàng làm việc trên cùng một tệp như tôi đã làm việc btw.


Công việc của tôi trên test được thực hiện và tôi sẵn sàng hợp nhất lại master. Dưới đây là hai cách tôi có thể nghĩ đến:

A: 

git checkout test
git pull origin master
git push origin test
git checkout master
git pull origin test 

B: 

git checkout test
git pull origin master
git checkout master
git merge test

Tôi không sử dụng --rebase bởi vì từ sự hiểu biết của tôi, rebase sẽ nhận được những thay đổi từ master và ngăn xếp mỏ trên đầu trang do đó nó có thể ghi đè lên những thay đổi mà người khác đã thực hiện.

Câu hỏi 2: Phương pháp nào trong hai phương pháp này là đúng? Sự khác biệt ở đó là gì?

Mục tiêu trong tất cả những điều này là giữ cho tôi test chi nhánh được cập nhật với những điều đang diễn ra trong master và sau đó tôi có thể hợp nhất chúng trở lại master hy vọng giữ cho dòng thời gian càng tuyến tính càng tốt.


1467
2018-04-09 00:01


gốc


không .. rebase không bao giờ ghi đè lên, nó chỉ cố gắng để đạt được một lịch sử rõ ràng hơn. bằng cách reattach (hoặc giả) lịch sử đến điểm cuối của thầy - Junchen Liu
rebase không ghi đè các cam kết của bạn. Nó hoàn tác các cam kết của bạn, áp dụng các cam kết trong nhánh chính cho nhánh thử nghiệm của bạn, sau đó áp dụng các cam kết của bạn trở lại để kiểm tra. - zundi
nếu như khi làm git pull origin master bạn nhận được "từ chối hợp nhất lịch sử không liên quan" ... nhưng bạn thực sự cần phải hợp nhất bất cứ điều gì trong chủ vào chi nhánh kiểm tra của bạn (là có thể / thực tế?) - iloveretards


Các câu trả lời:


Làm thế nào tôi sẽ làm điều này

git checkout master
git pull origin master
git merge test
git push origin master

Nếu tôi có một chi nhánh địa phương từ một từ xa, tôi không cảm thấy thoải mái với việc sáp nhập các chi nhánh khác với cái này với điều khiển từ xa. Ngoài ra tôi sẽ không đẩy những thay đổi của tôi, cho đến khi tôi hài lòng với những gì tôi muốn thúc đẩy và tôi cũng sẽ không thúc đẩy mọi thứ, điều đó chỉ dành cho tôi và kho lưu trữ địa phương của tôi. Trong mô tả của bạn, có vẻ như, test chỉ dành cho bạn? Vì vậy, không có lý do để xuất bản nó.

git luôn cố tôn trọng bạn và những người khác thay đổi, và như vậy sẽ --rebase. Tôi không nghĩ rằng tôi có thể giải thích nó một cách thích hợp, vì vậy hãy xem sách Git - Rebasing hoặc là git-ready: Giới thiệu vào rebasing cho một mô tả nhỏ. Đó là một tính năng khá thú vị


2170
2018-04-09 00:45



@ Duncanmoo Vâng, tất nhiên là chi nhánh test phải tồn tại. Chắc chắn, bạn có thể sử dụng hash cam kết thay vào đó, nhưng nó thường dễ dàng hơn để sử dụng tên chi nhánh. Bên trong nó chỉ lấy băm của HEAD của chi nhánh. - KingCrunch
whats điểm để kéo chủ sau khi thanh toán? - Junchen Liu
@shanyangqu Để nhận các thay đổi mới nhất từ ​​xa. Nếu bạn làm việc một mình và chỉ với một hệ thống thì không có vấn đề gì cả. Nhưng khi có những thay đổi được đẩy từ một hệ thống khác (có thể từ một nhà phát triển khác), bạn sẽ thấy xung đột ngay khi bạn cố gắng đẩy hợp nhất trở lại (bước thứ 4). Giải pháp duy nhất bây giờ là hợp nhất tổng thể địa phương của bạn vào tổng thể điều khiển từ xa, kết thúc bằng một cam kết hợp nhất rất xấu xí "sáp nhập vào nguồn gốc / chính". Vì vậy, nó luôn luôn là một ý tưởng tốt để thực hiện một kéo trước khi hợp nhất - KingCrunch
@KingCrunch 5 năm sau và vẫn là câu trả lời hữu ích nhất trên SO - sterling archer
"Trong mô tả của bạn có vẻ như, kiểm tra đó chỉ dành cho bạn? Vì vậy, không có lý do để xuất bản nó." Bạn có thể muốn đẩy chi nhánh địa phương của bạn lên đến một máy chủ nếu, ví dụ, máy chủ đó cung cấp một bản sao lưu đối với ổ đĩa cục bộ của bạn không thành công hoặc nếu bạn không có phương tiện khác để thực hiện sao lưu. - Eric


Đây là một câu hỏi rất thực tế, nhưng tất cả các câu trả lời trên đều không thực tế.

Như

git checkout master
git pull origin master
git merge test
git push origin master

Cách tiếp cận này có hai vấn đề:

  1. Nó không an toàn, bởi vì chúng tôi không biết nếu có bất kỳ xung đột giữa chi nhánh kiểm tra và chi nhánh chính.

  2. Nó sẽ "ép" tất cả các cam kết thử nghiệm thành một hợp nhất cam kết trên tổng thể; đó là để nói về nhánh master, chúng ta không thể thấy tất cả các bản ghi thay đổi của nhánh thử nghiệm.

Vì vậy, khi chúng tôi nghi ngờ có một số xung đột, chúng tôi có thể thực hiện các hoạt động git sau đây:

git checkout test
git pull 
git checkout master
git pull
git merge --no-ff --no-commit test

Kiểm tra merge trước commit, tránh cam kết nhanh về phía trước --no-ff,

Nếu xung đột gặp phải, chúng ta có thể chạy git status để kiểm tra chi tiết về xung đột và cố gắng giải quyết

git status

Khi chúng tôi giải quyết xung đột hoặc nếu không có xung đột, chúng tôi commit và push họ

git commit -m 'merge test branch'
git push

Nhưng theo cách này sẽ mất lịch sử thay đổi được đăng nhập trong nhánh thử nghiệm, và nó sẽ làm cho nhánh master trở nên khó khăn cho các nhà phát triển khác để hiểu lịch sử của dự án.

Vì vậy, phương pháp tốt nhất là chúng ta phải sử dụng rebase thay vì merge (giả sử, khi trong thời gian này, chúng tôi đã giải quyết được xung đột chi nhánh).

Sau đây là một mẫu đơn giản, cho các hoạt động nâng cao, vui lòng tham khảo http://git-scm.com/book/en/v2/Git-Branching-Rebasing

git checkout master
git pull
git checkout test
git pull
git rebase -i master
git checkout master
git merge test

Đúng, khi bạn đã làm xong, tất cả các cam kết của nhánh Test sẽ được chuyển lên phần đầu của nhánh Master. Lợi ích chính của việc rebasing là bạn có được một lịch sử dự án tuyến tính và sạch hơn nhiều.

Điều duy nhất bạn cần tránh là: không bao giờ sử dụng rebase trên chi nhánh công cộng, như nhánh chính.

như hoạt động sau:

git checkout master
git rebase -i test

không bao giờ làm những hoạt động này.

Chi tiết cho https://www.atlassian.com/git/tutorials/merging-vs-rebasing/the-golden-rule-of-rebasing

ruột thừa:


260
2018-03-14 12:13



Tôi đồng ý rebasing các chi nhánh thử nghiệm cho sau này sáp nhập vào tổng thể là con đường để đi. Ngay cả các câu trả lời khác là chính xác, điều này sẽ giữ lại lịch sử của những thay đổi của kiểm thử chi nhánh trong phần đầu của chủ như tự động đề cập đến "bạn có được một lớp lót và nhiều dự án sạch hơn", đó là mục đích của hệ thống kiểm soát phiên bản. - le0diaz
Tuyên bố "nó không phải là một cách an toàn, vì chúng tôi không biết là có bất kỳ xung đột giữa chi nhánh kiểm tra và chi nhánh tổng thể" là không đúng: người ta luôn có thể hủy hợp nhất. Và ngay cả khi không có xung đột, bạn luôn có thể hoàn tác cam kết cục bộ cuối cùng miễn là nó không được đẩy. Nếu không có sự hiểu biết chính xác về git một số điều có thể có vẻ hơi đáng sợ hoặc không rõ ràng, nhưng "không an toàn" chỉ là không chính xác trong bất kỳ cách nào. Hãy cẩn thận đừng nhầm lẫn giữa những người khác với thông tin không chính xác. - Paul van Leeuwen
đồng ý với @PaulvanLeeuwen, khi bạn git merge chi nhánh thử nghiệm thành chính, bạn sẽ được thông báo về các xung đột và đó là nơi bạn sẽ bước vào và hợp nhất các thay đổi. Khi bạn đã hoàn tất, bạn sẽ cam kết hợp nhất và đẩy lùi lại. Nếu bạn hối tiếc hoặc không thể dường như hợp nhất nó một cách chính xác, bạn luôn có thể loại bỏ công việc của bạn và kéo từ chủ một lần nữa. Vì vậy, nó chắc chắn không phải là không an toàn .. - Juan
tại sao rebase -i? - MushyPeas
Rebasing vốn kém an toàn hơn so với hợp nhất. Đề xuất việc rebasing là một tùy chọn an toàn hơn để hợp nhất là sai. Rebasing là một chiến lược hợp lệ, nhưng đi kèm với nhiều thông báo hơn mà người dùng nên cẩn thận. - Ikke


Cả rebase lẫn merge không nên ghi đè lên những thay đổi của bất kỳ ai (trừ khi bạn chọn làm như vậy khi giải quyết xung đột).

Cách tiếp cận thông thường trong khi phát triển là

git checkout master
git pull
git checkout test
git log master.. # if you're curious
git merge origin/test # to update your local test from the fetch in the pull earlier

Khi bạn đã sẵn sàng hợp nhất trở lại thành thạo,

git checkout master
git log ..test # if you're curious
git merge test
git push

Nếu bạn đang lo lắng về việc phá vỡ một cái gì đó trên hợp nhất, git merge --abort là có cho bạn.

Sử dụng push và sau đó kéo như một phương tiện sáp nhập là ngớ ngẩn. Tôi cũng không chắc tại sao bạn lại đẩy thử nghiệm xuất xứ.


73
2018-04-10 00:17



Quá trình này sẽ tăng số lần commit, mỗi lần bạn chuyển đổi giữa các nhánh, bạn phải cam kết chi nhánh của bạn. - iBug
Gì? Bạn đang nói nó sẽ tăng số lần commit mỗi khi bạn chuyển nhánh? Hay bạn đang nói rằng mỗi khi bạn chuyển đổi chi nhánh, bạn phải "cam kết chi nhánh của bạn"? Đầu tiên là không đúng sự thật và tôi không chắc chắn về phương tiện thứ hai. - raylu
trước khi thanh toán, bạn phải cam kết chi nhánh. đó là những gì tôi đang nói - iBug
Bạn không: đó là (một trong những thứ) git stash là cho. - msanford
Tôi khuyên bạn nên git checkout test; git pull thay vì git merge origin/test. Thậm chí tốt hơn là git pull --rebase. Dù sao, bạn quên kéo những thay đổi, vì vậy trước git merge origin/test bạn nên git fetch origin test (git fetch .. && git merge .. chính xác là cái gì git pull .. làm :)) - KingCrunch


ngoài ra KingCrunches trả lời, Tôi đề nghị sử dụng

git checkout master
git pull origin master
git merge --squash test
git commit
git push origin master

Bạn có thể đã thực hiện nhiều cam kết trong nhánh khác, mà chỉ nên là một cam kết trong nhánh chính. Để giữ cho lịch sử cam kết càng sạch càng tốt, bạn có thể muốn xóa tất cả các cam kết từ nhánh thử nghiệm thành một cam kết trong nhánh chính (xem thêm: Git: Để bí hay không để bí?). Sau đó, bạn cũng có thể viết lại thông điệp cam kết cho một cái gì đó rất biểu cảm. Cái gì đó dễ đọc và dễ hiểu, mà không cần đào sâu vào mã.

chỉnh sửa: Bạn có thể quan tâm

Vì vậy, trên GitHub, tôi sẽ làm như sau cho một chi nhánh tính năng mybranch:

Nhận thông tin mới nhất từ ​​nguồn gốc

$ git checkout master
$ git pull origin master

Tìm hàm băm cơ sở hợp nhất:

$ git merge-base mybranch master
c193ea5e11f5699ae1f58b5b7029d1097395196f

$ git checkout mybranch
$ git rebase -i c193ea5e11f5699ae1f58b5b7029d1097395196f

Bây giờ, hãy đảm bảo chỉ có pick, Phần còn lại là s:

pick 00f1e76 Add first draft of the Pflichtenheft
s d1c84b6 Update to two class problem
s 7486cd8 Explain steps better

Tiếp theo, chọn một thông điệp cam kết rất tốt và đẩy tới GitHub. Thực hiện yêu cầu kéo sau đó.

Sau khi hợp nhất yêu cầu kéo, bạn có thể xóa nó cục bộ:

$ git branch -d mybranch

và trên GitHub

$ git push origin :mybranch

20
2018-04-21 08:18



"mà chỉ nên là một cam kết trong nhánh chính", cũng không nhất thiết, bạn có thể wekk muốn giữ lịch sử - Cocowalla
Chắc chắn rồi. Nhưng sau đó chỉ đơn giản là không squash các cam kết - Martin Thoma


Đây là quy trình làm việc mà tôi sử dụng trong công việc của mình với nhóm. Kịch bản là như bạn mô tả. Đầu tiên, khi tôi hoàn thành công việc test Tôi rebase với chủ để kéo vào bất cứ điều gì đã được thêm vào chủ trong thời gian tôi đã làm việc trên test chi nhánh.

git pull -r upstream master

Điều này sẽ kéo các thay đổi thành thạo vì bạn đã chia nhỏ test và áp dụng chúng, sau đó áp dụng các thay đổi bạn đã thực hiện để kiểm tra "trên đầu trang" trạng thái hiện tại của chính. Có thể có xung đột ở đây, nếu những người khác đã thực hiện thay đổi đối với cùng một tệp mà bạn đã chỉnh sửa trong thử nghiệm. Nếu có, bạn sẽ phải sửa chúng theo cách thủ công và cam kết. Một khi bạn đã làm điều đó, bạn sẽ được tốt để chuyển sang các chi nhánh tổng thể và hợp nhất testkhông có vấn đề gì.


3
2018-03-16 22:27





git checkout master
git pull origin master
# Merge branch test into master
git merge test

Sau khi hợp nhất, nếu tệp được thay đổi, khi bạn hợp nhất nó sẽ thông qua lỗi "Giải quyết xung đột"

Vì vậy, sau đó bạn cần phải giải quyết tất cả các xung đột của bạn sau đó, bạn phải một lần nữa cam kết tất cả các thay đổi của bạn và sau đó đẩy

git push origin master

Điều này tốt hơn là ai đã thực hiện các thay đổi trong nhánh thử nghiệm, bởi vì anh ta biết những thay đổi mà anh ta đã làm.


1
2018-04-07 08:55