หลังจากที่ผมได้รู้จัก Git Submodules มาซักพักหนึ่ง ผมก็พยายามใช้ในงานต่าง ๆ ซึ่งช่วยให้ผมจัดการ Source code สะดวกขึ้นมาก แต่เนื่องจากได้ใช้คำสั่งพวกนี้ในช่วงเริ่มโปรเจคซะเป็นส่วนใหญ่เลยทำให้มีอาการหลงลืมคำสั่งไปบ้าง ก็เลยมาบันทึกไว้หน่อยจะได้ไม่ต้องไปหาข้อมูลใหม่อีก
การเพิ่ม Submodules เข้ามาใน Git Repository
ใช้คำสั่งดังนี้
$ git submodule add https://github.com/golfz/module1 lib/module1
Initialized empty Git repository in ~/a_project/lib/module1/.git/
remote: Counting objects: 1006, done.
remote: Compressing objects: 100% (978/978), done.
remote: Total 1006 (delta 631), reused 0 (delta 0)
Receiving objects: 100% (1006/1006), 408.22 KiB, done.
Resolving deltas: 100% (631/631), done.
แต่ละส่วนของคำสั่งมีรายละเอียดดังนี้
git submodule add เป็นคำสั่ง git เพื่อเพิ่ม Submodules
https://github.com/golfz/module1 คือ git repository ภายนอกที่เราต้องการเพิ่มเข้ามาเป็น submodule ซึ่งคุณต้องมั่นใจว่าคุณมีสิทธิ clone repository นี้
lib/module1 คือ path ของ submodules ใน repository หลัก
ลองตรวจสอบ repository ดูด้วย git status
$ git status
# On branch master
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
# new file: .gitmodules
# new file: lib/module1
#
ถ้าเราลองตรวจสอบ .gitmodules ที่เพิ่มเข้ามาใหม่ จะพบข้อมูลดังนี้
$ cat .gitmodules
[submodule "lib/module1"]
path = lib/module1
url = https://github.com/golfz/module1
การใช้งาน Submodules
ถ้าเราเพิ่ม clone repository ลงมา เราจะพบว่าโฟลเดอร์ที่เป็น submodule จะว่างเปล่า ดังนั้นเราต้อง initial submodules ก่อน ดังนี้
$ git submodule init
Submodule 'lib/module1' (https://github.com/golfz/module1) registered for path 'lib/module1'
ขั้นตอนต่อไปเราจำเป็นต้อง pull files ลงมา
$ git submodule update
Initialized empty Git repository in ~/a_project/lib/module1/.git/
remote: Counting objects: 26, done.
remote: Compressing objects: 100% (22/22), done.
remote: Total 26 (delta 5), reused 0 (delta 0)
Receiving objects: 100% (26/26), 17.37 KiB, done.
Resolving deltas: 100% (5/5), done.
Submodule path 'lib/module1': checked out '1c407cb2315z0847facb57d79d680f88ca004332'
ตอนนี้ถ้าเราเข้าไปดูใน lib/module1 เราจะพบว่ามีไฟล์อยู่อย่างถูกต้องแล้ว
การลบ Submodules
ขั้นตอนในการลบ Submodules จะมีความซับซ้อนเล็กน้อย ดังนี้
1. เข้าไปลบข้อมูล submodules ในไฟล์ .gitmodules ให้ลบข้อมูลออกไปดังนี้
[submodule "lib/module1"]
path = lib/module1
url = https://github.com/golfz/module1
2. เข้าไปลบข้อมูล submodule entry ในไฟล์ .git/config ขั้นตอนนี้ไม่จำเป็นต้องทำก็ได้ แต่เพื่อป้องกันปัญหาในอนาคตหากเราใช้คำสั่ง “git submodule init” ผมแนะนำว่าทำก็ดีครับ โดยให้ลบข้อมูลออกไปดังนี้
[submodule "lib/module1"]
url = https://github.com/golfz/module1
3. ลบ path ของ Submodules ด้วยคำสั่ง
$ git rm --cached lib/module1
rm 'lib/module1'
การอัพเดต Submodules
นี่เป็นอย่างหนึ่งที่เราจะค่อนข้างสับสนเมื่อใช้งาน Submodules เพราะเมื่อเราเพิ่ม submodules เข้ามา เราจะได้รับ commit ล่าสุดของ repository ของ submodule นั้น
หากหลังจากนั้น Repository ของ submodule มีการอัพเดตแล้วเรา clone โปรเจคหลักไปที่อื่น แล้วใช้คำสั่ง
$ git submodule init
ต่อด้วย
$ git submodule update
เราจะพบว่าเราจะไม่ได้โค้ดล่าสุดของ submodule ซึ่งมักสร้างความสับสนอยู่บ่อยครั้ง
แต่หากคิดดูดี ๆ ก็จะพบว่ากลไกนี้มีความเหมาะสมแล้ว เนื่องจาก code ใน repository หลักของเราได้ถูกทดสอบกับ submodules เวอร์ชั่นใด เมื่อ clone repository หลักไปใช้ก็ควรได้ submodule เวอร์ชั่นเดิมที่เคยทดสอบแล้ว ไม่ใช่เวอร์ชั่นใหม่ล่าสุดที่เราไม่เคยทดสอบ
แต่หากเราต้องการ repository ของ submodule ใหม่ล่าสุด สามารถทำได้ดังนี้
1. เข้าไปที่โฟลเดอร์ของ submodule
$ cd lib/module1
2. checkout ไปที่ master
$ git checkout master
Previous HEAD position was b8ff8f6... re-ordering
Switched to branch 'master'
Your branch is behind 'origin/master' by 8 commits, and can be fast-forwarded.
3. ดึงอัพเดตล่าสุดลงมา
$ git pull
remote: Counting objects: 31, done.
remote: Compressing objects: 100% (24/24), done.
remote: Total 24 (delta 15), reused 0 (delta 0)
Unpacking objects: 100% (24/24), done.
From https://github.com/golfz/module1
b8ff8f6..5cab93f master -> origin/master
* [new tag] 1.2.28 -> 1.2.28
From https://github.com/golfz/module1
* [new tag] 1.2.26 -> 1.2.26
* [new tag] 1.2.27 -> 1.2.27
Updating c547e0d..5cab93f
Fast-forward
index.php | 109 ++++++++++++++-
css/admin.css | 26 ++++
js/admin.js | 17 +++
3 files changed, 51 insertions(+), 4 deletions(-)
create mode 100644 css/admin.css
create mode 100644 js/admin.js
4. กลับไปที่ repository หลัก แล้ว
$ git add lib/module1
$ git status
# On branch master
# Changes to be committed:
# (use "git reset HEAD ..." to unstage)
#
# modified: lib/module1
#