Làm thế nào để xem cam kết nào trong một nhánh không ở nhánh kia?


180

Tôi có hai chi nhánh develnext. Trong devel tôi có một số lượng lớn hơn hoặc ít hơn các cam kết. Một số cam kết là anh đào được chọn trong next. Ngoài ra tôi đã thêm một số cam kết tiếp theo được hợp nhất devel.

Bây giờ tôi muốn xem những gì còn thiếu next, vì vậy tôi có thể kiểm tra các thay đổi một cách chi tiết trước khi đưa chúng đến next. Câu hỏi của tôi là bây giờ, làm thế nào tôi có thể xem những cam kết nào trong develnhưng không phải trong lần tiếp theo?



tiêu đề của bạn là một chút sai lệch, vì những gì bạn muốn so sánh là mẹo của cả hai chi nhánh. và tôi đến đây để tìm kiếm một giải pháp hai so sánh các cam kết cụ thể (khác nhau) của hai nhánh
bọ rùa

Câu trả lời:


210

Lệnh ít được sử dụng git cherrycho bạn thấy các cam kết chưa được chọn. Tài liệu cho đâygit cherry là , nhưng, tóm lại, bạn sẽ có thể làm được:

git checkout devel
git cherry next

... và thấy đầu ra giống như thế này:

+ 492508acab7b454eee8b805f8ba906056eede0ff
- 5ceb5a9077ddb9e78b1e8f24bfc70e674c627949
+ b4459544c000f4d51d1ec23f279d9cdb19c1d32b
+ b6ce3b78e938644a293b2dd2a15b2fecb1b54cd9

Các cam kết bắt đầu +sẽ là những cam kết mà bạn chưa chọn next. Trong trường hợp này, tôi chỉ chọn một cam kết cho đến nay. Bạn có thể muốn thêm -vtham số vào git cherrylệnh, để nó cũng xuất ra dòng chủ đề của mỗi lần xác nhận.


Tuyệt vời, đây là những gì tôi cần. Nó cũng sẽ là tốt đẹp để có được một mô tả ngắn về các bài kiểm tra, nhưng tôi có thể kịch bản này.
Sascha Effert

29
Bạn không cần git checkout devel, bạn chỉ có thể làm git cherry next devel.
Robin Winslow

21
“Có thể muốn thêm -v ? Cherry mà không có -vlà giống như lskhông có -la. ; -J
Slipp D. Thompson

1
Và bạn sẽ không biết cách nào cherryđể đánh dấu hoặc loại trừ các cam kết tương đương, phải không? cherrycó vẻ như một lệnh hệ thống ống nước, nhưng không (dường như) cung cấp nhiều tùy chọn. Đối với những gì tôi hiện đang ở giữa, git cherrymang lại cho tôi những thông tin sai lệch, nhưng @ sehe git log --cherry-pickchính xác loại trừ các cam kết đã chọn / bị từ chối trước đó.
Slipp D. Thompson

Tài liệu cung cấp một ví dụ cụ thể: git-scm.com/docs/git-cherry#_concittle_example
am

107

Ngoài ra, bạn có thể sử dụng

git log --left-right --graph --cherry-pick --oneline devel...next

để có được một danh sách tốt đẹp về các cam kết thực tế khác nhau không được chia sẻ giữa các chi nhánh.

Từ hoạt động là --cherry-pick

--cherry-pick

Bỏ qua bất kỳ cam kết nào đưa ra cùng một thay đổi như một cam kết khác ở "phía bên kia" khi tập hợp các cam kết bị giới hạn với sự khác biệt đối xứng. Ví dụ: nếu bạn có hai nhánh A và B, một cách thông thường để liệt kê tất cả các cam kết chỉ trên một mặt của chúng là với --left-right, giống như ví dụ ở trên trong mô tả về tùy chọn đó. Tuy nhiên, nó cho thấy các cam kết được chọn từ anh đào từ chi nhánh khác (ví dụ: "thứ 3 trên b" có thể được chọn từ anh đào từ chi nhánh A). Với tùy chọn này, các cặp xác nhận như vậy được loại trừ khỏi đầu ra.

Cập nhật Như đã đề cập trong một bình luận, các phiên bản gần đây của git đã thêm --cherry-mark:

--cherry-mark

Giống như --cherry-pick (xem bên dưới) nhưng đánh dấu các cam kết tương đương với = thay vì bỏ qua chúng và các tương đương với +.


1
Điều này đã không làm việc cho tôi. Phiên bản git của tôi không biết - một dòng, do đó tôi đã gỡ bỏ nó. Sau đó, tôi đã phải trao đổi phát và tiếp theo và nó đã làm việc. Rất đẹp!
Sascha Effert

@SaschaEffert: bạn không phải chuyển đổi phát và tiếp theo (chú ý BA dấu chấm, không phải HAI). Điều đó nói rằng, mọi thứ có thể khác nếu bạn sử dụng một phiên bản cổ của git (?) Nhưng trong trường hợp đó, bạn sẽ nhận được một lỗi phân tích lại trên ba dấu chấm.
sehe

2
Để giải trí, tôi đã tìm ra rằng cú pháp phân tích cú pháp '...' (khác biệt đối xứng) đã được thêm vào tháng 7 năm 2006 và tài liệu về nó đã được cập nhật vào tháng 6 năm 2008 . Niềm vui của nguồn mở!
sehe

1
'gls --first-Parent --cherry-mark - chỉ phát triển ... tiếp theo' trong đó gls là bí danh nhật ký git của tôi với tất cả các định dạng đẹp. cherry-mark cho thấy cả cherry cherry và not-cherry pick đều cam kết phát triển, nhưng đánh dấu chúng khác nhau.
angensesen

1
thêm - không hợp nhất có thể tốt hơn
MervynYang

51

Bạn có thể thử thực hiện các tập con git log:

git log --oneline devel ^next

4
Theo ý kiến ​​của tôi, đây là giải pháp tốt nhất (câu trả lời của @ sehe cũng cho thấy các cam kết tiếp theo không được phát triển - trong bối cảnh của OP, không có gì, nhưng trong tôi thì có - sử dụng --left-onlysẽ tốt hơn). Tuy nhiên, điều này có thể được cải thiện một chút bằng cách thêm vào --no-mergesđể bỏ qua mọi cam kết hợp nhất (ví dụ: nếu một tính năng hoặc nhánh hotfix được hợp nhất (riêng) vào cả phát và tiếp theo). Nói một cách nghiêm túc, tất nhiên, giải quyết xung đột trong sáp nhập có thể tạo ra sự khác biệt khác, nhưng đó thường không phải là trường hợp. Các --no-mergestùy chọn hữu ích có thể được áp dụng cho các câu trả lời khác là tốt.
Alex Dupuy

27

Làm thế nào về

git log next..devel

Kết quả tương tự như câu trả lời của Byran (thứ tự cam kết khác nhau) nhưng cả hai câu trả lời của chúng tôi sẽ tạo ra các cam kết khác nhau giữa các nhánh, thay vì chỉ hiển thị những gì trong một nhánh chứ không phải ở nhánh khác.


4
Bạn cũng có thể bỏ qua nhánh thứ hai nếu bạn hiện đang ở nhánh đó. tức làgit log next..
jmaxz

btw 'git log next..devel' khác với 'git log devel..next'
Eugene Kaurov

1

Để có được danh sách các cam kết không được tích hợp vào nhánh phát hành (tiếp theo), bạn có thể sử dụng:

git rev-list --reverse --pretty="TO_TEST %h (<%ae>) %s" --cherry-pick --right-only origin/release_branch...origin/development_branch | grep "^TO_TEST " > NotIntegratedYet.txt

Kiểm tra git-rev-list để biết thêm.


Lệnh của câu trả lời này đang thiếu các nhánh thực tế trong câu hỏi, tức lànext...devel
Alex Dupuy

@AlexDupuy Yah, đó là một câu trả lời khá nửa vời. Vì đó cũng không phải là câu trả lời đơn giản nhất và không giải thích được tại sao cách tiếp cận này sẽ tốt hơn, tôi -1 .
Slipp D. Thompson

-1

@Mark Longair đóng đinh nó trong câu trả lời của anh ấy ở đây , nhưng tôi muốn thêm một số hiểu biết bổ sung.

Liên quan và trả lời câu hỏi về cách chia nhỏ Yêu cầu Kéo (PR) lớn, đặc biệt là khi xóa các cam kết của bạn là không thực tế do một hoặc nhiều sự hợp nhất của chủ vào tính năng_branch của bạn

Tình huống của tôi:
Tôi đã thực hiện một khoản lớn feature_branchvới 30 lần cam kết và mở Yêu cầu kéo (PR) trên GitHub để hợp nhất nó vào master. Chi nhánh masterđã thay đổi một tấn bên dưới tôi và nhận được 200 cam kết mà tôi feature_branchkhông có. Để giải quyết xung đột tôi đã làm git checkout feature_branchgit merge masterhợp nhất mastercác thay đổi của tôi vào feature_branch. Tôi đã chọn mergethay vì rebaselên chủ mới nhất để tôi chỉ phải giải quyết xung đột một lần duy nhất thay vì có khả năng 30 lần (một lần cho mỗi lần cam kết của tôi). Tôi không muốn ép 30 lần cam kết của mình thành 1 lần đầu tiên và sau đó khởi động lại lần gần nhấtmasterbởi vì điều đó có thể xóa sạch lịch sử bình luận đánh giá GitHub trong PR. Vì vậy, tôi đã hợp nhất chủ vào nhánh tính năng của mình và giải quyết xung đột 1 lần duy nhất. Tất cả đều ổn rồi. PR của tôi, tuy nhiên, quá lớn để các đồng nghiệp của tôi xem xét. Tôi cần phải chia nó ra. Tôi đã đi tiêu diệt 30 lần cam kết của mình và OH NO! HỌ Ở ĐÂU? HỌ LÀ TẤT CẢ MỌI NGƯỜI QUAN TÂM VỚI master200 cam kết gần đây vì tôi đã hợp nhất mastervới tôi feature_branch! TÔI LÀM GÌ?

git cherrysử dụng trong trường hợp bạn muốn thử git cherry-pickcam kết cá nhân:

git cherry để giải cứu (loại)!

Để xem tất cả các cam kết trong feature_branchnhưng KHÔNG trong mastertôi có thể làm:

git checkout feature_branch
git cherry master

HOẶC, tôi có thể kiểm tra các cam kết từ bất kỳ chi nhánh nào mà không đảm bảo tôi vào feature_branchtrước bằng cách thực hiện git cherry [upstream_branch] [feature_branch], như thế này. Một lần nữa, kiểm tra này để xem cam kết nào trong feature_branchnhưng KHÔNG ở upstream_branch( mastertrong trường hợp này):

git cherry master feature_branch

Thêm -vcũng hiển thị các dòng chủ đề thông báo cam kết:

git cherry -v master

Đường ống đến "đếm từ" "-lines" ( wc -l) đếm xem có bao nhiêu cam kết:

git cherry master | wc -l

Bạn có thể so sánh số này với số cam kết được hiển thị trong GithHub PR của bạn để cảm thấy tốt hơn về việc biết git cherrythực sự đang hoạt động. Bạn cũng có thể so sánh các băm git từng cái một và xem chúng khớp giữa git cherryvà GitHub. Lưu ý rằng git cherrysẽ KHÔNG tính bất kỳ cam kết hợp nhất nào mà bạn đã hợp nhất mastervào feature_branch, nhưng GitHub SILL. Vì vậy, nếu bạn thấy sự khác biệt nhỏ trong số đếm, hãy tìm kiếm trang cam kết GitHub PR cho từ "hợp nhất" và có thể bạn sẽ thấy đó là thủ phạm không xuất hiện git cherry. Ví dụ: một cam kết có tiêu đề "Hợp nhất nhánh 'chủ' thành Feature_branch" sẽ hiển thị trong GitHub PR nhưng không xuất hiện khi bạn chạy git cherry master feature_branch. Điều này là tốt và mong đợi.

Vì vậy, bây giờ tôi có một phương tiện để tìm ra các khác biệt mà tôi có thể muốn chọn cherry trên một nhánh tính năng mới để phân tách khác biệt này: Tôi có thể sử dụng git cherry master feature_branchcục bộ hoặc xem các cam kết trong GitHub PR.

Làm thế nào squash có thể giúp - nếu chỉ chúng ta có thể squash:

Tuy nhiên, một cách khác để chia nhỏ diff của tôi là nén tất cả 30 cam kết của tôi thành một, vá nó vào một nhánh tính năng mới, đặt lại mềm cam kết vá, sau đó sử dụng git guiđể thêm các tệp theo tệp, chunk theo chunk, hoặc từng dòng một. Khi tôi nhận được một tính năng phụ, tôi có thể cam kết những gì tôi đã thêm sau đó kiểm tra một chi nhánh mới, thêm một số tính năng, cam kết, kiểm tra một chi nhánh mới, v.v., cho đến khi tôi có tính năng lớn của mình được chia thành một số tính năng phụ . Vấn đề là 30 cam kết của tôi được xen kẽ với 200 cam kết khác từ những người khác do tôi git merge mastertham gia feature_branch, do đó, việc đánh trả là không thực tế, vì tôi phải sàng lọc 230 cam kết để đặt hàng lại và xóa 30 cam kết của tôi.

Làm thế nào để sử dụng một tập tin vá như là một thay thế dễ dàng hơn cho squashing:

Cách giải quyết đơn giản là lấy một tệp vá chứa "tương đương squash" của tất cả 30 cam kết của tôi, vá nó vào một nhánh mới của master(một nhánh tính năng mới) và làm việc từ đó, như sau:

git checkout feature_branch
# ensure I have the latest changes from master merged into feature_branch
git merge master 
# Obtain a patch file, which is the equivalent of a squash of my 30 commits into 1 commit:
git diff master..feature_branch > ~/mypatch.patch
git checkout master
# Create a new, sub-feature branch
git checkout -b feature_branch2
# Patch the 30 commit patch file onto it:
git apply ~/mypatch.patch

Bây giờ tôi có bản vá 30 cam kết của mình được áp dụng tại địa phương, nhưng chưa được thực hiện và không được cam kết.

Bây giờ sử dụng git guiđể thêm tệp, khối và / hoặc dòng và chia nhỏ PR hoặc "diff" của bạn:

Lưu ý rằng nếu bạn không có git gui, bạn có thể dễ dàng cài đặt nó trong Ubuntu sudo apt install git-gui.

Bây giờ tôi có thể chạy git guivà bắt đầu thêm tệp, khối và / hoặc dòng (bằng cách nhấp chuột phải vào chương trình GUI git) và chia nhánh 30 tính năng cam kết thành các nhánh phụ như được mô tả ở trên, liên tục thêm, cam kết, sau đó bỏ qua một nhánh tính năng mới và lặp lại chu trình này cho đến khi tất cả các thay đổi đã được thêm vào nhánh tính năng phụ và tính năng 30 cam kết của tôi được chia thành công thành 3 hoặc 4 tính năng phụ. Bây giờ tôi có thể mở một PR riêng cho từng tính năng phụ này và nhóm của tôi sẽ dễ dàng xem xét hơn.

Người giới thiệu:

  1. Tạo tập tin patch hoặc diff từ kho git và áp dụng nó vào kho git khác

Tôi cần tham khảo câu trả lời này ngày hôm nay, nhưng không thể tìm thấy nó nhanh chóng. May mắn thay, nó có một downvote để giúp tôi tìm thấy nó dễ dàng hơn, vì vậy một cú nhấp chuột đơn giản vào biểu tượng giải thưởng ở phía trên bên phải màn hình cho thấy gần đây tôi đã mất 2 điểm và nhấp vào đó đưa tôi trở lại đây, nơi tôi có thể bây giờ tham khảo câu trả lời của riêng tôi ở đây! Hy vọng rằng tôi sẽ không nhận được nhiều lượt tải xuống nữa, nhưng với người xuống, cảm ơn vì dịch vụ đã vô tình giúp tôi!
Gabriel Staples
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.