Trước khi bắt đầu bài viết này cho mình xin phép tâm sự đôi lời. Hiện tại thì mình cũng đang là một developer. Mình gặp rất nhiều bạn newBie, mới vào nghề, chưa có kinh nghiệm làm việc nhiều nên hầu hết các bạn này rất lúng túng khi làm việc với Git (Git cơ bản thôi nhé), hoặc thậm chí có bạn còn chưa biết Git là gì, chưa biết làm việc với nó như thế nào. Trên quan điểm của mình, việc này không phải lỗi của bạn ấy, chẳng qua các bạn ấy chưa có cơ hội để sử dụng Git, nên chưa tìm hiểu. Nhưng, sẽ là lỗi của các bạn ấy, nếu trong dự án sử dụng Git mà lại không tìm hiểu.
Vậy nên, mình xin mạnh dạn chia sẻ về Git trong bài viết này với hy vọng sẽ giúp ích được những bạn đang ở trong trường hợp kể trên. Hoặc chí ít cũng là một tài liệu tham khảo hữu ích để giúp các bạn mới có thể hiểu Git hơn, tự tin làm việc trôi chảy với Git hơn. Mặc dù, đây không phải là kiến thức cao siêu gì. Mình xin kết thúc lời mở đầu của mình tại đây. Các bạn hãy dành một chút xíu thời gian để lướt qua Table of contents (mục lục) ở bên phải màn hình nhé. Nào, xin mời các bạn vào phần chính.
Trước hết, hãy bắt đầu với VCS. VCS là gì? VCS là viết tắt của Version Control System tạm dịch là Hệ thống quản lý phiên bản. Sỡ dĩ được gọi như vậy là vì các VCS sẽ lưu trữ tất cả các file trong dự án và ghi lại toàn bộ lịch sử thay đổi của file, mỗi sự thay đổi được lưu lại sẽ được phiên bản hóathành một version (phiên bản). (Để ý giúp mình từ “được lưu lại”, mình sẽ giải thích thêm ở phần Commit).
Và tất nhiên, bạn có thể xem lại danh sách các sự thay đổi của file như xem một timeline của các version. Mỗi version bao gồm: nội dung file bị thay đổi, ngày giờ sửa đổi, người thay đổi là ai, lý do thay đổi hay tên version…
Có hai điều quan trọng nhất để tạo ra một VCS:
Đối với các hệ thống VCS, hiện tại chúng được phân ra gồm ba loại dựa trên cách lưu trữ và chia sẻ các phiên bản:
Trong nội dung hôm nay mình không đề cập nhiều tới phần này. Các bạn vui lòng tham khảo thêm tại đây.
Git
chính là một hệ thống VCS cho dự án của bạn. Chính vì là một VCS ở trên nên Git cũng ghi nhớ lại toàn bộ lịch sử thay đổi của source code trong dự án. Bạn sửa file nào, thêm dòng code nào, xóa dòng code nào, bỏ thừa dấu ở đâu .etc. Tất tần tật đều được Git ghi lại.
Điểm khác biệt của Git so với các VCS khác (như Subversion…) chính là “cách Git nghĩ về dữ liệu”. Phần lớn các hệ thống khác coi thông tin được lưu trữ như là một tập hợp các file kèm theo các thay đổi được thực hiện trên mỗi file theo thời gian, như hình bên dưới.
Tuy nhiên ở Git, lại coi thông tin được lưu trữ là một tập hợp các snapshot (ảnh chụp toàn bộ nội dung tất cả các file tại thời điểm). Mỗi khi bạn “commit”, Git sẽ “chụp” và tạo ra một snapshot cùng một tham chiếu tới snapshot đó, như này:
Đó là cách Git nghĩ về dữ liệu. Để cài đặt Git, vui lòng truy cập trang Download của Git để tải về và làm theo hướng dẫn cài đặt.
Sau khi cài đặt, Git được sử dụng thông qua cửa sổ dòng lệnh với terminal (command-line). Ví dụ như này:
1
2
3
4
5
6
|
<span class="token function">git</span> init
<span class="token function">git</span> add <span class="token keyword">.</span>
<span class="token function">git</span> commit -m <span class="token string">"Save my first changed"</span>
|
Ngoài ra cũng có một số GUI tool giúp bạn dùng mà không phải dùng lệnh. Nhưng mà mình thấy nó chẳng cần thiết chút nào. Dùng terminal là xong hết, mà lại đơn giản. Dùng tool lại phải cài đặt, rồi phải học cách dùng, bla bla… 😄
Trong bài này, chúng ta sẽ sử dụng Git trên terminal nhé. Không có tool tiếc gì ở đây 😛 cả.
Trong Git, Repository là một kho chứa, lưu trữ source code của bạn. Có hai loại repository, mình tạm gọi là:
1
2
3
4
5
|
# Create local repository:
> git init
Initialized empty Git repository in /home/ubuntu/my-project/.git/
|
1
2
3
|
> git init
|
2. Tạo một local repository từ server repository:
1
2
3
|
> git clone repository_url
|
Đó là tổng kết toàn bộ kiến thức về repository trong Git. Bây giờ chúng ta hãy chuyển sang phần tiếp theo nhé!
Tiếp đây cũng là một khái niệm quan trọng của Git nên các bạn chú ý nha. Cho bạn xem một cái ảnh này trước đi ha (Ảnh Google):
Quay lại với bức hình cái cây ở trên. Bạn để ý sẽ thấy trên mỗi cành đều có những quả tròn màu xanh, đỏ, vàng. Mỗi quả tương ứng với một “commit”. Vậy commit là gì?
Trên mỗi branch bạn làm việc, sau khi sửa đổi các file source code… Những thay đổi đấy cần được lưu lại bằng cách tạo ra một điểm mốc đánh dấu. Điểm đánh dấu các thay đổi này gọi là Commit. Tại mỗi commit, git chụp lại toàn bộ dữ liệu, tạo ra một snapshot version hóa dữ liệu.
Như vậy, một version mới được tạo ra bằng cách tạo một “commit” cho các sự đổi của dữ liệu.
Mỗi commit được tạo ra gồm một số thông tin chính:
1
2
3
4
5
6
7
8
9
10
11
|
# Cú pháp: git commit -m
> git commit -m "Message mô tả thay đổi"
# Lưu lại thay đổi nhưng gì đè lên commit trước đó:
> git commit --amend -m "Message mô tả thay đổi"
# Ghi đè commit trước đó và đổi người tạo commit:
# git commit --amend --author "Your name " # Chú ý ghi cả dấu < > trong case này.
> git commit --amend --author "Nguyen Huu Kim "
|
Xem lại danh sách n
các commit đã tạo gần đây:
1
2
3
4
5
6
|
# Cú pháp: git log -
> git log -5
# Hiển thị mỗi commit trên một dòng
> git log --oneline -5
|
So sánh cá thay đổi của code trước khi add thay đổi vào commit
1
2
3
|
> git diff
|
Tạo commit vào message trên nhiều dòng (mặc định chỉ trên một dòng), sử dụng dấu '
thay thế "
khi tạo message:
1
2
3
4
|
> git commit -m '- First line
> - Second line'
|
Gộp nhiều commit làm 1 commit. VD: Gộp 3 commit gần nhất làm 1.
1
2
3
|
> git rebase -i HEAD~3
|
1
2
3
4
5
|
pick fd3fea3 Three
pick fd3fea2 Two
pick fd3fea1 One
|
Dòng commit đầu giữ nguyên, hai dòng thứ 2, 3 sửa pick thành s
để gộp. Sửa pick
thành d
để xóa commit tại dòng đó. Ctrl+O, Enter để lưu lại.
#
vào đầu dòng các commit message để loại bỏ message đó. Để lại một message cho commit mới sau khi gộp. Ctrl+O, Enter lưu lại là xong.
1
2
3
|
> git fetch <remote_name> <target_branch_name>:<target_branch_name>
|
Rebase lại target branch
1
2
3
|
> git rebase <target_branch>
|
Sau khi chạy lệnh rebase, những file bị conflict sẽ hiện thị với từ khóa conflict. Bạn mở các file đấy lên và xem những phần code bị conflict. Những đoạn code này sẽ được chia ra thành 2 phần, phần nửa trên là code hiện tại của target_branch, nửa dưới là code mà bạn đang sửa. Hãy đọc và giữ lại những phần code phù hợp. xóa bỏ các dấu == phân cách.
1
2
3
4
|
> git add .
> git rebase --continute
|
Trường hợp bạn chưa biết resolve những đoạn conflict như nào, có thể huỷ bỏ quá trình rebase bằng cách:
1
2
3
|
> git rebase --abort
|
Trước khi tạo một commit, nếu bạn chưa config thông tin định danh của bạn, git sẽ yêu cầu bạn config thông tin định danh của bạn trước khi cho phép commit. Câu lệnh config:
1
2
3
4
|
> git config user.name "Nguyen Huu Kim"
> git config user.email "kimnh@webee.asia"
|
Trong một project, mình hay ví von vui như này. Nếu mình coi Repository bên trên như là một cái gốc cây. Thì Branch sẽ các cành, các nhánh con phát triển từ cái gốc (Repository) mà thành như hình cái cây bên trên. Như bạn biết, một cái cây thì phải có một thân cây to đùng. Cái thân cây cũng chẳng qua chỉ là một cái nhánh (branch), chỉ khác là nó to mà thôi. Và nó là cái Branch chính để sinh ra (checkout) những branch nhỏ hơn tạo thành một cây project sum sê. Trong Git, cái thân cây đó chính là branch chủ đạo có tên là master 😄.
Như đã trình bày, master branch là nhánh chính. Sau khi bạn dùng lệnh tạo repository, master branch sẽ tự động được tạo ra. “Commit” của các thay đổi đầu tiên được tạo cũng sẽ được lưu vào master branch. Hãy tưởng tượng, nếu sau khi tạo repository, bạn chỉ có lưu các thay đổi lại dưới dạng một commit. Như vậy, tất cả chỉ source code của project chỉ lưư tập trung tại một branch master, và cái cây Git này nó đang là một cây thân cọc trơ trụi 😄.
Một dự án công nghệ thì có nhiều tính năng, khi bạn đang code dở chừng một chức năng A nhưng khách hàng thay đổi muốn có chức năng B trước, hoặc họ muốn phát triển đồng thời cả hai. Rõ ràng, chúng ta không thể lưu chung tại một branch master mãi được. Do đó, branch sinh ra để giải quyết vấn đề này. Mỗi branch cho các chức năng A, B riêng và phát triển riêng biệt. Và chúng ta có thể lưu lại công việc dở dang trên mỗi branch, chuyển đổi qua lại giữa chúng; Cũng có thể gộp hai branch lại. Và bây giờ, cái cây thân cọc đã mọc thêm nhiều branch từ master
branch.
Học đi đôi với hành, hãy đút túi những câu lệnh sau để sử dụng branch trong Git nhé. Giả sử bạn đang ở master sau khi tạo mới repository nhé.
feature/a
:
1
2
3
4
5
6
|
# Cách 1, chỉ thực hiện tạo branch:
> git branch feature/a
# Cách 2, tạo mới branch và chuyển luôn sang branch đấy để code:
> git checkout -b feature/a
|
2. Xem danh sách branch hiện có:
1
2
3
4
5
|
> git branch
feature/a
* master
|
Branch hiện tại bạn đang working sẽ có dấu *
ở đầu dòng. Khi có qua nhiều branch trong danh sách, git sẽ hiển thị dạng ScrollView, bạn nhấn nút điều hướng lên/xuống để cuộn lên/xuống. Muốn thoát khỏi chế độ cuộn, gõ:
1
2
3
|
> :q
|
Rồi nhấn Enter
để thoát khỏi danh sách.
1
2
3
4
5
|
> git checkout <branch_name>
# Ví dụ:
> git checkout feature/a
|
Khi muốn chuyển sang một branch khác, hãy hết sức lưu ý rằng bạn cần phải tạo thói quen commit lại các thay đổi trước khi chuyển bằng lệnh:
1
2
3
|
> git commit -m "My message for note"
|
1
2
3
4
5
6
|
# Xóa local branch
> git branch -D branch/name
# Xóa remote branch
> git push remote_name branch/name --delete
|
2. Đẩy code lên remote branch
1
2
3
4
5
6
|
# Cú pháp: git push
> git push origin master
# Nếu muốn bắt buộc ghi đè lên remote branch, thêm -f (force)
> git push orgin master -f
|
3. Merge branch, để merge code từ nhánh B vào nhánh A.
1
2
3
|
> git checkout A
|
1
2
3
|
> git merge B
|
Để đẩy code lên server repository, chúng ta cần các tham chiếu tới server repository tương ứng. Các tham chiếu này được gọi là Remote
. Mỗi remote sẽ có các thông tin:
Khi sử dụng URL dạng HTTP, mỗi khi bạn thao tác với server repository bạn sẽ phải nhập username và password. Còn URL dạng cho ssh, bạn sẽ không phải nhập username, password nữa.
Mặc định, sau khi clone một repository về máy, remote tham chiếu tới server repository được gán tên là
origin
.
Như bạn đã biết ở trên, mỗi repository có các branch. Local repository của chúng lại tham chiếu tới nhiều repository khác thông qua remote. Dĩ nhiên các repository này sẽ có các branch bị trùng tên với nhau, chẳng hạn như master
. Vậy làm sao phân biệt branch nào của repository nào?
Câu trả lời là Remote Branch. Các remote branch cũng là các branch bình thường, nhưng có prefix được git thêm vào chính là tên của remote.
VD: Chúng ta có:
1
2
3
4
|
# Cú pháp: git remote add
> git remote add upstream git@github.com/kimnguyen-ict/demo-repository.git
|
2. Xem danh sách remote đang có:
1
2
3
|
> git remote -v
|
3. Thay đổi url của remote
1
2
3
4
|
# Cú pháp: git remote set-url
> git remote set-url upstream https://github.com/kimnguyen-ict/demo-repository
|
4. Thay đổi tên của remote
1
2
3
4
|
# Cú pháp: git remote rename
> git remote rename upstream demo
|
5. Xóa một remote
1
2
3
4
|
# Cú pháp: git remote remove
> git remote remove demo
|
Để làm việc với Git hiệu quả, cả team của dự án cần tuân thủ các quy tắc của git flow.
master
và develop
. Master chứa code hoàn chỉnh, sử dụng để deploy lên production. Develop chứ code mới nhất đang được phát triển; sử dụng để deploy lên server testing. Hai nhánh này cần được bảo vệ (protected), chỉ người có quyền mới merge, push commit lên nhánh này.feature/branch-name
hoặc fix/feature-a
và làm việc trên branch đó. Sau khi hoàn thành, commit lại và tạo merge request (pull request) về repository gốc.Flow chính: Code sửa đổi -> Merge code vào develop -> testing -> merge develop vào master cho production.
Lúc này, quá trình làm việc với git flow có thể được mô tả qua bức ảnh sau:
Trên đây là Sổ tay Git cơ bản cho các bạn mới tìm hiểu về Git. Mọi ý kiến đóng góp bổ sung thêm hoặc sửa đổi, mời mọi người comment vào bên dưới để mình cập nhật vào bài viết. Chân thành cảm ơn các bạn đón đọc. Hy vọng bài này sẽ hữu ích cho mọi người, chúc mọi người thành công!
Nguồn: Sưu tầm từ internet Via Viblo