# ผมใช้ AI ย้าย GitLab ทีละหลายสิบ repo ยังไง
Table of Contents
ทำไมงานนี้เหมาะกับ AI
migration เป็นงานที่ น่าเบื่อและพลาดง่ายเมื่อทำมือ แต่มี pattern ชัดมาก — แต่ละ repo ต้องทำขั้นตอนเดิมซ้ำ: mirror → copy CI vars → grant member → verify นี่คือลักษณะงานที่ AI ช่วยได้ดีที่สุด เพราะ:
- ขั้นตอน ซ้ำเดิมทุก repo — คนทำสิบตัวก็เริ่มลืมขั้น พลาดบางอย่าง แต่ AI ทำเหมือนเดิมทุกครั้ง
- เกือบทุกอย่างทำผ่าน CLI กับ API (git, GitLab API) — สิ่งที่ Claude Code รันได้จริงใน terminal
- การ verify คือ นับตัวเลขให้ตรง (branch/tag/CI var) — งานที่คนขี้เกียจทำครบ แต่ AI ทำให้ทุก repo
- พอเสร็จต้องมี migration report — น่าเบื่อสำหรับคน แต่ AI สรุปให้ระหว่างทางได้ฟรีๆ
ขั้นที่ 1 — วางแผนวิธีย้ายก่อน
ผมไม่เริ่มจากสั่ง “ย้ายเลย” — ผมให้ Claude ช่วยตัดสินใจก่อนว่าจะใช้วิธีไหน เพราะ GitLab มีหลายทางย้าย แต่ละแบบเหมาะกับงานต่างกัน
| วิธี | ได้อะไรมาด้วย | เหมาะกับ |
|---|---|---|
| Project export/import | code + issues + MR + setting | ย้ายทีละ project พร้อม metadata |
| Git mirror (push) | branch + tag ทั้งหมด (code ล้วน) | ย้ายเป็นชุดเยอะๆ, control ละเอียด |
ใน PoC แรกเราลอง export/import ย้าย service หนึ่งจาก GitLab เวอร์ชันเก่าไปเวอร์ชันใหม่ — ได้ branch ครบ verify ผ่าน เหมาะกับย้ายทีละตัวที่อยากได้ issue/MR ติดไปด้วย
แต่พอต้องย้าย เป็นระลอกหลายสิบ repo ผมกับ Claude สรุปว่าใช้ git mirror เป็นหลักดีกว่า เพราะ control ได้ละเอียดและ verify ง่ายกว่า
ขั้นที่ 2 — ปล่อยให้ AI ทำงานซ้ำๆ ทีละ repo
พอล็อกวิธีได้ ผมให้ Claude ไล่ย้ายทีละ repo ตาม loop เดิม สิ่งที่มันทำให้แต่ละ repo คือ 3 อย่างนี้
mirror code
git clone --mirror https://old-gitlab.example.com/group/repo.gitcd repo.gitgit remote set-url --push origin https://new-gitlab.example.com/new-group/repo.gitgit push --mirrorcopy CI/CD variables ผ่าน API
variable ของ CI ไม่ได้อยู่ใน git — Claude ดึงจากเครื่องเก่าผ่าน API แล้วสร้างที่เครื่องใหม่ให้ครบ (ในงานจริงมีตั้งแต่ 14–29 ตัวต่อ project):
curl -s --header "PRIVATE-TOKEN: $OLD_TOKEN" \ "https://old-gitlab.example.com/api/v4/projects/$OLD_ID/variables" > vars.json
jq -c '.[]' vars.json | while read v; do curl -s --request POST --header "PRIVATE-TOKEN: $NEW_TOKEN" \ "https://new-gitlab.example.com/api/v4/projects/$NEW_ID/variables" \ --data-urlencode "key=$(echo "$v" | jq -r .key)" \ --data-urlencode "value=$(echo "$v" | jq -r .value)"donegrant member ตาม access level เดิม
Claude map สมาชิกและ access level จากเครื่องเก่าให้ตรง level เดิม ส่วน user ที่ยังไม่มี account บนเครื่องใหม่ก็ log ไว้เพื่อส่ง invite ทีหลัง ไม่ปล่อยให้เงียบหาย
ขั้นที่ 3 — Verify ด้วยตัวเลข ทุก repo
นี่คือจุดที่ AI ช่วยได้เด่นมาก — นับให้ตรงทุก repo ผมให้ Claude verify หลังย้ายแต่ละตัวด้วย output จริง ไม่ใช่เชื่อว่า “push ผ่าน = เสร็จ”
# ฝั่งเก่าgit ls-remote --heads https://old-gitlab.example.com/group/repo.git | wc -lgit ls-remote --tags https://old-gitlab.example.com/group/repo.git | wc -l# ฝั่งใหม่ — ต้องได้ตัวเลขเท่ากันเป๊ะgit ls-remote --heads https://new-gitlab.example.com/new-group/repo.git | wc -lgit ls-remote --tags https://new-gitlab.example.com/new-group/repo.git | wc -lในระลอกจริง Claude verify ให้ว่า “26/26 repos mirrored, branch/tag counts ตรงเป๊ะ, CI vars copied ครบ” — ตัวเลขพวกนี้คือสิ่งที่ทำให้ผมมั่นใจว่าย้ายครบจริง ไม่ใช่เดา
ขั้นที่ 4 — ให้เขียน Migration Report
ขั้นที่ผมชอบที่สุด — พอจบแต่ละระลอก ผมให้ Claude สรุปเป็น batch-migration-report.md ระหว่างที่ context ยังครบ ว่าย้ายอะไรไปบ้าง verify อะไรแล้ว และอะไรที่ยัง block
report นี้คือ source of truth เวลามีคนถามว่า “repo นี้ย้ายหรือยัง” และเป็นหลักฐานว่าเรา verify จริง ไม่ใช่เดาว่าน่าจะครบ — ระลอกถัดไปก็แค่บอก Claude ว่า “ทำตามแบบระลอกก่อน แต่เปลี่ยนเป็น group นี้” มันก็ทำซ้ำได้เลย
สิ่งที่ผมยังตัดสินใจเอง
ถึงจะให้ AI ทำงานซ้ำๆ เยอะ แต่มีเรื่องที่ผม ไม่ปล่อยให้มันตัดสินใจแทน:
- access level ของ member — ใครควรได้สิทธิ์ระดับไหนบนเครื่องใหม่ เป็นเรื่อง security ที่ผม review เอง
- branch ไหนแตะได้ — main ของ production ผมคุมเองว่าจะ force-push ทับหรือไม่
- repo ที่ติด protected-branch — มีระลอกที่ re-sync แล้ว 1 repo ถูก protected-branch rule บล็อก force-push ซึ่งถูกต้องแล้ว (งานย้ายไปอยู่เครื่องใหม่จริง) ผมเป็นคนตัดสินว่าปล่อยไว้แบบ new-ahead ไม่ฝืน
- token / secret — ไม่ commit ค่า CI variable จริงเข้า git เด็ดขาด
สรุป
workflow ของผมกับ Claude Code สำหรับย้าย GitLab เป็นชุดสรุปเป็น 4 ขั้น:
- วางแผนวิธีย้าย — export/import vs mirror ให้ตรงงาน
- ปล่อยให้ AI ทำงานซ้ำ ทีละ repo — mirror, CI vars, member
- verify ด้วยตัวเลข ทุก repo — นับ branch/tag/var ให้ตรง
- ให้เขียน migration report ทุกระลอก
มันไม่ได้แทนความเข้าใจเรื่อง GitLab ของผม — แต่ทำให้ผมโฟกัสกับ การตัดสินใจ (วิธีย้าย, สิทธิ์, branch policy) ส่วนงาน mechanical ที่ซ้ำหลายสิบรอบและพลาดง่ายก็ให้ AI ไล่ให้ครบ ผลคือย้ายเสร็จเร็วขึ้น พลาดน้อยลง และมี report ครบทุกระลอก