2012-06-15 39 views
55

Trong nỗ lực đạt được git niết bàn, tôi đang dành cả ngày học cách tận dụng rebase cho các tình huống mà tôi hiện đang hợp nhất.Tôi có thể sử dụng git rebase như thế nào mà không cần phải đẩy mạnh?

Khi chạy qua những gì tôi cho là luồng git 101 (mà tôi giải thích bên dưới), tôi phải push --force khi đẩy các thay đổi của tôi về nguồn gốc.

Tôi không phải là người duy nhất - Tôi biết rằng điều này được bao phủ mặt đất (xem 1, 2, 3, 4, 5), và tôi hiểu những lý do kỹ thuật tại sao một lực lượng là cần thiết. Vấn đề của tôi là --- có rất nhiều bài viết trên blog ca ngợi sự phản đối và cách nó thay đổi cuộc sống của họ (xem 1, 2, 3, 4 để liệt kê một vài), nhưng không ai trong số họ đề cập rằng push --force là một phần dòng chảy của họ. Tuy nhiên, gần như mọi câu trả lời cho các câu hỏi stackoverflow hiện có đều nói những câu như "yeah, nếu bạn sẽ rebase, ya gotta use push --force".

Với số lượng và tính tôn giáo của những người ủng hộ rebase, Tôi phải tin rằng việc sử dụng 'push - force' không phải là một phần vốn có của luồng rebase, và nếu người đó thường buộc phải đẩy họ, làm điều gì đó sai.

push --forcebad thing.

Vì vậy, đây là luồng của tôi. Tôi có thể đạt được kết quả tương tự như thế nào nếu không có một lực?

Ví dụ đơn giản

Hai chi nhánh:

  • v1.0 - một chi nhánh phát hành, chỉ chứa các bản vá lỗi
  • chủ - tất cả mọi thứ cho việc phát hành lớn tiếp theo.

Tôi có một vài bản vá và một vài cam kết cho bản phát hành tiếp theo.

premerge

Tôi muốn kết hợp các bản vá lỗi vào bậc thầy của tôi để họ không bị mất cho phiên bản tiếp theo. Pre-giác ngộ tôi muốn chỉ đơn giản là:

git checkout master 
git merge v1.0 

Nhưng bây giờ tôi đang cố gắng

git checkout master 
git rebase v1.0 

Vì vậy, bây giờ tôi đang ở đây:

enter image description here

Thời gian:

git push 

Không súc sắc.

Trả lời

29

Rebasing là một công cụ tuyệt vời, nhưng nó hoạt động tốt nhất khi bạn sử dụng nó để tạo các phép hợp nhất nhanh cho các nhánh chủ đề trên bản gốc. Ví dụ: bạn có thể rebase nhánh tiện ích bổ sung mới của mình chống lại chính:

git checkout add-new-widget 
git rebase -i master 

trước khi thực hiện hợp nhất nhanh nhánh vào nhánh. Ví dụ:

git checkout master 
git merge --ff-only add-new-widget 

Lợi ích của việc này là lịch sử của bạn sẽ không có nhiều hợp phức tạp cam kết hoặc hợp nhất các cuộc xung đột, bởi vì tất cả thay đổi của bạn sẽ được rebased lên đỉnh của bậc thầy trước khi hợp nhất. Lợi ích thứ hai là bạn đã được rebased, nhưng bạn không phải sử dụng git push --force vì bạn không phải là lịch sử clobbering trên nhánh master.

Đó chắc chắn không phải là trường hợp sử dụng duy nhất để rebase hoặc quy trình làm việc duy nhất, nhưng đó là một trong những sử dụng hợp lý hơn cho nó mà tôi đã nhìn thấy. YMMV.

+2

Cảm ơn CG, tôi nghĩ rằng "sử dụng nó để tạo sự hợp nhất nhanh" là chìa khóa. Nó không áp dụng cho trường hợp của tôi ở trên, nơi tôi có hai nhánh sống - nhánh phát triển và nhánh phát hành, nhưng dường như áp dụng rất tốt cho các nhánh chủ đề tạm thời chỉ cần thiết cho một thời gian hạn chế, và sau đó có thể đã bị xóa khi chúng được hợp nhất. Cảm ơn một lần nữa. –

+1

Tôi hiểu điều này, nhưng câu hỏi ban đầu vẫn còn. Tôi nghĩ câu trả lời thực tế là câu trả lời được đưa ra bởi [@Fabien Quatravaux] (http://stackoverflow.com/questions/11058312/how-can-i-use-git-rebase-without-requiring-a-forced-push# 11137857) – IsmailS

+2

Vâng, bạn vẫn sẽ phải ép buộc nhánh 1.0, phải không? Ít nhất, đó là cách mọi thứ có xu hướng trở nên luôn luôn xảy ra với tôi. Phương pháp Fabiens sẽ ngăn chặn điều đó xảy ra. – joerx

12

Bạn phải ép buộc nếu bạn rebase, bạn đã xuất bản các thay đổi của mình, đúng không?

Tôi sử dụng rebase toàn bộ nhóm, nhưng tôi sẽ xuất bản ở một nơi riêng tư mà lực đẩy không quan trọng (ví dụ: bản sao của riêng tôi trên GitHub, như một phần của yêu cầu kéo) hoặc tôi rebase trước khi tôi đẩy lần đầu tiên.

Đây là trung tâm của quy trình làm việc mà bạn sử dụng rebase, nhưng không ép buộc nhiều: không xuất bản mọi thứ cho đến khi chúng sẵn sàng, không rebase sau khi bạn đẩy.

+0

Cảm ơn Dan. Bạn có thể cho tôi biết làm thế nào ở trên nên đạt được sau đó? Đây không phải là một kịch bản mà rebase áp dụng? –

+2

Nếu bạn cô lập tất cả công việc của mình cho các nhánh chủ đề, thì nó sẽ thiết lập một kịch bản tốt để rebasing.Bạn 'rebase' các thay đổi mới được kéo vào nhánh chủ đề của bạn, nhưng khi bạn đã hoàn tất các thay đổi của nhánh đó, bạn' hợp nhất' nhánh đó trở lại nhánh phát triển chính. – redhotvengeance

+1

Vấn đề là bạn đã xuất bản chi nhánh - vì vậy bạn cần ép buộc vào kho lưu trữ. Bạn cần phải từ bỏ một trong hai: xuất bản theo cách bạn làm, hoặc rebasing. Lấy làm tiếc. –

20

@CodeGnome đúng. Bạn không nên rebase master trên nhánh v1.0 nhưng nhánh v1.0 trên master, điều đó sẽ tạo ra tất cả sự khác biệt.

git checkout -b integrate_patches v1.0 
git rebase master 
git checkout master 
git merge integrate_patches 

Tạo chi nhánh mới trỏ tới v1.0, di chuyển chi nhánh mới lên trên cùng của bản gốc rồi tích hợp phiên bản mới của bản vá V1.0 lên nhánh chính. Bạn sẽ kết thúc với một cái gì đó như:

o [master] [integrate_patches] Another patch on v1.0 
o A patch on v1.0 
o Another change for the next major release 
o Working on the next major release 
| o [v1.0] Another path on v1.0 
| o A patch on v1.0 
|/
o Time for the release 

Bằng cách này sử dụng rebase được khuyến khích bởi the official git documentation.

Tôi nghĩ bạn đúng về git push --force: bạn chỉ nên sử dụng nó nếu bạn phạm sai lầm và đã đẩy thứ gì đó bạn không muốn.

+0

Tôi nghĩ đây là câu trả lời tốt nhất cho vấn đề cụ thể trong OP. Bạn tạo một nhánh hợp nhất tạm thời và rebase trên đó, sau đó hợp nhất vào master và đẩy đến origin. Nhánh tạm thời không cần phải được đẩy tới gốc. Lời khuyên bổ sung duy nhất tôi đưa ra là có một chi nhánh phát triển hoặc qa nơi mã được hợp nhất/rebased có thể đủ điều kiện. Sau khi trình độ, mã này sau đó sẽ được hợp nhất thành ff. Điều này cho phép hotfix dễ dàng nếu quá trình tiêu chuẩn của bạn mất quá nhiều thời gian. Điều này về cơ bản là quy trình "git flow". –

3

Tôi nghĩ rằng trường hợp sử dụng tốt cho mẫu rebase-force-push này không phải là kết quả của việc đẩy nhầm: tự mình làm việc trên một chi nhánh tính năng từ nhiều vị trí (máy tính). Tôi làm điều này thường xuyên, vì đôi khi tôi làm việc tại văn phòng trên máy tính để bàn và đôi khi từ trang chủ/khách hàng trên máy tính xách tay của mình. Tôi cần phải thỉnh thoảng rebase để theo kịp với nhánh chính và/hoặc để làm cho việc sáp nhập trở nên rõ ràng hơn, nhưng tôi cũng cần phải đẩy mạnh khi tôi để một máy làm việc trên một máy khác (nơi tôi vừa kéo). Làm việc như một say mê, miễn là tôi là người duy nhất làm việc trên chi nhánh.

+2

Tôi có cùng quy trình làm việc này (làm việc từ nhiều máy tính/địa điểm). Vì vậy, giả sử bạn đang làm việc trên một nhánh chủ đề được gọi là 'mytopic'. Miễn là bạn luôn luôn rebase một chi nhánh throwaway địa phương (mà chỉ đơn thuần là một nhánh của mytopic) vào "master" và sau đó hợp nhất lại thành mytopic, thì bạn không bao giờ phải ép buộc. OP có một kịch bản hơi khác một chút, vì vậy trong trường hợp đó, lực đẩy có thể là cần thiết. Tuy nhiên, tôi nghĩ rằng OP đang đảo ngược sai đường - nếu anh ta làm như tôi đã mô tả thì không cần phải đẩy mạnh. – bwv549

0

Đây là những gì tôi sử dụng (giả sử tên chi nhánh của bạn là foobar):

git checkout master    # switch to master 
git rebase foobar    # rebase with branch 
git merge -s ours origin/master # do a basic merge -- but this should be empty 
git push origin master   # aaand this should work 
+1

Rebasing master trông kỳ lạ. –

+0

'git' không phải là không có cá tính – redolent

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