Câu hỏi Sử dụng GIT, làm cách nào tôi có thể chọn lọc / hợp nhất các thay đổi từ 'ngã ba' của người khác?


Thực hiện kịch bản này:

  1. Tôi quyết định 'fork' một codebase trên github.com, và bắt đầu thực hiện thường trình của tôi: Edit - Commit - Push; aka hack hack hack.
  2. Sau khi tôi thực hiện một số thay đổi, tôi thấy một số thay đổi mà một người khác đã thực hiện trên cùng một dự án và tôi thích chúng!
  3. Tôi quyết định tôi muốn kết hợp chúng với tôi. Vấn đề là, tôi chỉ muốn một 'phần' của một cam kết cụ thể, từ một số cam kết mà anh ta đã thực hiện.

Phương pháp hiệu quả nhất để nhận được số lượng thay đổi được chọn này, được hợp nhất vào 'ngã ba' của tôi là gì?


76
2017-09-10 12:36


gốc


Có thể trùng lặp Làm thế nào để chọn lọc hợp nhất hoặc chọn thay đổi từ một chi nhánh khác trong Git? - vas


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


Sau khi trolling những con sóng của thế giới IRC, ai đó đã đưa ra một giải pháp tuyệt vời:

git cherry-pick SHA1 --no-commit
git add --patch

Hy vọng rằng sẽ giúp bất cứ ai khác với cùng một câu hỏi!

EDIT: OK, có lẽ nó không phải là khá đơn giản. Dưới đây là các bước đầy đủ:

  1. Trước tiên, bạn phải ở trong kho lưu trữ của mình, hãy thực hiện cd-để đến thư mục làm việc của bạn.

  2. Bây giờ bạn cần thêm nhánh từ xa, và sau đó lấy nó. Làm điều này bằng cách:

    git remote add someUser git://github.com/someUser/someRepo.git

    git fetch someUser

  3. Bây giờ bạn có thể chạy các lệnh như git log someUser/master để tìm commit SHA1 bạn muốn kết hợp trong 'partial'.

  4. Một khi bạn có SHA, bây giờ bạn có thể chạy:

    git cherry-pick -n SHA1

    Ở đâu SHA1 là cam kết SHA, duh!

  5. Có khá có thể sẽ có xung đột, tùy thuộc vào độ tuổi cam kết, và tần suất mà khu vực cụ thể của dự án thay đổi. Xin lỗi, nhưng bạn phải tự giải quyết chúng bằng trình chỉnh sửa đáng tin cậy của bạn. Vì vậy, kéo VIM ra, hoặc bất cứ điều gì khác bạn sử dụng, và hack đi vào các cuộc xung đột cho đến khi bạn nhận được đến giai đoạn mà bạn thích những thay đổi.

  6. Bây giờ bạn phải thiết lập lại chỉ mục cho bản sửa đổi CHÍNH, sau đó bạn có thể sử dụng GIT đáng tin cậy add --patch lệnh để chọn và chọn những thay đổi bạn muốn:

    git reset HEAD

    git add --patch hoặc là git add -p

  7. Yay! Cam kết thời gian:

    git commit -m "I merged a select amount of changes"

  8. Để dọn dẹp đống lộn xộn (Những thứ bạn nói không vào git add --patch) và chỉ giữ các thay đổi đã chọn trong kho lưu trữ làm việc của bạn, hãy chạy:

    git reset --hard HEAD

    Hiển nhiên git checkout -f cũng là một lựa chọn khác.


113
2017-09-10 13:05



Tôi rất vui vì bạn đã tìm thấy git add -p; nó cực kỳ mạnh mẽ. Nếu bạn đã có cam kết được đề cập (ví dụ: không sử dụng --no-commit trên lựa chọn anh đào, hoặc đó là một trong những cam kết của bạn), bạn có thể sử dụng git reset HEAD^ để tua lại chỉ mục một lần commit, sau đó thêm các thay đổi trở lại với git add -p, cam kết theo từng bước. Nếu cam kết không ở đầu nhánh, bạn có thể sử dụng git rebase -i và chọn chỉnh sửa cam kết được đề cập. - Cascabel
Cảm ơn rất nhiều vì điều này! - Dave Martorana
đi bộ đẹp. hãy nhớ nếu bạn chỉ muốn toàn thể cam kết, bạn chỉ phát ra -n trong bước 4. Như thế này: git cherry-pick SHA1 - Hulvej
Các bit chính ở đây là git remote add <user> <fork-url> - sau đó bạn có thể git cherry-pick như bình thường. - Tom


Tôi không rõ ràng về những gì bạn muốn. Nếu bạn muốn chỉ mang lại một số cam kết từ các nhánh khác, bạn có thể sử dụng git cherry-pick SHA. Giải thích đầy đủ về gitready.


2
2017-09-10 12:40



Tôi chỉ sau 'phần' / 'phần' / 'một vài dòng' của một cam kết cụ thể, được hợp nhất vào kho lưu trữ của tôi. Không đặc biệt cụ thể. - Tim
Trong trường hợp đó, git format-patch SHA, git áp dụng <patch> là một tùy chọn - hgmnz


Tôi thực sự thích giải pháp của Tim, tuy nhiên đôi khi tôi thích mày mò trong vimdiff. Giải pháp của tôi cho vấn đề này là thô, nhưng nó có hiệu quả đối với tôi bởi vì tôi thích vim.

Tôi có vimdiff thiết lập như difftool của tôi, và sau đó để chọn lọc hợp nhất tôi diff các chi nhánh:

git difftool <branch> <file>

Sau đó, tôi đi đến cửa sổ với phiên bản hiện tại của chi nhánh và chỉnh sửa bản gốc trong vim (đôi khi điều này là không cần thiết, nhưng đôi khi vimdiff mở một phiên bản trong / tmp) và tắt chế độ chỉ đọc:

:e <file>
:set readonly!

Bây giờ tôi có thể sử dụng các công cụ vá lỗi của vim như do và dp để áp dụng những gì tôi muốn và thực hiện các chỉnh sửa nhỏ khác khi tôi thực hiện. Khi tôi làm xong, tôi lưu tập tin, thoát ra khỏi vim, và sau đó giai đoạn và cam kết các tập tin trong git như một chỉnh sửa thường xuyên.

Như tôi đã nói, điều này không đặc biệt phức tạp, nhưng nó rất mạnh mẽ, và vẫn hoàn toàn nằm trong dòng lệnh. Chỉ cần đảm bảo thêm thông báo cam kết rõ ràng, vì git sẽ không tự động bao gồm thông báo hợp nhất cho bạn.

ví dụ vimdiff http://j.mp/1dZVllt


2
2018-01-18 05:03



Tôi không nghĩ câu trả lời này hoàn toàn đủ điều kiện xứng đáng để trở thành một câu trả lời hoàn toàn độc lập. Thông tin hữu ích, nhưng không liên quan đặc biệt. (tại sao điều này ở đầu câu trả lời?) - Mike Kormendy


Nếu bạn chỉ muốn một cổng cam kết, có thể bạn sẽ tốt nhất bằng cách chọn lựa cam kết bạn muốn và đặt lại các tệp bạn không muốn chạm vào.

git cherry-pick SHA1
git checkout HEAD file1 file2 ... fileN

Tất nhiên, nếu bạn có một số phần được sửa đổi trong một tệp và chỉ muốn giữ một số trong số chúng, bạn không còn cách nào khác ngoài việc chỉnh sửa tệp theo cách thủ công, hãy cắt bỏ các thay đổi của chúng.


1
2017-09-10 12:38



Thanh toán có cần thiết ở đây không? Không lệnh chọn cherry đưa những thay đổi vào thư mục làm việc của bạn? - Casey Watson