Bạn cần gửi một snapshot mã nguồn cho đồng đội, nhưng thư mục hiện tại còn file đang sửa và dữ liệu thử chưa commit. Nén cả folder dễ lấy nhầm những thứ đó. Git archive cho phép chọn rõ một commit hoặc tree làm nguồn xuất.
Bài được đối chiếu ngày 30/10/2026 và thử bằng Git 2.54.0 trong repository tạm. Demo dùng Bash, tar và Python 3, không fetch, push hoặc sửa repository làm việc của bạn. Archive là bản xuất mã nguồn, không phải bản sao đầy đủ lịch sử Git hay backup toàn bộ môi trường chạy.
Chọn commit trước khi tạo file nén
Trong repository cần xuất, đọc ref và danh sách file của snapshot:
git rev-parse --verify HEAD
git ls-tree -r --name-only HEAD
HEAD là commit hiện tại, không có nghĩa mọi chỉnh sửa đang thấy trong editor đã thuộc commit đó. git-ls-tree giúp xem nội dung tree đã chọn; nó không liệt kê thay đổi chưa commit như một file explorer của working tree.
Khi cần gắn archive với một lần bàn giao, lưu commit ID từ lệnh đầu cùng tên archive hoặc ghi chú riêng. Không đổi ref đầu vào sang một branch khác mà vẫn ghi rằng đó là bản của commit cũ.
Tạo ba phiên bản để biết Git lấy bản nào
Khối sau tạo repository mới trong thư mục tạm. Subshell giữ thư mục và cấu hình demo trong phạm vi riêng. Nội dung committed, staged và working tree cố tình khác nhau.
(
set -eu
demo_dir=$(mktemp -d)
export GIT_CONFIG_NOSYSTEM=1
export GIT_CONFIG_GLOBAL=/dev/null
git init -q --template= "$demo_dir"
cd "$demo_dir"
git config core.autocrlf false
git config core.attributesFile /dev/null
printf 'committed\n' > note.txt
git add -- note.txt
git -c user.name=Demo -c [email protected] \
-c commit.gpgsign=false commit -qm base
printf 'staged\n' > note.txt
git add -- note.txt
printf 'working\n' > note.txt
printf 'local-only\n' > scratch.txt
git archive --format=tar --prefix=snapshot/ \
--output="$demo_dir/snapshot.tar" HEAD
tar -tf "$demo_dir/snapshot.tar"
tar -xOf "$demo_dir/snapshot.tar" snapshot/note.txt
python3 -c 'from pathlib import Path; print(Path("note.txt").read_text().strip())'
)
Danh sách tar trong fixture chỉ có thư mục snapshot/ và file snapshot/note.txt. Đọc file từ archive cho committed; đọc working tree cho working. File scratch.txt không có trong archive vì chưa thuộc commit được chọn. Nội dung staged cũng không thay thế blob trong HEAD.
Lệnh tar -xO ở đây đọc một file ra stdout, không giải nén đè lên working tree. Prefix giúp đặt nội dung vào một thư mục gốc trong archive; nó không thay đổi commit đầu vào hoặc tự thêm metadata triển khai.
Đóng gói repository thật
Sau khi đã chọn commit cần xuất, có thể tạo archive với một đường dẫn đích mới:
git archive --format=tar --prefix=source-snapshot/ \
--output=/path/to/new-output.tar HEAD
/path/to/new-output.tar là placeholder cần thay bằng file đích mới ở thư mục có quyền ghi. Lệnh tạo file nên không dùng đường dẫn của dữ liệu cần giữ. git-archive mô tả các format và tùy chọn; kiểm tra format hỗ trợ tại máy nếu muốn chuyển sang zip hoặc tar.gz.
Archive mặc định lấy nội dung của tree được chỉ định, chịu ảnh hưởng attributes phục vụ xuất bản. Đừng dùng phép so tên file với working tree để kết luận mọi file tracked đều chắc chắn xuất hiện trong bản nén.
export-ignore và những thứ vẫn có thể lọt vào
Một repository có thể đánh dấu file hoặc thư mục bằng thuộc tính export-ignore để loại khỏi archive. Mặc định attributes được đọc từ tree đang xuất; tùy chọn worktree attributes là một hành vi khác cần chọn có chủ đích. gitattributes phần archive là nguồn đối chiếu cho chính sách này.
File bí mật đã bị commit vào tree vẫn có thể đi vào archive nếu không bị loại theo chính sách. .gitignore không tự xóa một file đã tracked khỏi commit. Vì vậy, xem danh sách archive và rà nội dung trước khi gửi, không coi “dùng Git” là bằng chứng đã loại mọi dữ liệu riêng.
Giới hạn và checklist bàn giao
Archive không chứa .git để người nhận tiếp tục xem toàn bộ lịch sử như một clone. Nó cũng không tự dựng dependency, database, biến môi trường hoặc dữ liệu nằm ngoài snapshot. Với submodule, LFS hoặc quy trình xuất có filter riêng, kiểm tra quy trình dự án thay vì giả định archive là một release chạy được ngay.
Trước khi bàn giao, xác nhận commit ID, đường dẫn gốc trong archive, file cần có và file cần loại. Mở thử đúng file quan trọng từ archive, không chỉ kiểm tra file nén tồn tại hay kích thước khác 0.
Nếu cần xuất cả thay đổi chưa commit, hãy chốt đó là một yêu cầu khác và quyết định cách ghi nhận snapshot tương ứng. Đừng âm thầm đưa working tree vào một archive đang được gắn nhãn của HEAD. Chọn ref rõ ràng giúp người nhận biết chính xác mã nguồn nào đã được bàn giao.

