Tạo mới một Repository mới
Trong Git một Repository là một kho chứa (nó chứa các file mã nguồn của bạn, cơ sở liệu Git). Giả sử bạn có một dự án lưu C:\Path\projectcode
, chúng ta sẽ chuyển thư mục đó trở thành một Local Repository Git, để giám sát sự thay đổi các file trong thư mục dự án đó. Trước hết ta tìm hiểu về các trạng thái của file trong một Repo
Vòng đời các file trong Git có thể ở một trong các trạng thái được biểu diễn như hình.
Để biết trạng thái các file trong dự án ở trạng thái nào dùng lệnh kiểm tra trạng thái
git status
- Với vòng đời một File trong Git như trên, ta thấy đầu tiên file mới thì nó ở trạng thái untracked (không được giám sát phiên bản).
- Từ trạng thái untracked dùng lệnh Git để đưa nó vào trạng thái staged, khi ở staged có nghĩa là file được đưa vào kế hoạch để lưu (mới hoặc cập nhật) vào CSDL của Git (kế hoạch thôi - chưa thực sự có trong CSDL Git) - và bắt đầu theo dõi
- Ở trạng thái staged (chuẩn bị cho cập nhật vào CSDL - tạo mới hoặc update) dùng lệnh Git để cập nhật vào CSDL Git, gọi là
commit
- Sau khi cập nhật xong thông tin đầy đủ về File ở phiên bản cuối đã tồn tại trong CSDL Git và File sẽ ở trạng thái là unmodified - Ở trạng thái unmodified, nếu File bị sửa đổi nội dung (bạn thêm dòng code chẳng hạn) thì lập tức nó chuyển sang trạng thái modified, từ modified nếu muốn cập nhật sửa đổi vào dữ liệu Git thì lại dùng lệnh Git đưa nó vào trạng thái staged mang ý nghĩa kế hoạch cập nhật. Rồi lại commit để cập nhật vào CSDL và file lại vào trạng thái unmodified
- Hoặc Ở trạng thái unmodified, file được xóa khỏi CSDL Git để chuyển lại về không theo dõi untracked
Các Video: Sử dụng Git, GitHub
1 Tạo Local Repo
$ cd /c/Path/projectcode/ $ git init Initialized empty Git repository in C:/Path/projectcode/.git/
Sau lệnh đó thì thư mục projectcode
đã trở thành một Local Repo, bên trong nó gồm có các file code mà có thể đưa vào bất ký lúc nào, và một thư mục .git
chứa toàn bộ dữ liệu Git về Repo này.
Bắt đầu giám sát các file trong thư mục làm việc
Thời điểm này Git chưa giám sát một file nào chứa trong thư mục làm việc (là thư mục lưu dự án của bạn c:\Path\projectcode\
)
Giả sử trong thư mục dự án đang tồn tại các file:
about.html index.html abc.tmp
Gõ lệnh xem trạng thái hiện tại:
$ git status On branch master No commits yet Untracked files: (use "git add..." to include in what will be committed) abc.tmp index.html about.html
Qua đó cho biết tình trạng hiện tại như sau: Đang làm việc trên nhánh master
, đây là nhánh chính mặc định được tạo ra (ta sẽ tìm hiểu về nhánh sau), các file abc.tmp, index.html trong dự án ở trạng thái untracked có nghĩa là không được Git giám sát.
2 Đưa file mới vào staged giám sát
Để đưa file index.html vào giám sát gõ lệnh sau:
$ git add index.html
Xem lại trạng thái
$ git status Changes to be committed: new file: index.html Untracked files: abc.tmp about.html
Trạng thái hiện tại là file index.html
đã được đưa vào khu vực staged là nơi chứa những gì mà sẽ commit
ghi dữ liệu vào database của Git. Nhưng file abc.tmp
, about.html
vẫn là untracked
Những file khác muốn giám sát thực hiện lệnh git add
theo cách tương tự. Ngoài ra để đưa vào staged một cách nhanh chóng sử dụng một số trường hợp đặc biệt như:
$ git add *.c #Thêm tất cả các file có phần mở rộng .c $ git add . #Thêm tất cả thay đổi, trừ xóa file $ git add -A #Thêm tất cả thay đổi
3 Đánh dấu file bị lờ đi không giám sát
Trong thư mục dự án có thể có những file mà không muốn Git giám sát (phổ biến là các file trong thư mục trình biên dịch sinh ra, các file tạm ...). Nếu muốn lờ đi file nào, thư mục nào thì Git hỗ trợ khai báo chúng trong một file có tên là .gitignore
, bạn chỉ việc tạo ra file có tên như vậy ở thư mục dự án vào khai báo bên trong nó những gì muốn lờ đi.
Từ dòng lệnh có thể gõ lệnh sau để tao ra file .gitignore
$ touch .gitignore
Mở file ra: giả sử sẽ lờ đi file abc.tmp
, lờ đi các file dạng *.log
, lờ đi các file trong thư mục build/Release
thì cập nhật nội dung trong file .gitignore
như sau:
abc.tmp *.log build/Release
4 Đưa tất cả các file vào staged giám sát
Tiếp theo gõ lệnh sau để thêm tất cả các file trong dự án vào staged (có lờ đi các file đánh dấu - đó là abc.tmp
)
git add .
Xem lại trạng thái hiện tại:
$ git status
On branch master
Changes to be committed:
new file: .gitignore
new file: about.html
new file: index.html
Như vậy toàn bộ dự án có 3 file đã đưa hết vào staged để sẵn sàng thực hiện commit đầu tiên.
5 Thực hiện commit đầu tiên
Việc thực commit là thao tác đưa toàn bộ nội dung trong staged vào dữ liệu của Git - nó tạo ra ảnh chụp toàn bộ thư mục làm việc ở thời điểm đó. Như sơ đồ trên nếu đã commit thì nó chuyển file từ trạng thái staged sang unmodified. Thực hiện commit với lệnh như sau:
$ git commit -m"C0 - Khoi tao du an"
6 Xem lịch sử commit
$ git log --oneline
2e276a4 (HEAD -> master) C0 - Khoi tao du an
master
bạn có một commit, commit đó có mã hash là 2e276a4
sau này sẽ làm việc nhiều với mã này. HEAD gọi là con trỏ trong Git, bạn tạm hiểu nó cho biết đang đứng ở đâu trong Repo (Như trường hợp này bạn đang ở master, ở commit có mã hash 2e276a4
). Ta ký hiệu commit đầu tiên này là C0 - snapshot, thì mô hình hóa Repo hiện tại như hình bên, con trỏ HEAD đang ở nhánh master, và Repo có một snapshot C0Clone một Remote Repo
Nếu có một Repository đang lưu trữ ở một dịch vụ Git nào đó, ví dụ có Remote Repository - https://github.com/ichte/xtlab, thì có thể sao về máy để thành Local Repo bằng lệnh:
git clone https://github.com/ichte/xtlab.git
Hoặc là (có sử dụng SSH)
git clone git@github.com:ichte/xtlab.git
Làm việc cơ bản Git
Giờ ta sửa đổi nội dung sự án và giám sát nó với Git để tìm hiểu cách làm việc cơ bản
7 Tạo ra một file mới có tên là test.html
, sau đó kiểm tra lại trạng thái.
$ git status
On branch master
Untracked files:
test.html
Git đã phát hiện có một file mới trong dự án, file này chưa được giám sát
8 Đưa file test.html vào giám sát (staged) bằng lệnh git add .
hoặc git add test.html
$ git add .
$ git status
Changes to be committed:
new file: test.html
Đã đưa file test.html
+ nội dung của nó vào staged, giờ có thể thực hiện lệnh commit để lưu vào db của Git. Có thể lúc này bạn nhận ra cần thay đổi nội dung của test.html, nên muốn đưa nó ra khỏi staged để sửa đổi nó rồi mới cập nhật lại sau. Thì làm như sau:
$ git reset HEAD test.html
Giờ file lại ở trạng thái như 7, bạn có thể kiểm tra bằng git status
, giờ mở file test.html
ra cập nhật nội dung gì đó. Ví dụ thêm vào dòng chữ nội dung đầu tiên test.html
Sửa xong thực hiện lại git add .
để đưa test.html
trở lại sẵn sàng commit
$ git add .
9 Thực hiện commit
$ git commit -m"C1 - them file test.html"
Sau commit xem lại lịch sử commit
$ git log --oneline 8fe842a (HEAD -> master) C1 - them file test.html 2e276a4 C0 - Khoi tao du an
Đến đây Repo có 2 commit, mô hình hóa các snapshot như hình
10 Tiếp tục sửa file test.html, mở file test.html
ra, thay thế bằng nội dung mới ví dụ là dòng chữ Học Git và GitHub
, sau đó lưu lại. Quay trở lại Git kiểm tra trạng thái hiện tại
$ git status
On branch master
Changes not staged for commit:
modified: test.html
Git đã phát hiện ra có sự thay đổi trên test.html
, và nó đánh dấu ở trạng thái modified
Lúc này bạn có thể đưa sửa đổi vào staged bằng lệnh git add .
và thực hiện commit tiếp theo để cập nhật vào db Git.
11 Tuy nhiên lúc này bạn nhận ra muốn phục hồi lại file về trạng thái ở commit cuối thì làm như sau
$ git checkout -- test.html
File đã phục hồi về trạng thái ở commit cũ (mở ra nội dung nó quay về nội dung đầu tiên test.html
)
12 Mở file test.html ra tiếp tục sửa đổi lại ví dụ cho nội dung thành dòng chữ Test for Git and GitHub
, sau đó tiến hành commit để lựu lại
$ git add . $ git commit -m"C2 - update test" $ git log --oneline b9542bb (HEAD -> master) C2 - update test 8fe842a C1 - them file test.html 2e276a4 C0 - Khoi tao du an
Sơ đồ Repo hiện tại có 3 commit snapshot như hình bên
13 Tiếp tục mở file test.html
thay nội dung thành Test for Git and GitHub 2018
và lưu lại
Tạo ra một file mới test2.html
, mở file và chèn nội dung Test2 - Git and GitHub
Kiểm tra trạng thái
$ git status Changes not staged for commit: modified: test.html Untracked files: test2.html
Nó báo có 1 file ở trạng thái unmodified, 1 file ở trạng thái untracked
Thực hiện đưa hết các file untracked, modified vào staged và tiến hành commit, rồi xem lại log
$ git add . $ git commit -m"C3 - test2" $ git log --oneline de9a8d9 (HEAD -> master) C3 - test2 b9542bb C2 - update test 8fe842a C1 - them file test.html 2e276a4 C0 - Khoi tao du an
Tình trạng hiện tại như hình có 4 snapshot
14 lệnh git diff: giờ dự án đã có 4 commit mà ta ký hiệu các snapshot C0, C1, C2, C3 mỗi khi có nội dung sửa đổi thì trước khi commit phải đưa nó vào kế hoạch commit trước, đó là staged, thao tác commit chính là chuyển nội dung từ staged vào db của Git.
Nếu muốn so sánh sự khác nhau giữa nội dung trong thư mục làm việc, staged với commit cuối thì dùng lệnh:
$ git diff
Ví dụ: mở file test.html
nhập nhật nội dung thành Test for Git and GitHub 2018 - 2019
$ git status
modified: test.html
Kiểm tra trạng thái thấy file test.html
ở trạng thái modified, và trong staged không có bản chụp nào của test.html
. Nếu vậy lệnh git diff
sẽ so sánh sự khác nhau của bản ở thư mục làm việc và bản commit cuối
$ git diff diff --git a/test.html b/test.html index 2361f65..c31ae4c 100644 --- a/test.html +++ b/test.html @@ -1 +1 @@ -Test for Git and GitHub 2018 +Test for Git and GitHub 2018 - 2019
Nó cho biết bản có màu đỏ là bản gốc (ở commit cuối), bản có màu xanh là bản đang sửa đổi.
Gọi lệnh git add .
để đưa bản sửa đổi test.html
vào staged, rồi kiểm tra lại trạng thái thấy như sau
$ git status
On branch master
Changes to be committed:
modified: test.html
Bản sửa đổi test.html
đã đưa vào kế hoạch commit trong staged, giờ lệnh git diff
sẽ so sánh sự khác nhau của test.html
giữa ở thư mục làm việc và bản trong staged. Ngay thời điểm này thấy không có thông báo gì vì 2 bản đó hoàn toàn giống nhau
Mở test.html
ra sửa lại nội dung thành Git - GitHub 2018 - 2019
, sau đó kiểm tra trạng thái
$ git status On branch master Changes to be committed: modified: test.html Changes not staged for commit: modified: test.html
Thấy rằng file test.html
có một bản trong kế hoạch commit staged và một bản mới sửa đổi khác với bản kế hoạch. Nếu lúc này gõ lệnh git diff
sẽ so sánh khác nhau giữa bản đang ở thư mục làm việc và bản kế hoạch commit staged
$ git diff diff --git a/test.html b/test.html index c31ae4c..bc0c51b 100644 --- a/test.html +++ b/test.html @@ -1 +1 @@ -Test for Git and GitHub 2018 - 2019 +Git - GitHub 2018 - 2019
Thời điểm này test.html
có ba bản khác nhau:
- Bản ở thư mục làm việc
- Bản trong kế hoạch commit staged
- Bản ở dữ liệu Git trong commit cuối (snapshot cuối)
Để so sánh khác nhau giữa bản staged và bản commit dùng lệnh
$ git diff --staged diff --git a/test.html b/test.html index 2361f65..c31ae4c 100644 --- a/test.html +++ b/test.html @@ -1 +1 @@ -Test for Git and GitHub 2018 +Test for Git and GitHub 2018 - 2019
Tóm lại lệnh git diff
so sánh sự khác nhau giữa bản trong thư mục làm việc và bản trong staged nếu có, nếu không có thì so sánh với bản commit cuối. Lệnh git diff --staged
so sánh giữa bản trong staged và bản commit
15 Khi strong staged đang tồn tại một bản chưa commit của test.html
nếu bản ở thư mục làm việc có sửa đổi và gõ lại lệnh git add test.html
hoặc git add .
thì bản trong kế hoạch commit staged được thay mới từ thư mục làm việc
$ git status On branch master Changes to be committed: modified: test.html Changes not staged for commit: modified: test.html $ git add . $ git status Changes to be committed: modified: test.html
16 Tiến hành commit và xem lại log
$ git commit -m"C4" $ git log --oneline 969cbec (HEAD -> master) C4 de9a8d9 C3 - test2 b9542bb C2 - update test 8fe842a C1 - them file test.html 2e276a4 C0 - Khoi tao du an
17 Nếu muốn xóa một file khỏi Git thì bạn có thể sử dụng lệnh git rm filename
hoặc tự xóa trong thư mục làm việc bằng các lệnh xóa file của hệ thống, ví dụ sử dụng File Explore của Windows
Giả sử xóa file test2.html
bằng git rm
sẽ thấy như sau:
$ git rm test2.html
$ git status
Changes to be committed:
deleted: test2.html
File test2.html
đã xóa khỏi thư mục làm việc và thông tin xóa đã đưa luôn vào kế hoạch commit staged, nếu tiến hành commit thì sẽ có một snapshot phiên bản mà trong đó file test2.html
đã bị xóa.
Tuy nhiên lúc này (chưa commit) nếu muốn phục hồi lại file bị xóa do git rm
thì trước tiên phải đưa nó ra khỏi staged bằng lệnh git reset HEAD test2.html
, sau đó phục hồi lại bằng lệnh git checkout -- test2.html
Ví dụ phục hồi lại
$ git reset HEAD test2.html $ git checkout -- test2.html
Nếu xóa file mà không sử dụng git rm
thì file xóa đó không tự động đưa vào kế hoạch commit staged mà bạn phải tự đưa sau khi xóa file bằng lệnh git add
Ví dụ giờ bạn lại xóa test2.html
bằng cách xóa của hệ thống (ví dụ dùng File Explore). Sau đó kiểm tra trạng thái thấy:
$ git status
Changes not staged for commit:
deleted: test2.html
Nếu muốn commit việc này cần đưa vào staged trước
$ git status
Changes to be committed:
deleted: test2.html
Tiến hành commit tạo bản snapshot mà file test2.html đã bị xóa
$ git commit -m"C5 - Del test2" $ git log --oneline f5e1447 (HEAD -> master) C5 - Del test2 969cbec C4 de9a8d9 C3 - test2 b9542bb C2 - update test 8fe842a C1 - them file test.html 2e276a4 C0 - Khoi tao du an
18 git commit --amend Hiện giờ dự án có 6 snapshot, tương ứng với 6 commit, có thể xem thông tin về commit cuối:
$ git log -1 commit f5e1447053e792ada8f48fff804520bdb503d3ea (HEAD -> master) Author: XTLAB ≶xtl@xuanthulab.net> Date: Mon May 14 16:21:53 2018 +0700 C5 - Del test2
Nếu tạo ra sự thay đổi, ví dụ mở file index.html
cho vào dòng chữ Trang chủ
, nếu lúc này tiến hành commit thì hệ thống sẽ tạo ra một snapshot mới. Tuy nhiên bạn muốn không sinh ra thêm một snapshot mới mà sẽ thay thế snapshot cuối cùng thì lúc đó dùng đến lệnh git commit --amend
$ git add . $ git commit --amend -m"C5 - Update"
Xem lại log
$ git log --oneline e5d80b6 (HEAD -> master) C5 - Update 969cbec C4 de9a8d9 C3 - test2 b9542bb C2 - update test 8fe842a C1 - them file test.html 2e276a4 C0 - Khoi tao du an
Ta thấy toàn bộ lịch sử vẫn chỉ có 6 snapshot (6 commit), tuy nhiên mã hash của commit cuối cùng thay đổi so với lần commit trước, cho biết là nó mới bị thay thế
19 Khi tra cứu lịch sử commit dùng lệnh git log
, ngoài các trường hợp đã sử dụng ở trên, còn có thể sử dụng một số cú pháp để thêm thông tin muốn xem:
- Muốn xem thêm sự khác nhau (nội dung thay đổi) của từng commit thì thêm vào tham số
-p
, ví dụgit log -p
- Muốn giới hạn xem n (số nguyên) commit cuối cùng thì thêm vào tham số
-n
, ví dụ xem 2 commit cuối cùnggit log -p -2
- Muốn xem sự thay đổi từng từ một qua mỗi commit thêm vào tham số
--word-diff
, ví dụ$ git log -p -2 --word-diff
, khi hiện thị phần nội dung bị loại bỏ hiện thị trong [- -], nội dung thêm vào hiện thị trong {++}
Để xem lịch sử commit trên giao diện đồ họa từ dòng lệnh gõ gitk
Lệnh Git cơ bản làm việc với Repository
Tổng kết lại phần trên, ta đã sử dụng các lệnh Git sau
- 1
git init
khởi tạo một Repository mới - 2
git status
hiện thị thông tin trạng thái của Repository,git status -s
hiện thị thông tin ngắn gọn hơn - 3
git add
cập nhật nội dung thay đổi của các file, file mới ... vào index, đưa chúng vào staged để chuẩn bị cho việc commit tiếp theo, một số cách sử dụng tham số với lệnh này như:git add filename
thêm file có tên chỉ ra trong tham sốgit add *.c
tất cả các file có phần mở rộng .cgit add -A
thêm mọi thứ có sự thay đổi (file mới, xóa file, nội dung thay đổi ...)git add .
thêm mọi thứ trừ loại xóa filegit add -u
thêm mọi thứ trừ file mới
- 4
git commit
git commit -m "Thông báo ..."
thực hiện commit, lưu snapshot vào DB Gitgit commit --amend -m "Thông báo ..."
commit, nhưng cập nhật thông tin vào commit cuối
- 5
git clone path
sao chép một Repository có địa chỉ là path (có thể là địa mạng như https://github.com/ichte/xtlab.git hoặc SSH git@github.com:ichte/xtlab.git, có thể là ở chính máy của bạn như C:\Path\projectcode) - 6
git log
xem lại lịch sử commit. Nếu muốn hiện thị thông tin 4 commit cuối thôi thì thêm tham số -4 vàogit log -4
, nếu muốn hiện thị nhưng thông tin gì thay đổi trong từng commit thêm tham số-p
,git log --pretty=oneline
hiện thị thông tin mỗi commit trên một dòng - 7
git diff
xem sự thay đổ giữa nội dung ở thư mục làm việc và Staged nếu có, hoặc giữa thư mục làm việc với commit cuối.git diff --staged
xem sự thay đổi của nội dung trong staged và commit cuối - 8
git rm filename
xóa file khỏi thư mục làm việc - 9
git reset HEAD filename
hủy bỏ việc thay đổi trạng thái của file, ví dụ hủy đưa và Staged - 10
git checkout -- filename
khôi phục thay đổi nội dung của filename, việc khôi phục ở trạng thái hiện tại có thể là là khôi phục từ Staged nếu có, nếu không thì khôi phục từ commit cuối. Nếu muốn khôi phục file từ một commit cũ có mã hashhash
thì làm như saugit checkout [hash] filename
khôi phục lại filenamegit checkout [hash] .
khôi phục các file về phiên bản theo commit cũ