Git: Hướng dẫn cuối cùng về Git Merge và Git Rebase
Chào mừng bạn đến với hướng dẫn cuối cùng của chúng tôi về các lệnh git merge
và git rebase
. Hướng dẫn này sẽ dạy cho bạn mọi thứ bạn cần biết về cách kết hợp nhiều nhánh với Git.
Git Merge
Lệnh git merge
sẽ hợp nhất bất kỳ thay đổi nào được thực hiện đối với cơ sở mã trên một nhánh riêng biệt với nhánh hiện tại của bạn dưới dạng một commit mới.
Cú pháp lệnh như sau:
git merge BRANCH-NAME
Ví dụ: nếu bạn hiện đang làm việc trong một nhánh có tên dev
và muốn hợp nhất bất kỳ thay đổi mới nào đã được thực hiện trong một nhánh có tên new-features
, bạn sẽ đưa ra lệnh sau:
git merge new-features
Lưu ý: Nếu có bất kỳ thay đổi nào chưa được commit trên nhánh hiện tại của bạn, Git sẽ không cho phép bạn hợp nhất cho đến khi tất cả các thay đổi trong nhánh hiện tại của bạn đã được commit. Để xử lý những thay đổi đó, bạn có thể:
Tạo một nhánh mới và commit các thay đổi:
git checkout -b new-branch-name
git add .
git commit -m "<your commit message>"
Cất giấu chúng:
git stash # add them to the stash
git merge new-features # do your merge
git stash pop # get the changes back into your working tree
Từ bỏ tất cả các thay đổi:
git reset --hard # removes all pending changes
Git Rebase
Rebasing một nhánh trong Git là một cách để di chuyển toàn bộ nhánh đến một điểm khác trên cây. Ví dụ đơn giản nhất là di chuyển một nhánh xa hơn trên cây. Giả sử chúng ta có một nhánh chuyển hướng từ nhánh chính tại điểm A:
/o-----o---o--o-----o--------- branch
--o-o--A--o---o---o---o----o--o-o-o--- master
Khi bạn rebase, bạn có thể di chuyển nó như thế này:
/o-----o---o--o-----o------ branch
--o-o--A--o---o---o---o----o--o-o-o master
Để khởi động lại, hãy đảm bảo rằng bạn có tất cả các commit bạn muốn trong quá trình khởi động lại trong nhánh chính của mình. Kiểm tra nhánh bạn muốn khởi động lại và nhập git rebase master
(trong đó master là nhánh bạn muốn khởi động lại).
Cũng có thể khởi động lại trên một nhánh khác, ví dụ như một nhánh dựa trên một nhánh khác (hãy gọi nó là tính năng) được khởi động lại trên chính:
/---o-o branch
/---o-o-o-o---o--o------ feature
----o--o-o-A----o---o--o-o-o--o--o- master
Sau git rebase master branch
hoặc git rebase master
khi bạn đã kiểm tra chi nhánh, bạn sẽ nhận được:
/---o-o-o-o---o--o------ feature
----o--o-o-A----o---o--o-o-o--o--o- master
\---o-o branch
Git rebase tương tác trong bảng điều khiển
Để sử dụng git rebase
trong bảng điều khiển với danh sách các xác nhận, bạn có thể chọn, chỉnh sửa hoặc thả vào rebase:
- Nhập
git rebase -i HEAD~5
với số cuối cùng là bất kỳ số lần xác nhận nào từ lần gần đây nhất trở về trước mà bạn muốn xem lại. - Trong vim, nhấn
esc
, sau đói
để bắt đầu chỉnh sửa test. - Ở phía bên trái, bạn có thể ghi đè lên
pick
bằng một trong các lệnh bên dưới. Nếu bạn muốn gộp một commit vào một commit trước đó và loại bỏ thông báo commit, hãy nhậpf
vào vị trí của commitpick
. - Lưu và thoát khỏi trình soạn thảo văn bản của bạn.
- Khi quá trình rebase dừng lại, hãy thực hiện các điều chỉnh cần thiết, sau đó sử dụng
git rebase --continue
cho đến khi quá trình rebase thành công. - Nếu nó khởi động lại thành công thì bạn cần buộc đẩy các thay đổi của mình với
git push -f
để thêm phiên bản bị khởi động lại vào kho lưu trữ từ xa của bạn. - Nếu có xung đột hợp nhất, có một số cách để khắc phục điều này, bao gồm làm theo các đề xuất trong hướng dẫn này . Đây là một cách là mở các tệp trong trình soạn thảo văn bản và xóa các phần mã bạn không muốn. Sau đó sử dụng
git add <file name>
theo sau bởigit rebase --continue
. Bạn có thể bỏ qua commit xung đột bằng cách nhậpgit rebase --skip
, dừng khởi động lại bằng cách chạygit rebase --abort
trong bảng điều khiển của bạn.
pick 452b159 <message for this commit>
pick 7fd4192 <message for this commit>
pick c1af3e5 <message for this commit>
pick 5f5e8d3 <message for this commit>
pick 5186a9f <message for this commit>
# Rebase 0617e63..5186a9f onto 0617e63 (30 commands)
#
# Commands:
# p, pick = use commit
# r, reword = use commit, but stop to edit the commit message.
# e, edit = use commit, but stop to amend or add commit.
# s, squash = use commit, meld into previous commit and stop to edit the commit message.
# f, fixup = like "squash", but discard this commit's log message thus doesn't stop.
# x, exec = run command (the rest of the line) using shell
# d, drop = remove commit
#
# These lines can be re-ordered; they are executed from top to bottom.
#
# If you remove a line here THAT COMMIT WILL BE LOST.
#
# However, if you remove everything, the rebase will be aborted.
#
# Note that empty commits are commented out
Xung đột hợp nhất
Xung đột hợp nhất là khi bạn thực hiện các commit trên các nhánh riêng biệt làm thay đổi cùng một dòng theo những cách trái ngược nhau. Nếu điều này xảy ra, Git sẽ không biết nên giữ phiên bản nào của tệp trong một thông báo lỗi tương tự như sau:
CONFLICT (content): Merge conflict in resumé.txt Automatic merge failed; fix conflicts and then commit the result.
Nếu bạn xem file resumé.txt
trong trình chỉnh sửa mã của mình, bạn có thể thấy nơi xảy ra xung đột:
<<<<<<< HEAD
Address: 808 South Street
=======
Address: 505 North Street
>>>>>>> updated_address
Git đã thêm một số dòng bổ sung vào tệp:
<<<<<<< HEAD
=======
>>>>>>> updated_address
Hãy coi =======
là ranh giới phân chia xung đột. Mọi thứ nằm giữa <<<<<<< HEAD
và =======
là nội dung của nhánh hiện tại mà tham chiếu HEAD đang trỏ tới. Mặt khác, mọi thứ nằm giữa =======
và >>>>>>> updated_address
là nội dung trong nhánh được hợp nhất, updated_address
.
Git Merge so với Git Rebase
Cả hai git merge
và git rebase
đều là những lệnh rất hữu ích, và cái này không tốt hơn cái kia. Tuy nhiên, có một số khác biệt rất quan trọng giữa hai lệnh mà bạn và nhóm của bạn nên cân nhắc.
Bất cứ khi nào git merge
được chạy, một commit hợp nhất bổ sung sẽ được tạo. Bất cứ khi nào bạn đang làm việc trong kho lưu trữ cục bộ của mình, việc có quá nhiều commit hợp nhất có thể làm cho lịch sử commit trở nên khó hiểu. Thay vào đó , một cách để tránh commit hợp nhất là sử dụng git rebase
.
git rebase
là một tính năng rất mạnh mẽ. Điều đó đang được nói, nó cũng có rủi ro nếu nó không được sử dụng đúng cách. git rebase
làm thay đổi lịch sử commit, vì vậy hãy cẩn thận khi sử dụng nó. Nếu việc khởi động lại được thực hiện trong kho lưu trữ từ xa, thì nó có thể tạo ra nhiều vấn đề khi các nhà phát triển khác cố gắng lấy các thay đổi mã mới nhất từ kho lưu trữ từ xa. Hãy nhớ chỉ chạy git rebase
trong kho lưu trữ cục bộ.
Đó là tất cả những gì bạn cần biết để hợp nhất và khởi động lại với những thứ tốt nhất của chúng.