Trong khi làm việc với Git, bạn đã quá quen thuộc với việc chỉnh sửa mã nguồn, sau đó là commit mỗi khi chỉnh sửa xong và push lên remote repository nếu cần thiết. Nhưng bây giờ mình có một ví dụ đặt ra là mình muốn tạo một phiên bản thử nghiệm với mã nguồn đang làm việc trong working tree hiện tại mà không gây ảnh hưởng đến các code hiện tại. Vậy thì làm cách nào? Không lẽ clone một repository từ chính cái working tree hiện tại rồi sửa đổi hay sao? Như thế rất là mất công, mà lại không tối ưu và không thể đồng bộ hóa hoặc rất khó khăn để đồng bộ hóa.
Mà trong Git, chúng ta sẽ sử dụng một giải pháp khác tuyệt vời hơn, dễ dàng hơn gọi là phân nhánh (branching), mà cụ thể là phân nhánh cái gì? Đó là phân nhánh trong working tree hiện tại bạn đang làm việc đấy, và mỗi nhánh chúng ta sẽ gọi nó là một branch.
Branch trong Git là gì?
Khi bắt đầu khởi tạo một repository hoặc clone một repository, bạn sẽ có một nhánh (branch) chính tên là master
(bạn có thể hiểu master là một cái thân cây). Đây là branch mà sẽ chứa toàn bộ các mã nguồn chính trong repository.
Đó là lý do tại sao, ở các phần trước khi chúng ta push hoặc pull hay làm một số việc khác thì lại có tham số master
trong câu lệnh, đó nghĩa là chúng ta đang thực hiện thao tác trên branch master
.
Nhánh Master là nhánh chính mặc định trong working tree. Bạn có thể tạo ra một (hoặc nhiều nhánh mới) với tên là Develop chẳng hạn
Bây giờ nếu bạn muốn tạo một sự thay đổi nào đó mà có thể trực tiếp sử dụng trên working tree hoặc commit, push lên repository mà không ảnh hưởng đến branch master thì sẽ cần tạo ra một branch mới với tên là develop
chẳng hạn. Và từ đó mỗi khi bạn thực hiện lệnh checkout vào branch nào đó thì toàn bộ mã nguồn trên working tree của bạn sẽ được đổi sang môi trường dành cho branch đang checkout.
Ngoài ra còn một cách khác để kiểm tra đó là đọc tập tin .git/HEAD
Cách tạo một branch
Trước tiên bạn có thể xem toàn bộ các branch mà bạn đang có trong working tree bằng lệnh git branch
. Sau đó nếu muốn tạo thêm branch, chỉ cần gõ lệnh git branch tên_brand
. Ví dụ mình cần tạo branchdevelop
.
Bây giờ bạn có thể gõ lại lệnh git branch
một lần nữa để xem sẽ thấy brand tên develop xuất hiện.
Checkout một branch
Checkout ở đây nghĩa là bạn truy cập kiểm tra mã nguồn trong branch đó để làm việc đấy. Để làm việc này, bạn sử dụng lệnh git checkout tên_branch
.
Lúc này bạn đã đổi sang branch develop
rồi, để kiểm tra chắc ăn bạn có thể gõ các lệnh kiểm tra HEAD ở trên.
Bây giờ bạn sẽ làm việc trong branch mới chuyển hay nói đúng hơn là bạn đang làm việc ở chỗ mà cái HEAD đang trỏ tới. Để chuyển về branch chính thì gõ git checkout master
.
Bây giờ bạn thử tạo một tập tin nào đó, sau đó commit ở branch develop
rồi chuyển về branch master sẽ thấy những gì bạn đã làm ở branch develop
hoàn toàn vô nghĩa ởmaster
. Dưới đây là ví dụ về việc ở branch master
không có tập tin develop.html được tạo ra từ branch develop
.
Tương tự với việc sửa tập tin hay bất kỳ làm việc gì khác nó cũng chỉ áp dụng thay đổi ở branch bạn đang trỏ tới.
Gộp dữ liệu từ một branch
Nếu mỗi branch nó nằm riêng như vậy thì bạn muốn sử dụng các thay đổi ở một branch nào đó cho master thì sao? À, chúng ta có thể sử dụng lệnh git merge để chuyển dữ liệu từ một branch nào đó về branch mà bạn đang trỏ đến. Lưu ý là ở branch cần chuyển về đã phải được commit. Ví dụ mình cần chuyển dữ liệu từ branch develop về master thì sẽ làm lần lượt các lệnh sau:
Xóa branch
Nếu bạn không cần dùng tới branch nào nữa thì có thể xóa với lệnh git branch -d tên_branch. Lưu ý là cái branch muốn xóa phải được gộp dữ liệu (merge) về master.
Sau khi xóa xong, nó sẽ báo branch đó đã được móc vào commit với mã checksum nào (8c68896).
Làm việc với remote branch
Quay lại một xíu với bài remote repository, bây giờ bạn hãy tạo thêm một remote mới từ địa chỉ https://github.com/csswizardry/inuit.css và đặt tên cho remote này là inuit vào working tree của bạn.
Bây giờ bạn có thể xem toàn bộ branch của cái remote inuit
mới thêm vào bằng lệnh git remote show inuit
.
Bây giờ bạn có thể chọn một cái remote branche cần fetch dữ liệu về. Ví dụ bây giờ mình sẽ tạo một branch mới cho working tree của mình tên làfix_ui
, sau đó nạp dữ liệu trong branch gh-pages
của inuit
thì mình sẽ lần lượt làm như sau.
Có thể nó sẽ xảy ra lỗi conflict khi gộp file README.md cũng không quan trọng lắm nên bạn có thể bỏ qua bằng cách gõ lệnh git add README.md
để track file này, vì bây giờ nếu bạn gõ lệnh ls
ra thì đã có các file từ inuit rồi.
Bây giờ bạn có thể commit nó và thử push nó lên repository của bạn.
$ git commit -m “Commit from fix_ui”
Commit from fix_ui
$ git push thach fix_ui
Counting objects: 317, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (201/201), done.
Writing objects: 100% (317/317), 135.77 KiB | 0 bytes/s, done.
Total 317 (delta 113), reused 304 (delta 106)
To https://github.com/rinpcb/Code
* fix_ui -> fix_ui
Và dĩ nhiên, bạn cũng có thể qua một branch khác và sử dụng lệnh git merge
để gộp dữ liệu của branch này về.
Ngoài ra, kiến thức về branch còn có một kỹ thuật nữa cũng khá thú vị mà khi làm việc nhóm có thể sẽ cần đến, đó là rebase branch với mục đích hoán đổi vị trí của những lần commit. Tuy nhiên ở đây là serie cơ bản nên mình sẽ không nói qua mà bạn chỉ cần sử dụng thành thạo các kỹ thuật mà mình đã liệt kê trong đây là được.
Lời kết
Vậy là tới đây mình đã kết thúc hướng dẫn xong các kỹ thuật quan trọng nhất trong Git mà bạn dù bất cứ sử dụng Git trong mục đích nào cũng phải sử dụng. Mình cũng đã hướng dẫn cặn kẽ nhất theo cách hiểu của mình theo hướng đơn giản nhất nên mình hy vọng bạn có thể hiểu nó. Tiếp tục ở bài sau, mình sẽ không nói qua về các kỹ thuật trong Git nữa mà mình sẽ giới thiệu cho các bạn một số dịch vụ máy chủ repository dành cho Git tốt nhất và đặc biệt là có gói miễn phí để bạn có thêm nhiều lựa chọn.