Áp dụng các thay đổi từ nhánh b đến a mà không hợp nhất hoặc thêm cam kết


86

Kịch bản của tôi là tôi có một nhánh mà tôi đã thực hiện những cải tiến lớn đối với quá trình xây dựng (nhánh A) và trong một nhánh khác, tôi đang làm việc trên một tính năng không liên quan (nhánh B). Vì vậy, bây giờ khi tôi hack ở nhánh B, tôi muốn lấy những thứ tôi đã viết ở nhánh A vì tôi muốn bản dựng nhanh hơn và dễ dàng hơn. Tuy nhiên, tôi không muốn "gây ô nhiễm" cho nhánh B của mình, chỉ cần thêm các thay đổi từ nhánhA thành các thay đổi không theo giai đoạn.

Những gì tôi đã thử (khi đứng trên branchB):

git merge --no-commit branchA

Không hoạt động vì nó đưa bạn vào bên trong một hợp nhất. Nếu không, nó sẽ rất hoàn hảo.

git checkout branchA -- .

Không hoạt động vì nó áp dụng các thay đổi giữa branchA..branchB chứ không phải các thay đổi master..branchA.

Còn gì nữa không?

Chỉnh sửa: Có, các thay đổi trên chi nhánh A được cam kết. Trong ví dụ này chỉ có một nhánh có cải tiến bản dựng, nhưng có thể có tới N nhánh có cải tiến bản dựng mà tôi muốn áp dụng khi làm việc trên một nhánh tính năng.


Những thay đổi trên A đã được cam kết chưa?
Theolodis

Câu trả lời:


152

Tôi chỉ phải làm điều gì đó tương tự và có thể sửa nó bằng cách thêm --squashvào lệnh hợp nhất

git merge --no-commit --squash branchA
git reset HEAD # to unstage the changes

3
Điều này cũng nên có một ghi chú giải thích về những gì nó đang làm. Nó giai đoạn diff thay đổi từ branchA vào chi nhánh hiện tại của bạn
KareemElashmawy

giả sử tôi vừa hợp nhất mã từ branchA vào master nhưng tôi quên một vài thứ và muốn thêm một vài mã / thay đổi vào cam kết hợp nhất này mà không hiển thị dưới dạng cam kết hợp nhất khác trong lịch sử git. phương pháp này sẽ hoạt động?
Sushmit Sagar

@Sushmit Tôi nghĩ rằng bạn có thể làm một git commit —amendvà nó sẽ nối những thay đổi mới cam kết cuối cùng, tôi chỉ là không hoàn toàn chắc chắn nếu nó hoạt động trên các cam kết hợp nhất
guilffer

1
Tôi không nghĩ - không cần cam kết ở đây? Nên là mặc định.
Petter

11

cherry-pick -n nên làm những gì bạn muốn, nhưng tôi không chắc tại sao bạn muốn cải tiến bản dựng dưới dạng thay đổi không theo giai đoạn - điều đó chỉ làm cho một số thứ khó hơn (ví dụ: hợp nhất các thay đổi khác với tệp đã sửa đổi hoặc khôi phục bất kỳ thứ gì).

Trong ví dụ này chỉ có một nhánh có cải tiến bản dựng, nhưng có thể có tới N nhánh có cải tiến bản dựng mà tôi muốn áp dụng khi làm việc trên một nhánh tính năng.

Trong trường hợp đó, tôi sẽ tạo một nhánh mới, C, mà bạn hợp nhất từ ​​cả A và B (và bất kỳ nhánh nào khác có cải tiến bản dựng). Cam kết các thay đổi trên nhánh tính năng, B, sau đó hợp nhất chúng với nhánh C, hiện có chứa các cải tiến về bản dựng và các thay đổi của nhánh tính năng, vì vậy bạn có thể kiểm tra chúng cùng nhau. Nếu bạn cần thực hiện nhiều thay đổi hơn, hãy làm điều đó trong nhánh thích hợp, không phải C, sau đó hợp nhất thành C. Vì vậy, không bao giờ thay đổi bất kỳ điều gì trong nhánh C, chỉ sử dụng nó để tích hợp các thay đổi từ các nhánh khác.

Điều đó có nghĩa là bạn có thể sử dụng tất cả các tính năng của Git trong nhánh C, thay vì tung hứng những thay đổi chưa cam kết trong một cây bẩn.


UseCase for cherry-pick -n: Tôi đã tạo một bản sao mã đang hoạt động của mình bằng cách thêm nhiều thứ vào những vị trí ngẫu nhiên. Bây giờ tôi muốn xóa mã của mình trước khi tôi cam kết với nhánh của tính năng này. Vì vậy, tôi chuyển sang một nhánh tạm thời, cam kết tất cả các thay đổi. Quay lại nhánh tính năng, cherry-pickcam kết đó. Có cách nào tốt hơn để làm điều này không?
Tejas Kale

6

Bạn sẽ có thể chọn anh đào các cam kết (với -nđể tránh cam kết ngay lập tức).


-n không hoạt động. Nó cho biết tùy chọn no -m khi cam kết chọn cherry không thành công.
Alejandro Sanz Díaz,

5

Tôi không chắc chắn 100% rằng tôi đã hiểu nó rõ ràng, nhưng trong trường hợp của tôi, tôi vừa tạo bản vá khác nhau giữa các nhánh và sau đó áp dụng đường dẫn này trên nhánh B.

Bên trong nhánh A:

 git diff branchA..branchB > patch.diff
 git apply patch.diff

4

Tôi không chắc mình hiểu yêu cầu của bạn.

Bạn có thể chạy hợp nhất, sau đó gọi git reset HEAD~1.


Trình tự sau sẽ phát lại mọi cam kết giữa masterbranchAtrên đầu trang branchB. Các cam kết đã được áp dụng branchBsẽ bị bỏ qua.

# start from branchA
git checkout branchA
# create a temporary branch wip
git checkout -b wip
# use rebase to replay each commit between master and wip on branchB
git rebase --onto branchB master wip

# if you want to remove all the commit history and only keep the resulting diffs,
# use git reset
git reset branchB

# change the active branch
git checkout branchB
# remove temp branch
git branch -d wip

Điều đó thêm các tệp vào khu vực dàn dựng của git mà tôi không muốn. Thêm vào đó, nó dường như chỉ hoạt động tốt khi tất cả các nhánh được phân nhánh từ cùng một cam kết trên nhánh chính. Nếu không, các khác biệt không có trong phạm vi master..branchA được giới thiệu.
Björn Lindqvist

@ BjörnLindqvist: loại bỏ --softtùy chọn nếu bạn không muốn các thay đổi trong khu vực theo giai đoạn. Bạn có thể vẽ một biểu đồ về cách các chi nhánh của bạn được thiết lập không?
LeGEC
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.