2023.11.29
GIT – 1 vài kiến thức cơ bản cần hiểu rõ
GIT – những kiến thức cơ bản cần nắm để hiểu rõ hơn về hoạt động của các lệnh mà bạn hằng ngày vẫn sử dụng
Những kiến thức liên quan đến tầng lưu trữ của GIT
Remote Repository
Là nơi lưu trữ source code, data… của dự án ở một server nào đó: Github, Gitlab, Bitbucket…
Ví dụ: https://github.com/marketenterprise/Corp-VN
Các lệnh thông thường mà các bạn thao tác đến remote repository:
$ git clone // download toàn bộ remote repository
$ git pull, $ git fetch // tải source code mới nhất về máy của bạn
$ git push // đưa source code từ máy bạn lên remote repository
$ git branch –all // hiển thị danh sách các branch hiện có ở remote repository
Local Repository
Là nơi lưu trữ source code, data… ở dưới máy tính của bạn
Các lệnh thông thường mà các bạn thao tác đến local repository
$ git fetch // tải source code mới nhất về vùng chứa local repository
$ git checkout, $ git switch // chuyển source code từ local repository sang workspace
$ git commit // đưa source code từ staging area hoăc workspace lên local repository
$ git branch // hiển thị danh sách hiện có ở local repository
Staging area
Là những thay đổi mà bạn muốn lưu tạm trước khi đưa lên local repository, để lưu tạm ở vụng này, bạn có thể sử dụng $ git add
Kiểm tra danh sách các file đang ở Staging area: $ git diff --name-only --cached
Workspace
Là một branch nào đó mà bạn đang thao tác (đang mở bằng một trình soạn thảo nào đó, mình thường xài visual studio code), để đưa một branch từ local repository qua workspace thì các bạn có thể sử dụng checkout hoặc switch đều được
Bạn muốn kiểm tra workspace đang ở branch nào bạn có thể sử dụng lệnh $ git status
hoặc $ git branch
Bạn muốn chuyển workspace sang nhánh khác, bạn có thể sử dụng lệnh $ git switch <branch>
HEAD
Đang trỏ tới commit cuối cùng của branch tại thời điểm mà bạn đã download branch đó về máy bạn
Bạn có thể sử dụng lệnh $ git show HEAD
để xem branch dưới máy của bạn đang ở commit nào
HEAD~<number>: để trỏ tới commit thứ mấy. Ví dụ: HEAD → commit cuối, HEAD~1 → commit trước commit cuối…
Sự nhầm lẫn có thể xảy ra giữa pull và fetch trong
Cả 2 lệnh đều tải source code mới nhất từ remote repository về máy của bạn, nhưng điểm ảnh hưởng đến vùng chứa thì sẽ có sự khác nhau:
$ git pull
sẽ đưa source code đến workspace$ git fetch
sẽ đưa source code đến local repository
Hãy xem 1 ví dụ dưới đây để bạn có thể hiểu rõ hơn
- Bạn đang phụ trách feature-1 cùng với một member khác
- Bạn đang develop ở branch feature-1 (workspace), member làm chung với bạn đã làm xong phần việc của mình, yêu cầu bạn lấy code mới về! Lúc này mình nên sử dụng pull hay là fetch?
- Nếu bạn sử dụng fetch để tải về, bạn sẽ không thấy code mới đâu cả, vì sao? Vì lúc này code mới sẽ nằm ở local repository chứ ko phải workspace
- Nếu bạn sử dụng pull để tải về, bạn sẽ thấy code mới ngay lặp tức
Hiểu rõ sự khác nhau giữa checkout và restore
Checkout có 2 chức năng: chuyển hoặc tạo nhánh và phục hồi dữ liệu của file
Restore chỉ có 1 chức năng: phục hồi dữ liệu của file
Có thể nói Restore là một phần của Checkout → Checkout = Switch + Restore
Việc sử dụng switch để chuyển/tạo nhánh vs restore để phục hồi file sẽ giúp các bạn đỡ rối hơn việc sử dụng checkout
Restore sẽ phục hồi dữ liệu từ HEAD và ảnh hưởng đến vùng mà bạn muốn phục hồi: workspace hoặc staging area, các bạn quay lại mục 1 để hiểu HEAD là cái gì nhá
Trong quá trình sử dụng restore, bạn sẽ thấy 3 option phổ biến
$ git restore --worktree
→ phục hồi file ở vùng workspace, các file ở index (đã add) sẽ không ảnh hưởng$ git restore --staged
→ phục hồi file ở vùng index$ git restore --source=<>
→ chỉ định nơi lấy dữ liệu để phục hồi
Với những file đã commit thì các bạn vẫn có thể restore được nhưng commit sẽ không mất đi, có nghĩa là file đó đã được phục hồi và đang ở trạng thái cần commit lại thêm lần nữa
Các bạn muốn bỏ commit đó ra thì hãy sử dụng reset để phục hồi nhé
- Ví dụ, bạn lỡ commit 3 lần, 2 lần trước đó là các commit bạn không muốn push lên thì hãy làm như thế này:
$ git reset --soft HEAD~2
Lựa chọn phù hợp giữa merge và rebase
Cả 2 lệnh này đều có một mục đích chung là kết hợp source từ các branch khác nhau vào một branch
Cái khác nhau ở 2 lệnh này là mục về mục đích bạn muốn giữ lịch sử commit ở dạng nào: hình xương cá hay hình mạch điện
Bên dưới là log của một dự án khi sử dụng merge
Việc sử dụng rebase sẽ giúp bạn xem log dễ dàng hơn nhưng bù lại là việc thao tác sẽ phức tạp hơn và dễ gây ra lỗi mất code khi member của team bạn không thao tác thuần thục, vì khi thực hiện rebase, nếu có conflict xảy ra thì việc xử lý sẽ phức tạp hơn merge nhiều.
Nếu các bạn muốn sử dụng rebase cho dự án để quản lý log đơn giản hơn thì hãy chú ý tới một TIP: squash commit
Có 1 vài cách để squash commit, sử dụng $ git rebase -i <commit đầu của branch>
hoặc $ git reset --soft <commit đầu của branch>
. vì mục đích là quản lý log dễ dàng nên squash sẽ giúp bạn gom các commit lại thành 1, mỗi khi rebase 1 branch vào main thì tương ứng là 1 commit
Dưới đây là hình ảnh mô tả vì sao việc rebase sẽ giúp bạn xem log dễ dàng hơn, và nếu sử dụng rebase kèm với squash commit thì log sẽ đẹp đến mức nào
Kết luận
Việc các bạn hiểu rõ hơn cách thức lưu trữ của GIT, ý nghĩa của từng câu lệnh sẽ giúp bạn thao tác dễ dàng hơn cũng như sẽ bớt đi các câu hỏi: Tại sao không thấy source code mới? Làm gì để phục hồi lại file đã lỡ add hoặc commit?…