git init
Xem thửVấn đề cần giải quyết
Bạn có thư mục ung-dung/ với vài chục tệp mã nguồn nhưng chưa có lịch sử nào. Bạn muốn bắt đầu theo dõi thay đổi, và cả đội cũng cần một kho trung tâm để push lên. Hai nhu cầu này dùng hai dạng kho khác nhau.
Sau bài này, bạn có thể
- Dùng
git initđể biến một thư mục thành kho và giải thích nó thêm gì vào thư mục. - Phân biệt kho thường với kho bare và biết khi nào dùng loại nào.
- Nói được vai trò của HEAD, refs và objects trong
.git.
Tiên quyết: bài Tổng quan thiết lập kho.
Dùng cơ bản
cd duong-dan/du-an
git init
Sau lệnh này thư mục hiện tại trở thành kho. Các tệp của bạn không đổi; chỉ có thêm thư mục ẩn .git. Chưa có commit nào, nên lịch sử còn trống. Để khởi tạo vào một thư mục mới: git init ten-du-an.
Hai dạng kho
Cách đọc hình. Khung bên trái là kho thường: có Working Directory để bạn sửa tệp và thư mục .git chứa dữ liệu. Khung bên phải là kho bare (git init --bare): chỉ có dữ liệu Git, không có thư mục làm việc, nên không thể sửa code trực tiếp trong đó. Vì vậy kho bare phù hợp làm điểm trung tâm mà mọi người push và pull, đúng cách máy chủ Git hoạt động. Theo quy ước, tên kho bare kết thúc bằng .git.
git init --bare /srv/git/du-an.git
Năm thành phần chính trong .git: HEAD trỏ tới nhánh hiện tại; config là cấu hình riêng của kho; objects/ chứa toàn bộ nội dung (blob, tree, commit); refs/ chứa con trỏ nhánh và tag; hooks/ chứa script chạy theo sự kiện. Chuỗi HEAD, nhánh trong refs, commit trong objects giải thích vì sao đổi nhánh rất nhẹ: chỉ đổi con trỏ.
Thử và quan sát
Hãy dự đoán: ngay sau git init, nhưng trước khi có commit nào, git status báo gì và thư mục objects/ đã có gì chưa? Chạy mô phỏng, rồi thử biến thể kho bare để thấy vì sao nó không có Working Directory.
Đang tải Animation…
Bảng bước (bản đọc tĩnh của mô phỏng)
| Bước | Lệnh | Điều xảy ra |
|---|---|---|
| 1 | git init demo | Git tạo thư mục .git với bộ khung rỗng. HEAD trỏ tới nhánh main nhưng nhánh này chưa có commit nào. |
| 2 | git status | Kho tồn tại nhưng lịch sử còn trống. |
| 3 | echo "hello" > a.txt | Tạo tệp trong Working Directory. Chưa gì được ghi vào .git. |
| 4 | git add a.txt | Add ghi nội dung tệp thành một đối tượng blob trong objects/ và cập nhật Staging Area. |
| 5 | git commit -m "Commit đầu tiên" | Commit tạo thêm tree và commit trong objects/, rồi nhánh main trong refs/ trỏ tới C1. |
Biến thể: Thử với kho bare
| Bước | Lệnh | Điều xảy ra |
|---|---|---|
| 1 | git init --bare demo.git | Kho bare chỉ có dữ liệu Git, không có thư mục làm việc. Theo quy ước tên kết thúc bằng .git. |
| 2 | git add a.txt | Trong kho bare không có Working Directory nên các lệnh cần bản làm việc đều bị từ chối. |
| 3 | git push /srv/git/demo.git main | Muốn có nội dung, người dùng push từ một kho thường lên. Commit đến qua push chứ không sửa trực tiếp. |
Giải đáp. git status báo "No commits yet": kho có nhưng lịch sử trống, và objects/ chưa chứa đối tượng nào. Chỉ khi add, nội dung tệp mới thành blob; khi commit mới có tree và commit, và nhánh main trong refs/ trỏ tới commit đó. Trong biến thể bare, lệnh cần bản làm việc như git add bị từ chối; nội dung đến kho bare qua push.
Hiểu lầm và giới hạn
- "git init tự đưa các tệp vào lịch sử." Không. Bạn vẫn phải
addrồicommit. - "Có thể xóa .git cho gọn." Xóa
.gitnghĩa là biến kho trở lại thư mục thường và mất toàn bộ lịch sử, trừ khi bạn còn một bản clone. - "Chạy git init hai lần sẽ xóa dữ liệu." Chạy lại trong kho có sẵn chỉ báo "Reinitialized" và không xóa lịch sử, nhưng không cần thiết.
Tự kiểm tra
- Sau
git init, thư mục có thêm gì và các tệp cũ có đổi không? - Vì sao máy chủ Git thường dùng kho bare?
- Vì sao trong kho bare lệnh
git addthất bại?
Đáp án gợi ý. (1) Có thêm thư mục .git; tệp cũ giữ nguyên. (2) Nó không có Working Directory nên không ai sửa trực tiếp, chỉ nhận và phát lịch sử qua push và pull. (3) Vì add cần một bản làm việc để lấy nội dung, mà kho bare không có.
Điều cần nhớ
git initthêm.git, không đụng tới tệp của bạn.- Kho thường có bản làm việc, kho bare chỉ giữ dữ liệu Git để làm điểm trung tâm.
- HEAD, refs, objects tạo thành chuỗi trỏ từ nhánh tới nội dung.
- Bài sau:
git clone, lấy một kho đã có về máy.
Nguồn tham khảo
Tài liệu git-init (git-scm.com/docs/git-init); Pro Git, chương 10.2 "Git Internals - Plumbing and Porcelain" (git-scm.com/book).