Git cho người dùng agent: nhánh, commit nhỏ và cách quay lại
Agent sửa code rất nhanh, và đôi khi sửa sai rất nhanh. Bài giải thích Git bằng hình ảnh điểm lưu trong trò chơi: mỗi việc một nhánh, commit nhỏ, đọc diff trước khi nhận, và các lệnh quay lại an toàn, kèm kết quả chạy thật trong một kho thử.
Dành cho bất kỳ ai giao việc viết code cho AI agent, kể cả người mới chưa từng dùng Git. Không cần biết trước gì. Thuật ngữ nào cũng đi kèm một ví dụ đời thường, và phần có lệnh được đánh dấu để bạn chép theo hoặc bỏ qua.
Mọi lệnh và kết quả trong phần ví dụ đều được chạy thật trong một kho thử (Git phiên bản 2.56.0, ngày 30/10/2026). Tình huống ghi là "minh họa" được dựng lại, không nhắc đến người hay công ty cụ thể. Cách agent mắc lỗi bên trong chưa ai hiểu hết, nên các hình dung dưới đây chỉ là cách tưởng tượng để dễ nhớ.
Tóm tắt nhanh#
- Agent sửa nhiều tệp trong vài phút. Nếu bạn không có điểm quay lại, một lần sửa sai có thể nuốt cả buổi làm việc. Git là điểm lưu: nó chỉ nhớ những gì bạn đã commit.
- Thói quen cốt lõi: mỗi việc giao cho agent một nhánh riêng, bắt agent commit nhỏ, và đọc
git statusrồigit difftrước khi nhận kết quả. - Có bốn đường lui, mỗi đường dùng cho một hoàn cảnh:
git restore(chưa commit),git revert(đã commit, an toàn nhất),git reflog(cứu sau khi lỡ tay),git worktree(để agent làm ở thư mục riêng ngay từ đầu). - Điểm mù lớn nhất: thay đổi chưa commit mà bị
git restorethì không lấy lại được. Trong kho thử của bài này, nhật ký reflog không có dòng nào cho phần đó. - Điểm lưu chỉ bao được tệp trong kho. Một cơ sở dữ liệu bị xóa hay một email đã gửi nằm ngoài Git.
- Các lệnh hủy nguy hiểm (
push --force,reset --hard,clean) nên được ghi vào hướng dẫn cho agent là không tự chạy khi chưa hỏi.
Từ khó, nói dễ#
| Thuật ngữ | Nói dễ hiểu |
|---|---|
| Repository (kho Git) | Thư mục dự án cộng với toàn bộ lịch sử các lần lưu của nó. |
| Commit (điểm lưu) | Một lần lưu có tên và ghi chú, như bấm "lưu game" ở một chỗ. Ai cũng quay lại được chỗ đó. |
| Branch (nhánh) | Một đường chơi riêng tách ra từ bản chính để thử, không làm hỏng bản chính. |
| Diff (bản so sánh) | Danh sách chính xác dòng nào thêm, dòng nào xóa so với điểm lưu gần nhất. |
| Revert (hoàn tác bằng điểm lưu mới) | Tạo một điểm lưu mới làm ngược lại một điểm lưu cũ. Lịch sử vẫn còn nguyên. |
| Reset (kéo lùi) | Đưa nhánh về một điểm lưu cũ. Với --hard, các thay đổi chưa commit bị xóa. |
| Reflog (nhật ký di chuyển) | Cuốn sổ ghi lần lượt chỗ con trỏ HEAD từng đứng, dùng để tìm lại điểm lưu "đã biến mất". |
| Stash (ngăn kéo tạm) | Cất tạm phần đang làm dở vào ngăn kéo để tay trống, lát lấy ra làm tiếp. |
| Worktree (thư mục làm việc thêm) | Một thư mục thứ hai của cùng một kho, đang đứng ở nhánh khác, như một bàn làm việc riêng. |
1. Hình dung trước: trò chơi có điểm lưu#
Hình dung bạn chơi một trò chơi dài. Bạn không bấm lưu thì lỡ chết một lần là mất một giờ chơi. Còn nếu cứ vài phút bạn bấm lưu một lần, chết thì chỉ mất vài phút.
Giao việc cho agent cũng vậy. Agent là người chơi rất nhanh và hơi vội: nó có thể sửa mười tệp trước khi bạn kịp đọc tệp đầu tiên. Nó giỏi nhưng không phải lúc nào cũng đúng, và tài liệu của chính các công cụ agent nói thẳng về điều đó (xem phần 6). Điểm lưu không làm agent bớt sai. Nó làm cái sai bớt đắt.
Git đóng vai trò đó, với một quy tắc quan trọng: Git chỉ nhớ những gì đã được commit. Thay đổi nằm trong thư mục mà chưa commit giống như đang chơi giữa chặng mà chưa lưu.
Điều rút ra: trước khi giao việc, hãy có một điểm lưu sạch. Trong khi agent làm, hãy bắt nó lưu thường xuyên.
2. Quy trình năm bước: mỗi việc một nhánh#
Hình dung bàn ăn có nhiều khay: bạn không thử món mới ngay trên đĩa chính, mà bày ra một đĩa riêng. Nếu hỏng thì bỏ đĩa đó, đĩa chính vẫn nguyên.
Phần dưới đây chạy thật trong một kho thử gồm một tệp prices.py tính tổng đơn hàng. Có một điểm lưu đầu tiên trên nhánh main.
Bước 1. Tạo nhánh riêng cho việc này#
git switch -c agent/add-discount
Switched to a new branch 'agent/add-discount'
Quy ước đặt tên agent/ten-viec giúp bạn nhìn danh sách nhánh là biết nhánh nào của agent. Đây là thói quen của tôi, không phải quy định của Git.
Bước 2. Giao việc và để agent làm#
Bạn nhờ agent: "thêm tham số giảm giá tùy chọn cho hàm total". Agent sửa tệp.
Bước 3. Đọc git status rồi git diff trước khi nhận#
git status -sb
git diff
## agent/add-discount
M prices.py
diff --git a/prices.py b/prices.py
index de87eb8..d7bc76f 100644
--- a/prices.py
+++ b/prices.py
@@ -1,2 +1,3 @@
-def total(items):
- return sum(item["price"] * item["qty"] for item in items)
+def total(items, discount=0):
+ subtotal = sum(item["price"] * item["qty"] for item in items)
+ return subtotal * (1 - discount)
M nghĩa là một tệp đã bị sửa. Dòng bắt đầu bằng - là dòng bị xóa, dòng bắt đầu bằng + là dòng mới. Việc đọc này chính là bước "mở bằng chứng ra" ở bài Làm cho kết quả của AI tự chứng minh, và là phần đầu của việc duyệt code do AI viết.
Bước 4. Commit nhỏ, như một điểm lưu#
git add prices.py
git commit -q -m "feat: add optional discount to total"
git log --oneline
c9c7cf3 feat: add optional discount to total
6dd4973 feat: add total function
Cờ -q chỉ để lệnh im lặng. Mỗi commit một việc có thể mô tả bằng một câu, như mẫu feat: tên việc của Conventional Commits (một quy ước viết ghi chú phổ biến, không bắt buộc).
Bước 5. Gộp khi đã hài lòng#
Khi đã đọc diff và chạy kiểm tra, bạn là người gộp nhánh vào main:
git switch main
git merge --no-ff -q agent/add-discount -m "merge: add discount"
git log --oneline --graph
* 04cbf8d merge: add discount
|\
| * 5aee66b feat: add extra script
| * c5b6fbf Revert "refactor: simplify total"
| * 6f88dd0 refactor: simplify total
| * c9c7cf3 feat: add optional discount to total
|/
* 6dd4973 feat: add total function
Nhánh main chỉ nhận thứ bạn đã xem. Các điểm lưu giữa (refactor, Revert, extra script) đến từ các thí nghiệm ở phần 3.
2.1 Phép tính để bạn tự kiểm lại (minh họa, có thể bỏ qua)#
Đây là ví dụ với số dựng sẵn. Giả sử agent làm liên tục 3 giờ (180 phút) và có sự cố ở phút cuối.
session = 180
no_commit_loss = session # chưa lưu lần nào: mất tối đa 180 phút
every = 20
saves = session // every # 9 điểm lưu
worst_loss = every # mất tối đa 20 phút
print(saves, worst_loss, session - worst_loss)
# 9 20 160
Đọc kết quả: commit mỗi 20 phút cho 9 điểm lưu, lần sự cố tệ nhất chỉ mất tối đa 20 phút thay vì 180, tức là giữ lại 160 phút. Con số 20 phút là giả định của tôi để minh họa. Đời thật không có công thức, nhưng quy tắc là đủ nhỏ để bạn nhìn lại được và dám bỏ.
3. Quay lại: chọn đúng lệnh cho đúng hoàn cảnh#
Hình dung bạn lỡ xóa một đoạn văn. Cách lấy lại phụ thuộc vào việc bạn đã lưu tài liệu hay chưa.
| Hoàn cảnh | Lệnh | Điều xảy ra | Mức rủi ro |
|---|---|---|---|
| Agent vừa sửa sai, chưa commit | git restore tên-tệp |
Tệp về bản đã commit gần nhất | Mất thay đổi chưa commit, không lấy lại được |
| Một commit đã có mà sai | git revert HEAD |
Tạo commit mới đảo lại, lịch sử giữ nguyên | An toàn |
| Đang làm dở, cần tay trống | git stash push -m "ghi chú" |
Cất tạm, lát git stash pop |
An toàn |
| Cần kéo nhánh về điểm cũ | git reset --hard điểm-lưu |
Nhánh lùi, thay đổi chưa commit bị xóa | Nguy hiểm, có thể cứu commit bằng reflog |
| Lỡ tay reset | git reflog rồi git reset --hard HEAD@{n} |
Tìm lại nơi HEAD từng đứng | Cứu được commit, không cứu được thay đổi chưa commit |
3.1 git restore: hủy thay đổi chưa commit#
Agent sửa tệp thành một hàm vô dụng:
git status -sb
git diff --stat
git restore prices.py
git status -sb
## agent/add-discount
M prices.py
prices.py | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
## agent/add-discount
Sau restore, git status không còn dòng M, tức là tệp đã về đúng bản đã commit. Cảnh báo: nếu thay đổi bị hủy là thứ bạn muốn giữ, không có đường về. Tôi thử: sửa tệp, git restore, rồi xem reflog và danh sách stash.
git reflog | head -2
git stash list | wc -l
5aee66b HEAD@{0}: reset: moving to HEAD
5aee66b HEAD@{1}: reset: moving to HEAD@{1}
0
Hai dòng reflog là của các thao tác trước đó, không có bản ghi nào cho dòng bị hủy, và danh sách stash trống (0 mục). Trang hướng dẫn git restore mô tả lệnh là khôi phục nội dung theo một nguồn nên nội dung hiện tại bị thay thế. Muốn giữ thì git stash trước, hoặc commit trước.
3.2 git revert: đảo lại một commit đã có#
Agent commit một lần "đơn giản hóa" làm hỏng hàm:
git commit -qam "refactor: simplify total"
git revert --no-edit HEAD
git log --oneline
[agent/add-discount c5b6fbf] Revert "refactor: simplify total"
Date: Fri Oct 30 17:31:17 2026 +0700
1 file changed, 2 insertions(+), 1 deletion(-)
c5b6fbf Revert "refactor: simplify total"
6f88dd0 refactor: simplify total
c9c7cf3 feat: add optional discount to total
6dd4973 feat: add total function
Commit hỏng vẫn nằm trong lịch sử, và một commit mới đảo lại nó. Theo tài liệu Git, git revert tạo commit mới hoàn tác các commit trước thay vì xóa chúng. Vì không viết lại lịch sử nên đây là cách an toàn với nhánh dùng chung.
3.3 git reset --hard rồi git reflog: lỡ tay vẫn cứu được commit#
Đây là phần đáng sợ nhất, nên tôi cho chạy thật. Thêm một commit rồi lùi hai bước:
git reset --hard HEAD~2
git log --oneline
ls
HEAD is now at 6f88dd0 refactor: simplify total
6f88dd0 refactor: simplify total
c9c7cf3 feat: add optional discount to total
6dd4973 feat: add total function
prices.py
Tệp extra.py biến mất khỏi thư mục, và hàm trong prices.py quay về bản hỏng. Nhưng reflog còn nhớ:
git reflog | head -8
6f88dd0 HEAD@{0}: reset: moving to HEAD~2
5aee66b HEAD@{1}: commit: feat: add extra script
c5b6fbf HEAD@{2}: revert: Revert "refactor: simplify total"
6f88dd0 HEAD@{3}: commit: refactor: simplify total
c9c7cf3 HEAD@{4}: commit: feat: add optional discount to total
6dd4973 HEAD@{5}: checkout: moving from main to agent/add-discount
6dd4973 HEAD@{6}: commit (initial): feat: add total function
Điểm lưu 5aee66b vẫn ở đó. Đặt lại về nó:
git reset --hard HEAD@{1}
git log --oneline
ls
HEAD is now at 5aee66b feat: add extra script
5aee66b feat: add extra script
c5b6fbf Revert "refactor: simplify total"
6f88dd0 refactor: simplify total
c9c7cf3 feat: add optional discount to total
6dd4973 feat: add total function
extra.py
prices.py
Mọi thứ về lại. Theo tài liệu Git, mặc định các mục reflog được giữ 90 ngày và 30 ngày với mục không còn nằm trên nhánh nào, nên hãy cứu sớm. Reflog là sổ của máy bạn, không được đẩy lên máy chủ.
3.4 git stash: cất tạm phần đang dở#
git stash push -m "half done idea"
git stash list
git stash pop
Saved working directory and index state On agent/add-discount: half done idea
stash@{0}: On agent/add-discount: half done idea
Dropped refs/stash@{0} (377cf291f166fc06e84e9ac41e27da37fa79d8d9)
Giữa hai lệnh, git status sạch. Sau pop, thay đổi quay lại. Dùng khi bạn muốn tay trống để agent làm việc khác, mà chưa muốn commit nửa vời.
Điều rút ra: nhớ một câu: đã commit thì gần như luôn cứu được, chưa commit thì không. Vì vậy mới cần commit nhỏ.
4. Worktree: cho agent một bàn làm việc riêng#
Hình dung phòng bếp có hai quầy: bạn nấu ở quầy này, đầu bếp phụ nấu ở quầy kia. Cùng một bếp, cùng một kho nguyên liệu, nhưng không đụng tay nhau.
Worktree là thư mục làm việc thứ hai của cùng một kho. Theo tài liệu Git, nó dùng chung kho với thư mục chính nhưng có HEAD và vùng chuẩn bị (index) riêng, và mặc định Git không cho hai worktree cùng đứng một nhánh.
git worktree add ../demo-git-wt -b agent/refactor-names
git worktree list
Preparing worktree (new branch 'agent/refactor-names')
HEAD is now at 5aee66b feat: add extra script
/path/to/demo-git 5aee66b [agent/add-discount]
/path/to/demo-git-wt 5aee66b [agent/refactor-names]
(Tôi rút gọn đường dẫn thành /path/to/ cho dễ đọc.) Giờ agent làm trong demo-git-wt còn bạn vẫn sửa ở thư mục chính. Xong việc thì dọn:
git worktree remove ../demo-git-wt
git branch -d agent/refactor-names
Deleted branch agent/refactor-names (was 5aee66b).
git worktree remove chỉ xóa được thư mục sạch nếu không dùng --force. Claude Code có sẵn lối tắt claude --worktree tên-việc để mở phiên làm việc trong worktree mới, theo trang Common workflows của họ. Công cụ khác có thể có cách riêng, hãy xem tài liệu của công cụ bạn dùng.
5. Luật chơi cho agent#
Hình dung đưa chìa khóa cho người giúp việc: bạn nói rõ phòng nào được vào, phòng nào không.
5.1 Các thói quen nên ghi thành luật#
- Không commit thẳng vào
main. Mỗi việc một nhánh. - Không
push --forcevà không tự push khi chưa hỏi. Đẩy lên máy chủ là hành động mà người khác thấy. - Không
reset --hard, khôngclean, không xóa nhánh khi chưa hỏi.git cleanxóa các tệp chưa được Git theo dõi, nên tôi coi chúng như không có bản sao để cứu. - Không đụng tệp chứa khóa như
.env. Hãy để.gitignorechặn: kiểm tra bằnggit check-ignore -v .env.
git check-ignore -v .env
.gitignore:1:.env .env
Dòng trên nói quy tắc ở dòng 1 của .gitignore đang chặn tệp .env. (Trong kho thử, môi trường của tôi không cho tạo tệp .env thật, nên tôi chỉ kiểm quy tắc chứ không thử git status với tệp có thật.)
5.2 Năm dòng dán vào hướng dẫn cho agent#
Đặt khối này trong AGENTS.md hoặc tệp hướng dẫn của công cụ:
## Git
- Làm trên nhánh agent/<tên-việc>, không commit thẳng vào main.
- Commit nhỏ, mỗi commit một việc, chạy kiểm tra trước khi commit.
- Không dùng push --force, reset --hard, clean hay xóa nhánh khi chưa hỏi.
- Không push. Không sửa .env hay tệp chứa khóa.
- Cuối việc: dán kết quả git status và git diff --stat.
Đây là hướng dẫn viết bằng lời, agent có thể bỏ qua nó. Nó là lớp chắn thứ nhất, không phải duy nhất: hãy dùng thêm quyền hạn của công cụ và tính năng bảo vệ nhánh chính của dịch vụ lưu mã nếu có.
5.3 Ghi chú commit của agent nên trông thế nào#
feat: add optional discount to total
- discount defaults to 0, so existing callers keep working
- checked with: python -m pytest tests/test_prices.py (3 passed)
Dòng đầu nói việc gì, thân bài nói vì sao và đã kiểm bằng gì. Ghi chú này tự nó là bằng chứng nhỏ, hợp với cách 2 trong bài Làm cho kết quả của AI tự chứng minh.
6. Số liệu và tài liệu đã dùng#
| Nguồn | Nói gì | Cách đọc | Lưu ý |
|---|---|---|---|
Git, trang git-restore |
Khôi phục đường dẫn theo một nguồn, nội dung hiện tại bị thay thế | Căn cứ cho cảnh báo mất thay đổi chưa commit | Trang không nói thẳng là không lấy lại được, đó là kết quả tôi thử |
Git, trang git-revert |
Tạo commit mới hoàn tác commit trước, không xóa chúng | Căn cứ cho phần 3.2 | Cần thư mục sạch khi revert |
Git, trang git-reflog |
Ghi lại nơi các tham chiếu từng đứng. Mặc định giữ 90 ngày, 30 ngày với mục không còn trên nhánh | Căn cứ cho phần 3.3 | Chỉ trên máy bạn |
Git, trang git-worktree |
Worktree liên kết dùng chung kho, HEAD và index riêng. Mặc định không cho hai nơi cùng một nhánh |
Căn cứ cho phần 4 | remove cần --force nếu thư mục không sạch |
| Tài liệu Claude Code, Checkpointing | Checkpoint theo dõi chỉnh sửa của công cụ tệp. Không theo dõi tệp chỉ bị Bash đổi, thường không phục hồi sửa đổi của subagent, và không thay quản lý phiên bản | Vì sao vẫn cần Git | Tài liệu của nhà sản xuất công cụ, có thể đổi theo phiên bản |
| Tài liệu Claude Code, Common workflows | claude --worktree tên-việc chạy phiên trong worktree riêng, cần kho đã có ít nhất một commit |
Căn cứ cho lối tắt ở phần 4 | Chỉ nói về công cụ này |
| Các bản tin (Tom's Hardware, heise) về vụ Replit, 7/2025 | Một agent bị cho là xóa cơ sở dữ liệu sản xuất của một công ty trong lúc đang có lệnh đóng băng mã | Điểm lưu Git không bao được cơ sở dữ liệu | Phần lớn chi tiết đến từ bài đăng của người trong cuộc, các nguồn khác nhau về khả năng phục hồi |
| Kho thử trong bài này | Mọi lệnh ở phần 2 đến 5 chạy thật | Kết quả có thật | Một kho rất nhỏ, một máy, Git 2.56.0, không phải khảo sát |
Đọc cho đúng: tài liệu Git và Claude Code ủng hộ việc dùng điểm lưu và nhánh riêng. Tôi chưa tìm thấy nghiên cứu đo việc dùng nhánh riêng giảm bao nhiêu sự cố khi dùng agent, nên các thói quen ở trên là thực hành tốt, chưa phải kết quả đo.
7. Chỗ nào có điểm lưu vẫn hỏng#
Hình dung bạn lưu game ở máy này nhưng nhân vật đã làm gì đó ở thế giới thật bên ngoài.
| Tình huống | Vì sao hỏng | Cách tránh hoặc bắt |
|---|---|---|
Thay đổi chưa commit bị restore hoặc reset --hard |
Git không có bản sao | Commit hoặc stash trước, commit nhỏ và thường xuyên |
Agent chạy git clean |
Tệp chưa theo dõi không có bản sao trong Git | Cấm trong luật, thêm tệp quan trọng vào Git |
Agent push, nhất là --force |
Thay đổi đã lên máy chủ, người khác kéo về | Không cho push, bảo vệ nhánh chính, không bao giờ --force |
| Lộ khóa trong commit | Khóa nằm trong lịch sử, revert không xóa được |
Dùng .gitignore, và coi khóa đã lộ là phải đổi |
| Việc ngoài kho: xóa cơ sở dữ liệu, gửi thư, gọi API trả phí | Git chỉ lưu tệp | Tách môi trường thử, giới hạn quyền, xem bài gói không tồn tại về quyền chạy lệnh |
| Lệnh Bash đổi tệp mà công cụ chưa theo dõi | Checkpoint của công cụ không phủ | Dựa vào Git, không chỉ dựa vào nút hoàn tác |
| Quá nhiều commit lẫn lộn | Khó biết điểm nào tốt | Mỗi commit một việc, ghi chú rõ |
7.1 Minh họa: một sáng với agent#
Đây là tình huống minh họa, không nhắc đến người hay sản phẩm thật.
- 09:00. Dev tạo nhánh
agent/add-discount, giao việc "thêm giảm giá cho hàm tính tổng". - 09:20. Agent báo xong. Dev chạy
git diff --statthấy một tệp đổi nhiều hơn dự kiến. Đọc kỹ thì agent đã viết lại cả hàm cũ. - 09:25. Chưa commit, nên dev có hai lựa chọn:
git restore(mất hết, kể cả phần tốt) hoặcgit stashrồi chọn phần cần. Dev chọn stash, giữ lại phần tốt, rồi nhờ agent làm lại gọn hơn. - 10:10. Agent commit lần hai. Dev nhận ra commit này làm hỏng một test và chạy
git revert HEAD. Lịch sử giữ nguyên, hàm về lại như trước. - 10:30. Dev gộp vào
mainsau khi đọc diff.
Việc nên làm: commit sớm, đọc diff trước khi nhận, và quen với stash và revert hơn restore và reset. Minh họa này không chứng minh điều gì. Bằng chứng nằm ở các tài liệu trên, và ở một vụ có thật đáng nhớ: các bản tin năm 2025 kể rằng trong một thử nghiệm của một nhà sáng lập, một agent bị cho là đã xóa cơ sở dữ liệu sản xuất dù đang có lệnh đóng băng mã. Các nguồn không thống nhất về chi tiết, như khả năng phục hồi, và phần lớn thông tin đến từ chính người trong cuộc. Nếu đúng như kể thì đây là chuyện của một cơ sở dữ liệu chứ không phải tệp, tức là nằm ngoài những gì điểm lưu Git bao được.
8. Thói quen áp dụng từ ngày mai#
8.1 Tám câu hỏi trước khi giao việc và trước khi nhận#
- Mình đang ở nhánh riêng của việc này chưa, hay đang ở
main? - Trước khi giao,
git statuscó sạch không, có việc dở nào chưa lưu? - Agent biết luật Git chưa (nhánh riêng, commit nhỏ, không push)?
- Sau khi agent làm, mình đã đọc
git statusvàgit diffchưa? - Có tệp nào bị sửa mà mình không nhờ không?
- Có thứ gì giống khóa hay mật khẩu trong diff không?
- Nếu bỏ lần sửa này, mình dùng
stash,restorehayrevert, và mình có đang mất thứ chưa commit không? - Việc này có chạm vào thứ ngoài kho (cơ sở dữ liệu, thư, API) không?
8.2 Ba việc làm ngay#
- Dán khối năm dòng ở 5.2 vào tệp hướng dẫn của công cụ bạn đang dùng.
- Thử một lần trong kho nháp:
reset --hardrồireflogrồi đặt lại, để lúc cần không hoảng. - Bật bảo vệ nhánh
maintrên dịch vụ lưu mã bạn dùng, nếu có.
9. Nhìn cân bằng: Git làm được gì, chưa làm được gì#
Làm được: cho bạn điểm lưu, để thử không sợ hỏng, cho phép nhiều việc chạy song song nhờ worktree, và làm mọi thay đổi của agent hiện ra dưới dạng diff đọc được.
Chưa làm được:
- Không bao được thứ ngoài kho: cơ sở dữ liệu, thư đã gửi, tiền đã chuyển.
- Không cứu được thay đổi chưa commit.
- Không ngăn agent làm điều xấu, chỉ giúp bạn quay lại sau khi chuyện xảy ra. Ngăn chặn cần quyền hạn và luật.
- Học Git có chi phí. Với người mới, vài lệnh ở bài này đã đủ để bắt đầu. Các tình huống phức tạp như xung đột khi gộp cần thêm thời gian học.
- Tôi chưa thấy thử nghiệm đối chứng đo hiệu quả của từng thói quen. Hãy thử trong nhóm bạn và điều chỉnh.
Đừng thổi phồng: Git không phải công tắc an toàn. Đừng coi nhẹ: phần lớn tai nạn khi dùng agent trên tệp đều có thể giảm xuống thành chuyện "mất 20 phút" nếu có điểm lưu gần đó.
10. Kết luận#
Agent nhanh, và nhanh cả khi sai. Hãy cho mỗi việc một nhánh riêng, bắt nó lưu thường xuyên, đọc diff trước khi nhận, và nhớ bốn đường lui: restore cho phần chưa commit (và hiểu nó là mất thật), revert cho commit đã có, reflog để cứu sau khi lỡ tay, worktree để mỗi agent có một bàn làm việc riêng. Điểm lưu không làm agent bớt sai, nhưng làm bạn bớt sợ.
Nguồn tham khảo#
Số liệu và lệnh dựa trên tài liệu công khai và một kho thử chạy ngày 30/10/2026 (Git 2.56.0). Các bản tin về vụ Replit chủ yếu thuật lại bài đăng của người trong cuộc, nên hãy mở nguồn gốc để kiểm tra trước khi trích dẫn.
- Git, git-restore, git-revert, git-reflog, git-worktree
- Anthropic, Checkpointing và Common workflows, mục Run parallel sessions with worktrees
- Tom's Hardware, AI coding platform goes rogue during code freeze and deletes entire company database và heise (7/2025)
- Conventional Commits, Specification 1.0.0
Câu hỏi thường gặp
- Vì sao cần Git khi đã có chức năng hoàn tác của công cụ agent?
- Tài liệu Claude Code nói rõ checkpoint chỉ là cách phục hồi nhanh trong một phiên: nó không theo dõi thay đổi do lệnh Bash tạo ra trên tệp mà agent chưa sửa bằng công cụ chỉnh sửa, thường không phục hồi sửa đổi của subagent và không thay cho quản lý phiên bản. Git giữ lịch sử lâu dài và dùng được với mọi công cụ.
- Nên dùng lệnh nào để hủy thay đổi agent vừa làm?
- Nếu chưa commit, git restore tên-tệp đưa tệp về bản đã commit gần nhất, nhưng phần chưa commit bị mất hẳn. Nếu đã commit, git revert tạo một commit mới để đảo lại, giữ nguyên lịch sử nên an toàn. Git reset --hard kéo cả nhánh lùi về và xóa thay đổi chưa commit, chỉ dùng khi hiểu rõ.
- Lỡ chạy git reset --hard thì có lấy lại được không?
- Với các commit thì thường được: git reflog ghi lại nơi nhánh và HEAD từng đứng, rồi bạn đặt lại bằng git reset --hard HEAD@{1} (số thứ tự tùy bản ghi). Mặc định mục reflog giữ 90 ngày, và 30 ngày với mục không còn nằm trên nhánh nào. Phần chưa commit thì không có bản ghi nào để cứu.
- Git worktree dùng để làm gì với agent?
- Worktree tạo thêm một thư mục làm việc riêng, gắn với cùng kho Git và một nhánh riêng. Agent làm ở đó thì không đụng vào tệp bạn đang sửa, và hai việc song song không giẫm lên nhau. Claude Code có sẵn tùy chọn claude --worktree tên-việc cho mục đích này.
- Có nên cho agent tự push lên main không?
- Không nên. Hãy để agent làm trên nhánh riêng, chỉ commit, và bạn tự đọc diff rồi mới đẩy hoặc gộp. Không dùng push --force. Nhiều dịch vụ lưu mã có tính năng bảo vệ nhánh chính, nên bật nó như một lớp chặn thứ hai.