Làm web (12) - Git: phân nhánh căn bản

Bài học trước: Làm web (11) - Git: tạo nhánh
-----

3.8.4     Phân nhánh và tích hợp


Đọc thêm tài liệu tiếng Anh:


Để dễ hiểu về phân nhánh và tích hợp, hãy theo dõi một tình huống đơn giản sau:

1. Bạn đang lập trình để tạo một website

2. Bạn tạo một nhánh mới để  làm một chức năng mới cho website (tên nhánh là iss53)

3. Bạn làm việc trên nhánh vừa tạo

Đang làm việc thì có thông báo: một chức năng đã làm trước đó (nằm trên nhánh production) của website bị lỗi, bạn nhận được yêu cầu cần phải sửa gấp. Khi đó, bạn sẽ thực hiện các bước sau:

1. Chuyển qua nhánh production

2. Tạo một nhánh mới để sửa lỗi cho website

3. Sau khi sửa lỗi xong, tích hợp nhánh đó vào nhánh production và đưa website vào hoạt động bình thường

4. Chuyển sang nhánh mà bạn đang làm việc trước đó (nhánh iss53)

Cơ bản về phân nhánh

Giả sử bạn đang làm việc trên một dự án, và đã thực hiện commit một số lần trên nhánh master.

Xem hình minh họa,




Bạn quyết định là sẽ thực hiện công việc (issue) có số hiệu là #53. Thường thì mỗi nhóm hoặc công ty sẽ có quy ước riêng về việc đặt tên cho các công việc, ví dụ iss01, iss02.

Để vừa tạo và chuyển sang nhánh mới, sử dụng lệnh $ git checkout kèm theo tham số -b.

Ví dụ,

$ git checkout -b iss53
Switched to a new branch 'iss53'

Lệnh trên là gộp của hai lệnh sau:

$ git branch iss53
$ git checkout iss53

Xem kết quả,

$ git log --oneline --decorate
47ed23e (HEAD -> iss53, master) thay doi tren master branch
a89362e (tag: v1.4-lw, tag: v1.3, tag: v1.2, tag: v1.1, origin/master, origin/HEAD, phienban1) Update testdesktop.txt

Xem hình minh họa,



Bạn lập trình và thực hiện một số commit. Kết quả là nhánh iss53 sẽ tiến về phía trước.

Ví dụ,

$ git add *
$ git commit -m "them logo cho home page"
[iss53 1cef1be] them logo cho home page
 2 files changed, 239 insertions(+)

Xem kết quả,

$ git log --oneline --decorate
1cef1be (HEAD -> iss53) them logo cho home page
47ed23e (master) thay doi tren master branch
a89362e (tag: v1.4-lw, tag: v1.3, tag: v1.2, tag: v1.1, origin/master, origin/HEAD, phienban1) Update testdesktop.txt

Xem hình minh họa,



Đang làm công việc có số hiệu #53 thì bạn nhận được thông báo là một chức năng của website đã làm trước đó có lỗi, bạn cần phải sửa lỗi ngay. Nhờ có Git, bạn sẽ không phải sửa lỗi trực tiếp trên phần việc đang làm dở dang tại nhánh iss53, bạn cũng không phải khôi phục lại trạng thái của dự án tại thời điểm trước khi thực hiện công việc #53. Việc đơn giản bạn cần làm lúc này là chuyển về nhánh master.

Tuy nhiên, trước khi bạn chuyển nhánh, cần lưu ý là nếu khu vực làm việc và khu vực stage có chứa các thay đổi chưa được commit, nếu nó có xung đột (conflict) với nhánh sẽ chuyển qua (nhánh mới), thì Git sẽ không cho phép chuyển nhánh. Vì vậy, tốt nhất là thực hiện commit các thay đổi trên nhánh cũ rồi mới chuyển nhánh (cũng có thể thực hiện commit amend hoặc stash-sẽ tìm hiểu sau).

Giả sử bạn đã commit hết các thay đổi trên iss53 và sẵn sàng chuyển về nhánh master.

$ git checkout master
Switched to branch 'master'

Lúc này, thư mục làm việc (số tập tin, nội dung các tập tin) của bạn sẽ ở trạng thái giống như khi bạn chưa thực hiện công việc #53. Thực tế Git đã tự động tham chiếu tới snapshop tương ứng với commit cuối cùng trên nhánh master, để thêm/xóa/sửa các tập tin trong thư mục làm việc, sao cho giống với trạng thái của commit cuối cùng. Việc của bạn bây giờ là tập trung vào sửa lỗi.

Công việc tiếp theo cần làm là, bạn sẽ tạo nhánh mới có tên là hotfix, thực hiện việc sửa lỗi trên nhánh hotfix cho tới khi hoàn thành công việc.

$ git checkout -b hotfix
Switched to a new branch 'hotfix'

$ git log --oneline --decorate
47ed23e (HEAD -> hotfix, master) thay doi tren master branch
a89362e (tag: v1.4-lw, tag: v1.3, tag: v1.2, tag: v1.1, origin/master, origin/HEAD, phienban1) Update testdesktop.txt
Sửa lỗi xong và commit,
$ git add *
$ git commit -m "sua lai logo"
[hotfix e31a627] sua lai logo
 1 file changed, 1 insertion(+)
 create mode 100644 hotfix.html

Xem kết quả,

$ git log --oneline --decorate
e31a627 (HEAD -> hotfix) sua lai logo
47ed23e (master) thay doi tren master branch
a89362e (tag: v1.4-lw, tag: v1.3, tag: v1.2, tag: v1.1, origin/master, origin/HEAD, phienban1) Update testdesktop.txt

Xem hình minh họa,



Sau khi kiểm tra kĩ, để đảm bảo lỗi đã được sửa, bạn cần phải tích hợp nhánh hotfix vào lại nhánh master. Mục đích là cập nhật lại website đang hoạt động, nhằm khắc phục lỗi vừa xuất hiện. Để tích hợp (merge) vào nhánh master (nhánh chính), bạn cần phải chuyển sang “nhánh chính” và sử dụng lệnh $ git merge <tên nhánh phụ>.

Ví dụ,

$ git checkout master
Switched to branch 'master'

$ git merge hotfix
Updating 47ed23e..e31a627
Fast-forward
 hotfix.html | 1 +
 1 file changed, 1 insertion(+)
 create mode 100644 hotfix.html

Kết quả,

$ git log --oneline --decorate
e31a627 (HEAD -> master, hotfix) sua lai logo
47ed23e thay doi tren master branch
a89362e (tag: v1.4-lw, tag: v1.3, tag: v1.2, tag: v1.1, origin/master, origin/HEAD, phienban1) Update testdesktop.txt



Nếu để ý, trong kết quả của lệnh $ git merge có dòng chữ “fast-forward”. Chữ fast-forward nghĩa là “tua nhanh”, hiểu nôm na là tiến nhanh về phía trước. Tại sao lại có chữ này ở đây? Quan sát ở hình minh họa phía trên sẽ thấy: nhánh master đang trỏ tới commit C2, hotfix đang trỏ tới commit C4, mà C4 lại là commit kế tiếp của C2. Như vậy, thực sự ở đây không có sự “tích hợp” nào hết, mà Git chỉ đơn giản di chuyển con trỏ của nhánh master tiến về phía trước. Kết quả là cả hai nhánh master và hotfix đểu trỏ tới commit C4. Fast-forward nghĩa là  “tích hợp mà như không tích hợp”.

Vậy là việc sửa lỗi đã hoàn thành, con trỏ trong nhánh master đang trỏ tới commit mới nhất, và website đã sẵn sàng cho người dùng sử dụng.

Sửa lỗi xong, bạn đã có thể quay lại công việc dở dang khi trước. Nhánh hotfix bây giờ không cần thiết nữa, nhánh master đang chứa tất cả các commit của hotfix rồi, vì vậy bạn có thể xóa hotfix đi (nhắc lại: nhánh chỉ là một tập tin chứa 40 kí tự, đó là giá trị SHA-1 của commit mà nhánh đó trỏ tới).

Để xóa một nhánh, sử dụng lệnh $ git branch với tham số -d.

Ví dụ,

$ git branch -d hotfix
Deleted branch hotfix (was e31a627).

Bạn quay lại nhánh iss53 để làm việc, thực hiện commit.

Ví dụ,

$ git checkout iss53
Switched to branch 'iss53'
$ git commit -m "da them logo [issue 53]"
[iss53 b765740] da them logo [issue 53]
 1 file changed, 1 insertion(+)
$ git log --oneline --decorate --all --graph
* b765740 (HEAD -> iss53) da them logo [issue 53]
* 1cef1be them logo cho home page
| * e31a627 (master) sua lai logo
|/
* 47ed23e thay doi tren master branch

Xem hình minh họa,



Để ý là công việc bạn đã thực hiện trong nhánh hotfix sẽ không có trong nhánh iss53. Muốn tích hợp công việc mà bạn đã thực hiện trên nhánh hotfix vào nhánh iss5, có hai cách: một là đứng tại nhánh iss53, tích hợp nhánh master vào; hai là chờ tới khi bạn quyết định trộn nhánh iss53 vào nhánh master.

Lab 29. Hiểu về phân nhánh và fast-forward.

– Làm việc cá nhân

– Tạo một local repo

– Sau mỗi câu lệnh có dấu (*), sử dụng lệnh $ git log --oneline --decorate, hoặc --all --graph để xem kết quả, ghi lại kết quả của mỗi bước

– Thay đổi nội dung trong local repo và thực hiện 03 commit (*)

– Tạo nhánh mới, đặt tên là iss100 (*)

– Chuyển sang nhánh iss100 thực hiện 02 commit (*)

– Quay về nhánh master, tạo nhánh mới có tên hotfix01 (*)

– Chuyển sang nhánh hotfix01, thực hiện thay đổi trên local repo và commit 02 lần (*)

– Tích hợp nhánh hotfix01 và nhánh master (*)

– Xóa nhánh hotfix01 (*)

– Chuyển sang nhánh iss100, thay đổi trên local repo và thực hiện commt 02 lần (*)


– Fast-forward là gì? nó xảy ra khi nào?
</////12
-----------
Cập nhật [27/05/2020]
-----------
Xem thêm: Tổng hợp các bài viết về Làm web
Xem thêm: Làm web (13) - Git: tích hợp căn bản