Git cho vibe coding: Quản lý thay đổi do AI tạo ra

Bạn nhờ AI sửa một lỗi nhỏ. Nửa giờ sau, nó đã thay đổi 28 file: vài trang hướng dẫn, một số khai báo kiểu dữ liệu, ba thành phần giao diện, hai đường dẫn API, một file cấu hình và cả hàm tính toán đang được dùng.
AI báo “đã hoàn thành, toàn bộ kiểm tra đều đạt”. Bạn nhìn danh sách file nhưng không biết nên đọc từ đâu. Cuối cùng, bạn có hai lựa chọn đều không tốt: tin toàn bộ hoặc bỏ toàn bộ.
Đây là lúc Git cần được nhìn theo một cách khác.
Với vibe coder, Git không chỉ là nơi lưu code lên GitHub và cũng không chỉ là nút “hoàn tác”. Git là hệ thống quản lý thay đổi giữa con người và AI: nó giữ lại các mốc có ý nghĩa, tách thử nghiệm khỏi phần đang hoạt động, làm rõ điều gì đã đổi và giúp người dùng dành sự chú ý cho đúng nơi có rủi ro.
Tư duy trong bài được phát triển từ hai Agent Skills của Vnstock: git-commit-grouped, tập trung vào việc chia thay đổi thành những commit có mục đích rõ; và git-master, tổ chức Git thành quy trình an toàn, dễ duyệt và có thể tiếp tục qua nhiều phiên làm việc.
Bài viết chỉ giải thích các concept và logic ra quyết định. Những quy trình thực thi, công cụ hỗ trợ, tình huống phục hồi và chỉ dẫn chi tiết vẫn nằm trong skill.
Vấn đề mới của vibe coding không phải tốc độ viết code
Trước khi có coding agent, một người có thể mất cả buổi để sửa năm file. Họ thường nhớ mình vừa làm gì vì từng thay đổi đi qua tay mình.
AI có thể sửa năm mươi file trong thời gian ngắn hơn. Tốc độ tạo thay đổi tăng lên, nhưng tốc độ đọc, hiểu và đánh giá của con người không tăng tương ứng. Nút thắt chuyển từ viết code sang kiểm soát thay đổi.
Đây là khác biệt quan trọng:
| Câu hỏi cũ | Câu hỏi cần thêm khi dùng AI |
|---|---|
| Code có chạy không? | AI đã thay đổi những hành vi nào ngoài yêu cầu? |
| Lỗi đã hết chưa? | Phần sửa có làm yếu kiểm tra hoặc che lỗi không? |
| Test có xanh không? | Test nào thực sự bao phủ thay đổi quan trọng? |
| Có thể commit chưa? | Các thay đổi có đang bị trộn thành một khối khó duyệt không? |
| Có thể phát hành chưa? | Người dùng có biết phần nào cần xác nhận và phần nào chưa được kiểm tra không? |
Tài liệu GitHub về review code do AI tạo cũng nhấn mạnh việc kết hợp đánh giá của con người với công cụ tự động, kiểm tra các thư viện phụ thuộc được đề xuất và xem xét những bài kiểm tra còn thiếu.1 AI có thể hỗ trợ review, nhưng trách nhiệm chấp nhận thay đổi vẫn cần một điểm kiểm soát của con người.
Ba vai trò của Git khi làm việc cùng AI
Một quy trình Git dễ hiểu cho vibe coder nên bắt đầu từ tác dụng, không phải câu lệnh.
Git giữ mốc để quay lại, giữ lịch sử để truy vết và chia thay đổi để con người duyệt được
Lưới an toàn
Trước một thay đổi lớn, dự án cần có một trạng thái đang hoạt động mà bạn biết có thể quay lại. Mốc an toàn không nhất thiết chứng minh code hoàn hảo; nó chứng minh bạn biết mình đang đứng ở đâu trước khi thử điều mới.
Lưới an toàn chỉ có giá trị khi mốc đó thực sự tồn tại và có thể tìm lại. Copy thư mục thành project-final-backup-2 tạo cảm giác yên tâm nhưng không nói rõ nó khác bản hiện tại ở đâu, được tạo lúc nào và có qua kiểm tra hay chưa.
Cỗ máy thời gian
Git giữ lịch sử để bạn trả lời:
- thay đổi nào xuất hiện trước khi kết quả bắt đầu lệch;
- file nào từng hoạt động ở một mốc cụ thể;
- quyết định cũ được đưa ra vì lý do gì;
- phần nào có thể lấy lại mà không xóa những việc tốt làm sau đó.
“Quay lại” không phải lúc nào cũng có nghĩa đưa toàn bộ dự án về quá khứ. Đôi khi chỉ một file cần phục hồi; đôi khi nên sửa tiếp về phía trước; đôi khi cần mở một nhánh riêng từ mốc cũ để so sánh. Tư duy tốt bắt đầu bằng việc bảo toàn các lựa chọn, không vội chọn thao tác mạnh nhất.
Bộ lọc review
Một bản so sánh thay đổi — thường được gọi là diff — gồm 3.000 dòng không phải là một đơn vị review hữu ích. Git phát huy giá trị khi thay đổi được chia thành các nhóm mà con người có thể hiểu:
- nhóm này chỉ sửa câu chữ;
- nhóm kia thay đổi cấu trúc hoặc contract;
- nhóm tiếp theo tác động giao diện;
- nhóm cuối thay đổi logic, phép tính hoặc hành vi vận hành.
Khi đó, người dùng không cần dành cùng một mức tập trung cho mọi file. Sửa chính tả có thể đọc nhanh; thay đổi công thức, quyền truy cập hoặc cấu trúc dữ liệu cần xem kỹ hơn.
Commit không phải nút Save
Nhiều vibe coder xem commit như một lần bấm lưu sau khi AI làm xong mọi thứ. Cách này tạo ra những lịch sử kiểu:
update
fix again
final changes
working nowNhững commit này cho biết đã có hoạt động, nhưng không kể được dự án đã thay đổi như thế nào.
Một commit tốt là một đơn vị quyết định. Nó nên đủ nhỏ để hiểu, đủ trọn vẹn để có lý do tồn tại và đủ độc lập để người khác có thể đánh giá ảnh hưởng.
Commit tốt kể được dự án đã thay đổi thế nào và vì sao
Đó là ý nghĩa của atomic commit — commit nguyên tử. “Nguyên tử” không có nghĩa chỉ được sửa một file hoặc vài dòng. Nó có nghĩa mọi thay đổi bên trong cùng phục vụ một mục đích.
Ví dụ, việc đổi tên một khái niệm có thể chạm type, giao diện, liên kết và tài liệu. Nếu tất cả cùng phục vụ một lần đổi tên, nhóm theo chủ đề có thể dễ hiểu hơn việc ép chúng thành bốn commit theo loại file.
Ngược lại, nếu cùng một file chứa cả sửa giao diện lẫn đổi công thức, hai phần nên được nhìn như hai quyết định khác nhau. Ranh giới commit nằm ở ý nghĩa, không nằm ở ranh giới file.
Duyệt từ dễ tới khó để sử dụng sự chú ý đúng chỗ
Khi AI tạo nhiều thay đổi, người dùng dễ mở ngay file phức tạp nhất rồi nhanh chóng mệt và bỏ cuộc. Một thứ tự duyệt có chủ đích giúp giảm tải nhận thức.
Logic chung là:
- Đọc phần giải thích và nội dung để hiểu mục tiêu.
- Xem contract, schema hoặc cấu hình để biết hình dạng nào đang thay đổi.
- Kiểm tra phần trình bày để thấy tác động người dùng.
- Dành sự tập trung cao nhất cho logic, phép tính, quyền và dữ liệu.
- Xem công cụ tự động hóa cùng bằng chứng kiểm tra liên quan.
Đọc nhanh phần dễ, dồn sự tập trung cao nhất cho logic, phép tính, quyền và dữ liệu
Đây không phải một thứ tự cứng cho mọi dự án. Nếu một tính năng chỉ chạy được khi type, logic và UI đi cùng nhau, chia theo tính năng sẽ dễ duyệt hơn chia theo tầng. Nếu lịch sử cần hỗ trợ việc tìm commit gây lỗi, mỗi mốc còn cần giữ được trạng thái đủ nhất quán để kiểm tra.
Nguyên tắc cần giữ là: thứ tự commit phục vụ khả năng hiểu và xác minh, không phục vụ vẻ đẹp hình thức của lịch sử.
Commit message là nhật ký quyết định
Diff đã cho biết dòng nào được thêm và xóa. Commit message cần bổ sung những thứ diff không tự kể:
- Vì sao thay đổi này cần thiết?
- Quyết định nào đã được chọn giữa các phương án?
- Kết quả hoặc hành vi nào sẽ khác?
- Có ảnh hưởng tương thích không?
- Cần chạy lại, chuyển đổi hoặc kiểm tra việc gì?
So sánh hai cách viết:
fix calculationvà:
fix: giữ nguyên đơn vị khi chuẩn hóa chuỗi giá
Nguồn đầu vào có thể biểu diễn cùng mức giá theo hai đơn vị.
Thay đổi đưa bước quy đổi về một vị trí duy nhất trước khi tính toán.
Ảnh hưởng: kết quả lịch sử cần được đối chiếu lại trước khi dùng tiếp.Ví dụ thứ hai chưa cần kể từng file, nhưng người đọc sau ba tháng vẫn hiểu quyết định và biết nên kiểm tra điều gì.
Lịch sử Git vì thế không chỉ phục vụ việc quay lại. Nó là bộ nhớ mang theo dự án khi đổi máy, đổi AI agent hoặc mở cuộc trò chuyện mới.
Mọi thay đổi không có cùng mức rủi ro
Một lỗi chính tả, một màu nút, một schema mới và một phép tính không nên được xử lý bằng cùng một mức cẩn trọng.
Có thể đánh giá rủi ro qua bốn câu hỏi:
- Phạm vi: bao nhiêu phần của hệ thống phụ thuộc vào thay đổi?
- Khả năng phát hiện: nếu sai, chương trình có báo lỗi hay vẫn chạy với kết quả lệch?
- Khả năng phục hồi: có mốc an toàn và cách khôi phục đã được xác định không?
- Tác động bên ngoài: thay đổi chỉ nằm trên máy hay sẽ ảnh hưởng repository dùng chung, người dùng hoặc môi trường đang hoạt động?
Thay đổi nguy hiểm nhất không phải lúc nào cũng là file dài nhất. Đổi đơn vị nhưng giữ nguyên kiểu số có thể không gây lỗi kỹ thuật; chương trình vẫn chạy trong khi kết quả đã sai ý nghĩa. Vì vậy, data contract, schema dữ liệu và Git cần nối với nhau: contract cho biết điều gì phải giữ, test tạo bằng chứng, còn Git ghi lại thay đổi và lý do.
Thay đổi công thức cần bằng chứng, không chỉ cần test xanh
Khi AI “tối ưu” hoặc tái cấu trúc một phép tính, mục tiêu có thể là chạy nhanh hơn, dễ đọc hơn hoặc dùng thư viện khác. Dù code mới trông hợp lý, câu hỏi quan trọng vẫn là: kết quả có còn tương đương với phiên bản trước không?
Một cách tư duy khoa học gồm:
- Chọn một đầu vào cố định có thể chạy lại.
- Ghi nhận kết quả của phiên bản cũ trước khi sửa.
- Chạy phiên bản mới trên đúng đầu vào đó.
- So sánh giá trị, thứ tự, kiểu dữ liệu, trường thiếu và sai số cho phép.
- Ghi bằng chứng cùng quyết định thay đổi.
Nếu mỗi lần so sánh lại gọi dữ liệu đang tiếp tục cập nhật từ bên ngoài, hai đầu vào có thể khác nhau và làm kết luận mất ý nghĩa. Mục tiêu không phải chứng minh code mới “hay hơn”, mà tách thay đổi triển khai khỏi thay đổi kết quả.
Trong nghiên cứu định lượng, đây là ranh giới giữa refactor — sắp xếp lại code mà không chủ đích đổi kết quả — và thay đổi phương pháp. Một lần refactor phải chứng minh kết quả được giữ trong phạm vi sai số đã chọn. Nếu kết quả cần thay đổi, commit phải nói rõ đó là quyết định có chủ đích.
Branch là không gian thử nghiệm, không phải bản sao dự án
Khi muốn thử một ý tưởng rủi ro, nhiều người copy cả thư mục. Sau vài ngày, họ có hai cây code và không biết file nào đã được sửa ở đâu.
Branch, hay nhánh Git, giải quyết vấn đề này bằng cách giữ thử nghiệm trong cùng lịch sử. Bạn có thể hiểu branch là một không gian thử nghiệm có tên:
- bản đang dùng vẫn có mốc rõ ràng;
- thử nghiệm có lịch sử riêng;
- kết quả tốt có thể được đưa về theo một quyết định có kiểm soát;
- kết quả không phù hợp có thể dừng mà không làm mất dấu những gì đã thử.
Branch không tự tạo an toàn nếu thư mục làm việc vẫn lộn xộn, nhánh bị xóa khi chưa giữ mốc hoặc thay đổi được gộp mà không review. Công cụ chỉ cung cấp cấu trúc; quy trình mới quyết định cấu trúc đó có đáng tin hay không.
Phân biệt việc trên máy và việc ảnh hưởng người khác
Một coding agent có thể làm nhiều thao tác Git, nhưng không phải thao tác nào cũng có cùng phạm vi quyền.
| Nhóm hành động | Cách suy nghĩ |
|---|---|
| Đọc trạng thái và lịch sử | Thu thập bằng chứng, thường không làm thay đổi dự án |
| Tạo mốc cục bộ | Thay đổi lịch sử trên máy, cần báo rõ đã lưu gì |
| Phục hồi hoặc viết lại | Có khả năng làm phần việc hiện tại khó tìm lại, phải giữ đường lui trước |
| Đưa thay đổi lên kho mã dùng chung | Ảnh hưởng GitHub, GitLab hoặc nơi cộng tác chung, cần sự đồng ý rõ ràng |
| Viết lại lịch sử đã chia sẻ | Có thể ảnh hưởng người khác và công cụ triển khai, không được tự suy đoán quyền |
Nguyên tắc này giúp vibe coder giao quyền cho AI theo tác động, thay vì “cho phép dùng Git” một cách chung chung.
Tương tự, AI không nên bỏ qua các bước kiểm tra tự động của dự án — thường gọi là hook — chỉ để làm commit “thành công”. Một commit bị chặn là tín hiệu cần giải quyết hoặc báo lại, không phải chướng ngại cần lách qua.
Bí mật và file rác phải bị chặn trước khi vào lịch sử
Git có trí nhớ rất tốt. Đó là ưu điểm khi phục hồi code, nhưng trở thành rủi ro nếu API key, token, .env, dữ liệu cá nhân hoặc tệp xuất lớn bị commit.
.gitignore giúp ngăn một số file chưa được theo dõi đi vào commit, nhưng không thay thế việc kiểm tra chính phần đang chuẩn bị lưu. Một file từng được Git theo dõi không tự biến mất khỏi lịch sử chỉ vì sau đó được thêm vào .gitignore.
Convention cho AI nên yêu cầu:
- đọc danh sách file mới trước khi gom thay đổi;
- không in nội dung bí mật để “kiểm tra”;
- dừng khi phát hiện dấu hiệu thông tin xác thực hoặc dữ liệu nhạy cảm;
- không tự dọn lịch sử chứa bí mật nếu chưa có quyết định của người dùng;
- ưu tiên cơ chế lưu khóa tách khỏi workspace, như đã phân tích trong bài Lưu API key an toàn khi dùng coding agent.
Git là bộ nhớ chuyển giao giữa các phiên AI
Một AI agent mới không có ký ức đầy đủ về buổi làm việc hôm qua. Nếu working tree chứa 17 file chưa commit và không có ghi chú, agent mới chỉ thấy trạng thái kỹ thuật, không thấy câu chuyện.
Lịch sử có cấu trúc giúp kể dự án theo ba lớp:
- Nền tảng: những quyết định lớn đang định hình kiến trúc.
- Gần đây: mục tiêu chung của các thay đổi mới nhất.
- Đang làm: nhánh hiện tại, phần hoàn thành và việc còn dở.
Một commit đang làm dở vẫn có thể hữu ích nếu nó nói rõ phần nào đã xong, phần nào chưa và cách kiểm tra hiện trạng. Trước khi đưa vào nhánh chính, lịch sử nháp có thể được sắp xếp lại thành các đơn vị dễ hiểu hơn.
Điểm quan trọng là Git chỉ kể được điều đã được ghi lại. AI không nên suy diễn mục tiêu từ tên file rồi trình bày như sự thật. Khi phải phỏng đoán, báo cáo cần nói rõ đó là suy luận.
Bộ nguyên tắc giao việc Git cho AI agent
Khối dưới đây giúp người mới đặt ranh giới, nhưng không thay thế một quy trình Git đầy đủ:
## Git safety and review rules
- Trước khi thay đổi lịch sử, hãy báo trạng thái hiện tại và phần việc chưa được lưu.
- Chia thay đổi theo mục đích; không gom tài liệu, giao diện và logic không liên quan vào một commit.
- Sắp xếp phần review để thay đổi dễ hiểu được xem trước, phần rủi ro cao được chỉ rõ.
- Commit message phải ghi lý do và ảnh hưởng, không chỉ liệt kê tên file.
- Giữ một đường quay lại trước mọi thao tác có thể làm mất hoặc che khuất công việc.
- Không push, phát hành, xóa remote hoặc viết lại lịch sử dùng chung nếu chưa được đồng ý trong phiên hiện tại.
- Không bỏ qua hook, test hoặc bước kiểm tra để ép commit thành công.
- Dừng khi phát hiện API key, token, `.env`, dữ liệu cá nhân hoặc tệp xuất không nên vào Git.
- Với thay đổi công thức, so sánh kết quả cũ và mới trên cùng một đầu vào cố định.
- Khi kết thúc, báo các mốc đã tạo, kiểm tra đã chạy, phần chưa xác minh và quyết định còn chờ người dùng.Bộ quy tắc trên nói điều AI phải bảo vệ. Chúng chưa nói cách chọn mốc so sánh, xử lý từng tình huống phục hồi, tách riêng từng phần thay đổi, gom lịch sử nháp, đối chiếu nhánh để lâu ngày hoặc dựng báo cáo review. Đó là phần một skill chuyên biệt cần đảm nhiệm.
Khi nào rules là đủ, khi nào cần Git Master?
Rules cơ bản phù hợp khi dự án nhỏ, thay đổi ít và người dùng vẫn dễ đọc toàn bộ diff. Khi AI đã sửa nhiều nhóm file, công thức cần đối chiếu, nhánh tồn tại lâu hoặc người dùng cần quay lại một mốc khó xác định, một danh sách nguyên tắc không còn đủ.
git-master được thiết kế cho những tình huống đó. Trang công khai mô tả skill như lớp hỗ trợ giúp giữ lịch sử an toàn và dễ duyệt, chia thay đổi theo nhóm, thử nghiệm tách biệt, tìm thay đổi làm lệch số liệu và tiếp tục công việc qua phiên mới.2
Giá trị của skill không nằm ở việc AI thuộc nhiều lệnh Git hơn. Giá trị nằm ở việc nó biết:
- tình huống hiện tại thuộc loại rủi ro nào;
- phải bảo toàn điều gì trước khi hành động;
- bằng chứng nào cần thu thập;
- quyết định nào AI có thể tự thực hiện;
- quyết định nào phải trả lại cho người dùng.
Đó cũng là khác biệt giữa một prompt “hãy commit mọi thứ” và một quy trình quản lý dự án bằng AI.
Điều cần nhớ
Git cho vibe coding không bắt đầu từ việc thuộc lệnh. Nó bắt đầu từ cách nhìn mỗi thay đổi như một quyết định cần được bảo toàn, giải thích và kiểm chứng.
Một quy trình tốt cần làm được năm việc:
- Giữ trạng thái đang hoạt động trước thử nghiệm rủi ro.
- Chia thay đổi thành các đơn vị có mục đích rõ.
- Dẫn sự chú ý của người review tới phần có ảnh hưởng lớn.
- Ghi lại lý do, bằng chứng và tác động trong lịch sử.
- Giữ quyền quyết định của con người ở những thao tác ảnh hưởng bên ngoài hoặc khó phục hồi.
AI có thể viết code nhanh, phân tích diff và đề xuất cách tổ chức. Git giúp biến tốc độ đó thành một quá trình có trí nhớ và có đường lui. Khi hai phần được nối bằng rules cùng một skill phù hợp, vibe coder không còn phải chọn giữa “tin AI” và “không dám thay đổi”; họ có một quy trình để biết điều gì đã xảy ra và nên quyết định gì tiếp theo.
Nội dung phục vụ học tập, nghiên cứu và tham khảo. Quy trình Git cần được điều chỉnh theo repository, cách làm việc và mức độ chia sẻ của từng dự án. Không thực hiện thao tác phá hủy hoặc viết lại lịch sử dùng chung khi chưa hiểu rõ tác động và chưa có mốc phục hồi phù hợp.
Footnotes
-
GitHub Docs, Review AI-generated code. ↩
-
Vnstock Agent Skills, Git Master. ↩
