Mô hình sử dụng GIT và một số lệnh hay dùng
Mô hình sử dụng GIT
Việc quản lý branch trong GIT rất linh động, do đó thường mỗi công ty sẽ sử dụng mô hình riêng cho phù hợp với hiện trạng công ty.
Thường khuyến khích mọi người sử dụng mô hình sau: A successful Git branching model
Theo mô hình này sẽ có hai nhánh chính:
- master: Đây là nhánh chính thứ nhất, nơi chứa source code sẵn sàng để triển khai.
- develop: Đây là nhánh chính thứ hai, chứa source code phát triển mới nhất cho lần triển khai sắp tới. Nhánh này là nhánh tích hợp, chứa các commit hàng ngày của các thành viên phát triển. Khi nào nhánh này đạt đến trạng thái "ổn định", sẵn sàng cho việc triển khai thì sẽ được merge sang nhánh master. Việc merge từ develop vào master cần phải được kiểm soát chặt chẽ để đảm bảo an toàn.
Bên cạnh hai nhánh chính ở trên, chúng ta còn sử dụng thêm các nhánh hỗ trợ khác để hỗ trợ phát triển song song giữa các Nhóm/Thành viên, theo dõi việc phát triển theo từng tính năng, chuẩn bị release sản phẩm hoặc khắc phục nhanh các lỗi trên môi trường thật. Không giống như các nhánh chính, các nhánh này luôn có thời gian sống hạn chế, vì chúng sẽ bị loại bỏ cuối cùng.
- Feature branches: Nhánh sử dụng để phát triển tính năng mới cho bản triển khai sắp tới hoặc trong tương lai xa. Bản chất nhánh này tồn tại khi tính năng đang được phát triển, được merge vào nhánh develop nếu thành công và bị loại bỏ nếu thử nghiệm không thành công. Tên nhánh thường đặt theo tên feature để tiện theo dõi.
- Release branches: Tên nhánh này thường đặt theo cú pháp: release-*
- Hotfix branches: Tên nhánh này thường đặt theo cú pháp: hotfix-*
Sau khi triển khai source code trên nhánh master thành công trên môi trường thật, thì thực hiện tag lại để lưu lại commit được sử dụng để triển khai.
Một số lệnh hay dùng trong GIT
Tham khảo: https://hackmd.io/LyrNou22RXu5n9NAKMEn6Q
Bảo vệ branch master
Thông thường, nhánh master là nhánh quan trọng, chứa source code triển khai, vì vậy nhánh master này cần phải được bảo vệ để tránh các lệnh nguy hiểm.
Để bảo vệ nhánh master này, bạn vào giao diện trên web, chọn Project => Vào mục Setting của Project => Repository:
Tại giao diện này, bạn có thể Protect/Unprotect một nhánh bất kỳ. Nhánh master luôn luôn phải được Protect để đảm bảo an toàn.
Tạo tag
Sau khi source trên nhánh develop được triển khai, source trên nhánh develop sẽ được merge sang nhánh master. Chúng ta cần đánh dấu lại commit này trên master tương ứng với lần triển khai.
Chúng ta tạo tag để làm việc này. Lệnh tạo tag như sau:
git tag -a v5.0 -m "Create tag for release: Support new LTC coin"
git push origin v5.0
Checkout tag bằng lệnh sau:
git fetch --all --tags --prune
git checkout tags/<tag_name> - b <branch_name>
git checkout tags/v5.0 -b v5.0
Tạo branch mới
Hiện tại bạn đang sửa code ở Local và muốn đẩy code ở Local lên Server, bạn sử dụng lệnh sau (branch_name là tên branch do bạn đặt):
git checkout -b branch_name
git push origin branch_name
Bạn muốn clone source code từ master sang một branch mới, bạn sử dụng lệnh sau (branch_name là tên branch do bạn đặt):
git checkout master
git pull
git checkout -b branch_name
git push origin branch_name
Xóa branch
Trong thời gian phát triển sẽ có nhiều nhánh thừa, nhánh tạm và bạn sẽ có nhu cầu xóa bỏ chúng.
Xóa remote branch
Lệnh xóa một remote branch (Branch trên server) như sau:
git checkout branch_name
git pull
git push origin --delete branch_name
Xóa local branch
Lệnh sau ép xóa một branch ở local, khi xóa phải đứng ở một branch khác:
git checkout master
git pull
git branch -D branch_name
Merge source code
* C1: Sử dụng giao diện Web
Thông thương khi phát triển sẽ tạo nhiều branch khác nhau và sẽ có nhiều lúc bạn cần thực hiện lệnh merge source code giữa hai nhánh.
Để an toàn bạn nên thực hiện lệnh merge trên website: Chọn Project => Merge Requests => Kích nút "New merge request":
* C2: Sử dụng Rebase
Sử dụng rebase sẽ giữ lại được hết các commit nhưng bù lại thì nó phức tạp hơn và có nhiều rủi ro hơn.
Lệnh sau để merge source code từ nhánh dev sang nhánh master:
git checkout master
git pull
git checkout dev
git pull
git rebase master
git checkout master
git merge --no-ff dev
git log --oneline
git push origin master
* C2: Sử dụng Merge
Để đơn giản thì tốt nhất nên dùng GIT MERGE sẽ an toàn hơn nhưng sẽ có 1 số commit không được lưu lại.
Ví dụ bạn muốn merge branch1 vào branch2 bạn thực hiện các lệnh sau:
git checkout branch1
git pull
git checkout branch2
git pull
git merge branch1
Xóa commit trên remote
Nếu bạn muốn lùi source code về commit trước đó bạn có thể thực hiện bằng 02 cách:
- C1: Tạo commit revert => Cách này sẽ tạo thêm một commit khác và khi đó các branch khác có liên quan commit này phải rebase lại.
- C2: Xóa trực tiếp commit này.
Để xóa một commit, branch phải đang ở chế độ Unprotect (Trên Git Web, vào Setting => Repository => Thực hiện "Unprotect").
Lệnh sau sẽ thực hiện xóa 01 commit gần đây nhất trên nhánh master:
git checkout master
git pull
git log --oneline
git reset --hard HEAD~1
git log --oneline
git push -f origin master
Lệnh sau sẽ thực hiện xóa 02 commit gần đây nhất trên nhánh master:
git checkout master
git pull
git reset --hard HEAD~2
git push -f origin master
Chú ý:
- Nếu xóa trên nhánh master, sau khi xóa xong cần phải Protect lại.
- HEAD~ tương đương với HEAD~1
- Nên sử dụng lệnh git log để kiểm tra lại commit
Lưu password cho GIT HTTP
Từ phiên bản 1.7.9 trở lên, GIT không tự động lưu password khi sử dụng HTTP/HTTPS vì vấn đề bảo mật.
Bạn muốn bật chế độ này phải đánh lệnh sau:
git config --global credential.helper store
Lệnh git reset
Tham khảo: https://www.atlassian.com/git/tutorials/undoing-changes/git-reset
Lệnh git reset là một công cụ phức tạp và linh hoạt để hoàn tác các thay đổi. Nó có ba hình thức gọi chính. Các hình thức này tương ứng với các đối số dòng lệnh --soft, --mixed, --hard. Ba đối số, mỗi đối số tương ứng với ba cơ chế quản lý trạng thái nội bộ của Git: The Commit Tree (HEAD), The Staging Index, và The Working Directory.
Bạn vừa add file A.js lên để chuẩn bị tạo commit, sau đó bạn không muốn đẩy file này trong commit nữa thì bạn sử dụng lệnh sau:
git reset HEAD A.js
Bạn vừa tạo 1 commit nhưng chưa push lên server, nhưng commit này của bạn chưa đúng các file mà bạn cần. Bạn muốn loại bỏ commit này để tạo lại, bạn có thể dùng lệnh:
git reset --soft HEAD~
Lệnh git diff
Lệnh sau hiển thị thay đổi ở tất cả các tệp:
git diff
Bạn muốn hiển thị các thay đổi của 1 file bạn đã sửa khi mà chưa thực hiện add hoặc commit:
git diff <file_path>
git diff auto-click.bat
Bạn có thể xem thay đổi của local với 1 branch nào đó:
git diff <branch> <file_path>
git diff branch auto-click.bat
Bạn có thể xem thay đổi của local với 1 commit nào đó:
git diff <commit> <file_path>
git diff 532f242 auto-click.bat
Trong trường hợp đã commit nhưng chưa push, bạn có thể xem các thay đổi bằng lệnh sau:
git diff --cached
git diff --cached client/html/container.html
Nếu bạn so sánh thay đổi của 1 tệp giữa hai commit bạn thực hiện lệnh sau:
git diff <commit1> <commit2> <file_path>
git diff 532f242 04c0252 auto-click.bat
Lệnh git difftool
Lệnh này tương tự lệnh git diff, nhưng sử dụng thêm công cụ thứ 3 để view.
Lệnh sau sẽ cho chọn công cụ:
git difftool client/html/container.html
Lệnh sau xác định luôn sử dụng công cụ nào:
git difftool --tool=winmerge
git difftool --tool=winmerge client/html/container.html
Tương tự cho các dạng khác.
Kiến thức thêm về GIT
So sánh giữa HEAD^ và HEAD~
Tham khảo: https://stackoverflow.com/questions/2221658/whats-the-difference-between-head-and-head-in-git