Làm web (04) - Git: thao tác với kho chứa

Bài học trước: Làm web (03) - Git: cài đặt, cấu hình, kho chứa
-----

3.2        Thao tác tại kho chứa

3.2.1    Lưu lại thay đổi vào kho chứa


Tới thời điểm này, bạn đã có một kho chứa và một bản sao dữ liệu của dự án, bạn đã có thể bắt tay vào làm việc. Trong quá trình làm việc, khi đạt được một kết quả nhất định, bạn muốn ghi lại trạng thái kết quả đó (để sau này có thể quay lại/quay lui), nhằm tạo ra một dấu mốc cho dự án, bạn sẽ thực hiện commit dự án vào kho chứa (tạo một snapshot của dự án).

Một tập tin trong kho chứa (thư mục đang làm việc) có thể ở một trong hai trạng thái: chưa được Git theo dõi (untracked) và đã được Git theo dõi (tracked).

Tập tin đã được theo dõi là tập tin đã có mặt trong snapshot trước, nghĩa là được được commit ít nhất một lần. Tập tin được theo dõi có thể ở các tình trạng: unmodified (chưa bị thay đổi), modified (đã bị thay đổi), hoặc đã được đánh dấu để commit (staged).

Tập tin chưa được theo dõi là các tập tin còn lại, bao gồm các tập tin trong kho chứa mà không có ở snapshop trước (chưa được commit lần nào) hoặc chưa được đánh dấu để commit (chưa được stage). Ví dụ, các tập tin vừa được tạo sẽ là tập tin chưa được theo dõi.

Khi mới clone một kho chứa thì mọi tập tin trong kho chứa sẽ ở trạng thái tracked và unmodified.
Khi bạn chỉnh sửa một tập tin, Git sẽ xem là đã bị thay đổi so với lần commit trước. Bạn sẽ stage các tập tin vừa bị thay đổi này, sau đó commit các tập tin, quá trình này được lặp đi lặp lại liên tục. Xem hình minh họa, vòng đời các trạng thái của tập tin,



3.2.2     Kiểm tra trạng thái của tập tin


Để kiểm tra trạng thái của các tập tin trong một kho chứa, sử dụng lệnh git status.

$ git status
On branch master
Your branch is up to date with 'origin/master'.
nothing to commit, working tree clean

Kết quả trên cho biết, bạn đang ở nhánh master, kho chứa đang “sạch”, nghĩa là không có sự thay đổi nào trên các tập tin đã theo dõi (tracked), và Git cũng không phát hiện ra tập tin nào chưa được theo dõi (untracked).

Giờ sẽ thêm một tập tin vào kho chứa, ví dụ tạo tập tin readme.txt.

Và chạy lại lệnh git status,

Kết quả là Git thông báo có tập tin readme.txt chưa được theo dõi. Nghĩa là readme.txt chưa tồn tại trong snapshot trước đó (hay nói cách khác là chưa có trong lần commit trước). Git sẽ không tự động đưa tập tin readme.txt vào lần commit tiếp theo, trừ khi bạn ra lệnh cho Git làm việc này. Theo cách này, bạn sẽ không gặp tình huống vô tình thêm các tập tin mà bạn không mong muốn.

$ git status
On branch master
Your branch is up to date with 'origin/master'.
Untracked files:
  (use "git add <file>..." to include in what will be committed)
        readme.txt
nothing added to commit but untracked files present (use "git add" to track)

3.2.3     Theo dõi các tập tin mới


Để theo dõi tập tin mới tạo, sử dụng lệnh git add. Ví dụ, để bắt đầu theo dõi tập tin readme.txt, sử dụng lệnh sau,

$ git add readme.txt

Chạy lại lệnh git status để xem kết quả,

$ git status
On branch master
Your branch is up to date with 'origin/master'.
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)
        new file:   readme.txt

Kết quả trên cho thấy, tập tin readme.txt đã nằm trong danh sách “những thay đổi sẽ được commit” (staged), nghĩa là nó đã được theo dõi (tracked). Nếu bạn thực hiện commit thời điểm này, phiên bản (trạng thái) của tập tin ở thời điểm bạn chạy lệnh “git add” sẽ được thêm vào lịch sử commit. Lệnh git add cũng có thể sử dụng để theo dõi một thư mục, khi đó mọi tập tin và thư mục con cũng được theo dõi.

Lệnh git add cho phép lập trình viên có thể commit từng phần của dự án (một số tập tin cụ thể) chứ không phải toàn bộ dự án.

3.2.4     Quản lý các tập tin đã thay đổi


Thử sửa một tập tin đã được theo dõi (tracked), ví dụ thêm nội dung vào tập tin readme.txt, sau đó chạy lệnh git status để xem kết quả.

$ git status
On branch master
Your branch is ahead of 'origin/master' by 1 commit.
  (use "git push" to publish your local commits)
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)
        modified:   readme.txt
no changes added to commit (use "git add" and/or "git commit -a")

Thông báo trên cho biết: tập tin readme.txt đã bị thay đổi trong thư mục làm việc (working directory) nhưng chưa được tổ chức /đánh dấu (staged) để commit. Để đánh dấu, sử dụng lệnh git add readme.txt, sau đó chạy lệnh git status để xem kết quả.

$ git status
On branch master
Your branch is ahead of 'origin/master' by 1 commit.
  (use "git push" to publish your local commits)
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)
        modified:   readme.txt  

Lệnh git add nên được hiểu là “đánh dấu nội dung sẽ được commit chứ không chỉ là đưa một tập tin vào dự án”.

Thông báo trên cho biết “tập tin readme.txt đã được staged và đã sẵn sàng để commit trong lần sắp tới”. Tuy nhiên, trước khi thực hiện commit, bạn lại nhớ ra là mình cần phải thêm một thông tin nữa vào trong readme.txt. Bạn mở readme.txt ra để thêm thông tin còn thiếu vào. Bây giờ, thì đã sẵn sàng để commit. Bạn thử gõ lệnh git status để xem trạng thái,

$ git status
On branch master
Your branch is ahead of 'origin/master' by 1 commit.
  (use "git push" to publish your local commits)

Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

        modified:   readme.txt

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

        modified:   readme.txt

Chuyện gì thế này? Tập tin readme.txt đang nằm ở cả hai trạng thái, một là đã được staged để sẵn sàng commit và hai là đã bị thay đổi nhưng chưa được staged. Vậy nếu bạn thực hiện commit ở thời điểm này thì nội dung của readme.txt khi bạn thực hiện git add trước đó sẽ được commit, còn những nội dung bạn vừa sửa sẽ không được commit. Để đảm bảo nội dung của readme.txt được commit là mới nhất, bạn phải thực hiện lệnh git add thêm một lần nữa, trước khi thực hiện commit.

Chạy git add readme.txt và git status để xem kết quả.

$ git add readme.txt

$ git status
On branch master
Your branch is ahead of 'origin/master' by 1 commit.
  (use "git push" to publish your local commits)

Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

Lab 12. Hiểu về Working Directory, Staging Area và Git Directory.

– Tạo một kho chứa

– Trong kho chứa, tạo tập tin DangNhap.cs

– Thực hiện lệnh git add để đưa tập tin DangNhap.cs và Staging Area

– Tìm tập tin DangNhap.cs trong Working Directory


– Tìm tập tin DangNhap.cs trong Staging Area


3.2.5     Hiển thị trạng thái ở dạng rút gọn


Mặc định, lệnh git status hiển thị các thông tin trạng thái ở dạng đầy đủ, khá dài. Tuy nhiên, khi làm việc nhiều với Git, đã hiểu về Git, thì chỉ cần hiển thị các thông tin ở dạng ngắn gọn. Để làm việc này, bạn sử dụng thêm tham số -s hoặc --short trong lệnh git status.

Ví dụ,

$ git status -s
M  readme.txt
A  taptin1.doc
AM  view/view1.txt
?? code.php
MM test.txt

Màn hình kết quả được chia thành hai cột, cột bên trái thể hiện trạng thái của tập tin/thư mục trong vùng staging, cột bên phải là tên của tập tin và thư mục (gồm cả đường dẫn).

Các trạng thái được viết tắt: ?? là tập tin chưa được theo dõi (untracked), A là tập tin đã được đánh dấu để commit (staged), M là tập tin đã bị thay đổi mà chưa được đánh dấu (modified). AM là tập tin đã staged và modified. MM là tập tin đã modified, đã staged rồi lại modifed.

Lab 13. Tạo một thư mục có tên project, tạo nội dung và thực hiện các thao tác cần thiết để ra được kết quả như sau.

$ git status -s
M  readme.txt
A  taptin1.doc
AM  view/view1.txt
?? code.php
MM test.txt


3.2.6     Bỏ qua các tập tin


Trong thực tế có một số tập tin không cần phải quản lý, lưu trữ, ví dụ các tập tin nhật kí (log), các tập tin tạm sinh ra trong quá trình biên dịch mã nguồn. Để giúp Git loại bỏ việc quản lý những tập tin này, bạn có thể đưa ra các luật quy định các tập tin nào sẽ không được quản lý và theo dõi. Các luật được lưu trong tập tin .gitignore.

Các luật được tạo ra dựa trên các mẫu (patterns), tập tin hay thư mục nào khớp với mẫu sẽ bị tác động bởi luật. Các mẫu được viết theo dạng Biểu thức chính quy (regular expression).

Trong tập tin .gitignore, một dòng sẽ chứa một luật.

Ví dụ một số mẫu:

– Dòng trống hoặc bắt đầu với dấu # sẽ bị bỏ qua

– *.a : yêu cầu Git bỏ qua tất cả các tập tin có phần mở rộng là a

– *.[oa] : yêu cầu Git bỏ qua các tập tin có phần mở rộng là o hoặc a (a là tập tin archive, o là tập tin object, là các tập tin được sinh ra trong quá trình biên dịch mã nguồn)

– Sử dụng dấu ! để phủ định các giá trị phía sau, ví dụ "!lib.a" nghĩa là không bỏ qua tập tin lib.a

– Dấu * đại diện cho 0 hoặc nhiều kí tự

– Dấu ? đại diện cho một kí tự

– [0-9] đại diện cho một khoảng dữ liệu từ 0 tới 9

– Bắt đầu một luật bằng dấu xuyệt (/) để tránh đệ quy

– Kết thúc một luật bằng dấu xuyệt (/) để xác định một thư mục

Ví dụ nội dung của một tập tin .gitignore,

# không theo dõi tập tin có phần mở rộng là .a
*.a

# nhưng theo dõi tập tin lib.a, mặc dù ở luật bên trên đã bỏ qua mọi tập tin .a
!lib.a

# chỉ bỏ qua tập tin TODO ở thư mục hiện tại, còn ở các thư mục con thì không
/TODO

# bỏ qua mọi tập tin trong các thư mục có tên là build
build/

# bỏ qua doc/notes.txt, chứ không phải doc/server/arch.txt
doc/*.txt

# bỏ qua mọi tập tin .pdf trong thư mục doc/ (kể cả trong các thư mục con)
doc/**/*.pdf

Ngay khi tạo kho chứa, nên tạo tập tin .gitignore để tránh theo dõi những tập tin không cần thiết.

Xem một số tập tin .gitignore mẫu ở đây: https://github.com/github/gitignore

Lab 14. Thực hành với tập tin .gitignore

– Tạo mới một thư mục (ví dụ testignore)

– Chuyển testignore thành kho chứa (repository)

– Trong kho chứa testignore, tạo tập tin .gitignore (dùng lệnh touch trong Git Bash để tạo)

– Thực hiện add và commit để đảm bảo .gitignore đã được theo dõi

– Trong kho chứa testignore tạo các tập tin và thư mục sau: (test.exe, test1.exe, test2.exe, tập tin log.txt, thư mục vendor, trong vendor tạo tập tin vendor1.txt)

– Dùng lệnh git status để kiểm tra, đảm bảo các tập tin và thư mục vừa tạo chưa được theo dõi (untracked)


– Viết các luật cho tập tin .gitignore để bỏ qua tất cả các tập tin có phần mở rộng là .exe, trừ tập tin test2.exe; bỏ qua tập tin log.txt; và bỏ qua thư mục vendor. Nếu làm đúng, khi gõ lệnh git status sẽ không còn báo là các tập tin và thư mục trên là untracked, trừ tập tin test2.exe.

</////04
-----------
Cập nhật [29/09/2019]
-----------
Xem thêm: Tổng hợp các bài viết về Làm web
Xem thêm: Làm web (05) - Git: thao tác với kho chứa (tt)