# Git khi code nằm trong repo của khách: danh tính, remote, credential và luật review

> Ngày đầu ở site khách, lỗi Git đáng sợ nhất thường không phải conflict mà là một commit mang sai email bị đẩy lên sai server.

Bản gốc: https://fdetimes.net/vi/bach-khoa/git-khi-code-nam-trong-repo-cua-khach/

Thử hình dung tuần đầu ở site của một ngân hàng. Bạn nhận một laptop bị khoá quyền cài đặt, một tài khoản trên GitLab nội bộ, và một repo có cả chục nhánh mang tên các chi nhánh.

Đến chiều thứ ba, merge request đầu tiên của bạn nằm im vì nút Merge bị khoá, còn trong lịch sử commit thì email cá nhân của bạn đang nằm cạnh email công ty khách.

Chẳng có gì ở đây khó về mặt kỹ thuật. Nhưng chính những lỗi kiểu này làm khách mất niềm tin nhanh hơn một bug: nó cho thấy bạn chưa hiểu môi trường của họ.

Với FDE, Git ở site khách là kỹ năng vận hành, gồm năm việc: cài đặt trên máy không phải của mình, giữ đúng danh tính, quản lý nhiều remote, giữ credential an toàn, và tôn trọng luật review của khách.

## Máy của khách, luật của khách

Việc đầu tiên là có Git chạy được. Pro Git hướng dẫn trên các bản Linux họ Debian như Ubuntu thì dùng `apt`. Trên macOS từ Mavericks (10.9) trở lên, chỉ cần gõ `git` trong Terminal lần đầu, máy sẽ đề nghị cài Xcode Command Line Tools.

Windows là chỗ hay vướng. Bản chính thức đến từ Git for Windows, một dự án tách riêng khỏi Git, còn gói trên Chocolatey là do cộng đồng duy trì. Trên VM bị khoá của khách, hãy hỏi bộ phận IT xem họ cho phép nguồn nào trước khi tự tải về, vì tải nhầm nguồn có thể biến thành một ticket bảo mật.

Nếu hệ điều hành của khách đi kèm một bản Git quá cũ, Pro Git nhắc rằng cài từ source sẽ cho bạn bản mới nhất. Đây là lựa chọn cuối, chỉ dùng khi khách cho phép build trên máy họ.

## Thư mục nào, danh tính nấy

Lỗi phổ biến nhất của người làm cho nhiều khách là commit bằng `user.email` toàn cục. Tài liệu `git config` mô tả đúng tình huống này: có thể dùng `user.name` và `user.email` khác nhau tùy thư mục chứa worktree, thông qua `includeIf` với điều kiện `gitdir`.

Cách tổ chức đơn giản nhất là mỗi khách một thư mục. Trong `~/.gitconfig`:

```ini
[user]
name = Nguyen Van A
email = a@congty-cua-ban.vn

[includeIf "gitdir:~/clients/nganhang/"]
path = ~/clients/nganhang/.gitconfig
```

Và trong `~/clients/nganhang/.gitconfig`:

```ini
[user]
email = a.nguyen@nganhang-noibo.vn
```

Mọi repo nằm dưới `~/clients/nganhang/` tự động dùng email khách cấp. Kiểm tra bằng cách `cd` vào một repo trong đó và chạy `git config user.email`. Tài liệu `git config` dùng đúng kiểu điều kiện này để áp một cấu hình cho mọi repo bên trong một thư mục, nên bạn chỉ cần khai báo một lần cho mỗi khách.

**Điểm mấu chốt:** Đừng dựa vào trí nhớ để đổi email trước mỗi commit; hãy để cấu trúc thư mục làm việc đó thay bạn.

## Origin là của ai?

Khi bạn clone từ GitLab của khách, remote mặc định tên là `origin`. Vài tuần sau, bạn có thêm một repo nội bộ của công ty mình để giữ code tích hợp dùng chung, và `origin` bắt đầu mập mờ. Hãy đổi tên ngay từ đầu:

```bash
git remote rename origin nganhang
git remote add noibo git@git.congty-cua-ban.vn:fde/connector.git
git fetch noibo
git branch -r
```

Theo tài liệu `git remote`, lệnh rename cập nhật luôn mọi remote-tracking branch và cấu hình liên quan, nên bạn không phải sửa tay. Sau `git fetch noibo`, các nhánh xuất hiện dưới dạng `noibo/feature-x`, tách bạch với `nganhang/feature-x`.

Tài liệu Git còn khuyên một điều đáng nhớ: nếu bạn fetch từ một nơi và push đến nơi khác, hãy dùng hai remote riêng. Ở site khách, quy tắc này tránh được kịch bản tệ nhất là đẩy code của khách lên server của công ty bạn, hoặc ngược lại. Trước mỗi lần push, gõ rõ tên remote (`git push nganhang feature/x`) thay vì để Git tự đoán.

Với repo có nhiều nhánh theo từng chi nhánh hay từng khách con, tên remote rõ ràng giúp `git branch -r` đọc được như một bản đồ. Bạn biết nhánh nào là của ai chỉ bằng tiền tố.

## Mật khẩu nằm ở đâu trên máy người khác?

Mặc định Git không lưu credential, nên mỗi lần push qua HTTPS bạn phải gõ lại. Phản xạ tự nhiên là bật helper `store`, và đây là sai lầm trên máy của khách. Pro Git ghi rõ: chế độ `store` lưu credential vào một file plain text trên đĩa và không bao giờ hết hạn.

Trên laptop hay VM do khách sở hữu, nhất là máy dùng chung, một file như vậy là lỗ hổng mang tên bạn. Lựa chọn hợp lý hơn là helper `cache`, giữ credential trong bộ nhớ và xoá sau 15 phút:

```bash
git config --global credential.helper cache
```

Hơi phiền vì cứ mỗi quãng nghỉ dài lại phải nhập lại, nhưng sự phiền đó rẻ hơn nhiều so với một cuộc điều tra bảo mật. Nếu khách có chính sách riêng về token, hãy theo chính sách đó.

## Đọc luật review trước khi viết code

Quay lại merge request bị khoá. Trên GitLab, khách có thể bật required approvals: theo tài liệu GitLab, khi chưa có đủ phê duyệt từ những người được chỉ định thì không thể merge. Đây không phải lỗi, mà là quy trình của họ.

Câu hỏi là ai phải duyệt. GitLab dùng file `CODEOWNERS` để xác định reviewer theo từng file. Nếu bạn sửa cả thư mục thanh toán lẫn thư mục báo cáo trong một merge request, rất có thể bạn đang cần hai nhóm khác nhau cùng gật đầu, và MR của bạn sẽ chờ người chậm nhất.

Vì thế, trước khi tạo nhánh, hãy mở `CODEOWNERS` và tìm các dòng khớp với đường dẫn bạn định chạm vào. Chia thay đổi sao cho mỗi merge request chỉ cần một nhóm owner, và nhắn trước cho họ một câu ngắn về việc bạn sắp gửi. Một MR nhỏ, đúng người, được giới thiệu trước thường đi nhanh hơn một MR lớn rơi vào hộp thư của ba team.

## Những lỗi lặp đi lặp lại

Lỗi hay gặp nhất là commit bằng email cá nhân vào repo khách, sửa được bằng includeIf trước khi viết dòng code đầu tiên. Kế đó là để mọi thứ tên `origin` rồi push nhầm server. Rồi đến chuyện bật `store` trên máy dùng chung vì ngại gõ mật khẩu.

Lỗi cuối khó thấy hơn: coi quy trình review của khách là vật cản và tìm cách đi đường vòng. Approval và CODEOWNERS cho bạn biết ai thật sự sở hữu phần code đó, tức là những người bạn cần quen sớm.

Nếu bạn đang chuẩn bị CV cho vị trí FDE, hãy thay dòng "thành thạo Git" bằng một câu cụ thể: "làm việc trên GitLab nội bộ của khách với required approvals và CODEOWNERS, quản lý nhiều remote và danh tính theo khách". Chuẩn bị thêm một ví dụ ngắn về lần bạn chia MR theo nhóm owner để kể khi phỏng vấn.

Ở site khách, repo không phải của bạn, nhưng mỗi commit vẫn ký tên bạn. Cấu hình đúng từ ngày đầu là cách rẻ nhất để chữ ký ấy luôn đáng tin.

**Thử ngay tuần này:**

- Tạo thư mục ~/clients/ và một file .gitconfig riêng cho một khách giả định, nối bằng includeIf, rồi chạy git config user.email trong và ngoài thư mục để kiểm tra.
- Trong một repo cá nhân, đổi origin thành tên khách bằng git remote rename, thêm remote thứ hai, rồi chạy git branch -r để xem remote-tracking branch.
- Mở một repo GitLab bất kỳ có file CODEOWNERS, liệt kê ai phải review thư mục bạn định sửa trước khi tạo nhánh.

## Nguồn

- [Git - Installing Git](https://git-scm.com/book/en/v2/Getting-Started-Installing-Git)

- [Git - git-remote Documentation](https://git-scm.com/docs/git-remote)

- [Merge request approvals (GitLab Docs)](https://docs.gitlab.com/ee/user/project/merge_requests/approvals/)

- [Git - Credential Storage](https://git-scm.com/book/en/v2/Git-Tools-Credential-Storage)

- [Git - git-config Documentation](https://git-scm.com/docs/git-config)
