Lewati ke konten utama

Penjelasan Git Subtree: Panduan Praktis dengan Contoh

Gunakan empat perintah penting (add, pull, push, split) untuk menjaga library bersama tetap sinkron di seluruh tim.
Diperbarui 28 Sep 2026  · 12 mnt Baca

Jelajahi bersama AI

ChatGPTClaudePerplexity

Anda sedang mengerjakan proyek analisis data dan perlu menyertakan library utilitas bersama yang dikelola tim Anda di repositori lain. Anda bisa saja menyalin-tempel kodenya, tetapi Anda akan kehilangan jalur pembaruan. Anda bisa menggunakan submodule Git, tetapi konon itu rumit. Ada opsi ketiga: git subtree.

git subtree memungkinkan Anda menyematkan satu repositori Git ke dalam repositori lain sebagai subdirektori, sekaligus mempertahankan riwayat lengkap dan jalur pembaruan yang mudah.

Panduan ini membahas kapan harus menggunakan git subtree, cara kerjanya, dan contoh praktis untuk alur kerja umum. Kita akan menggunakan skenario realistis yang mungkin Anda temui dalam proyek data science.

Apa itu git subtree?

Git subtree menyertakan repositori Git lain di bawah folder tertentu dalam proyek Anda sambil mempertahankan seluruh riwayat commit-nya. Berbeda dengan menyalin kode atau menggunakan symbolic link, subtree mempertahankan koneksi ke repositori asli sehingga Anda dapat menarik pembaruan dan mendorong perubahan kembali.

Berikut yang membuatnya berbeda dari sekadar menyalin kode:

Menyalin-tempel kode:

  • Tidak ada koneksi ke repo asli
  • Tidak ada jalur pembaruan saat library berubah
  • Tidak ada riwayat asal-usul kode

Git subtree:

  • Riwayat commit lengkap dari repo asli
  • Menarik pembaruan dengan satu perintah
  • Mendorong perubahan kembali ke repo asli jika diperlukan
  • Semuanya berada dalam satu checkout repositori

Perbedaan kunci dari submodule Git: konten subtree dikomit langsung ke repositori utama Anda. Saat seseorang mengkloning proyek Anda, mereka mendapatkan semuanya dalam satu checkout tanpa langkah penyiapan tambahan.

Semua ini bermuara pada onboarding yang lebih sederhana dan lebih sedikit masalah “berfungsi di mesin saya”.

Cara Kerja git subtree

Saat Anda menambahkan subtree, Git melakukan sesuatu yang cerdas: ia menggabungkan riwayat repositori lain ke dalam subdirektori proyek Anda. Berikut yang terjadi:

  1. Git mengambil riwayat repositori remote
  2. Git menulis ulang commit-commit tersebut sehingga muncul di bawah subdirektori pilihan Anda
  3. Git menggabungkan riwayat yang telah ditulis ulang ini ke cabang Anda saat ini
  4. Pembaruan mendatang mengikuti pola yang sama: fetch, rewrite, merge

Repositori Anda berisi file nyata dan riwayat commit penuh dari subtree, bukan hanya penunjuk atau referensi. Saat seseorang mengkloning proyek Anda atau checkout cabang, mereka langsung memiliki semua kode. Tidak ada langkah terpisah “initialize submodules”.

Konsekuensinya: repositori Anda membesar karena berisi kode Anda dan kode subtree beserta riwayat lengkapnya. Apakah sepadan? Tergantung situasi Anda, tetapi bagi sebagian besar tim data science, saya rasa demikian.

Cara Menggunakan git subtree (Perintah Umum)

Sekarang setelah Anda memahami apa yang dilakukan subtree, mari kita bahas operasi yang paling umum. Kita akan menggunakan skenario realistis saat Anda membangun proyek analisis data dan perlu menyertakan library utilitas bersama.

Contoh penyiapan:

  • Proyek utama: data-pipeline

  • Library bersama: shared-utils (berada di https://github.com/yourteam/shared-utils.git)

  • Anda ingin menyertakannya di bawah libs/shared-utils/ dalam proyek Anda

git subtree add

Perintah add menyertakan repositori lain ke dalam proyek Anda untuk pertama kalinya.

Sintaks dasar, sebagai referensi, seperti ini:

git subtree add --prefix=<directory> <remote-url> <branch> --squash

Contoh nyata:

# Tambahkan repo shared-utils di bawah libs/shared-utils
git subtree add --prefix=libs/shared-utils \
  https://github.com/yourteam/shared-utils.git \
  main \
  --squash

Apa yang dilakukan perintah ini:

  • Membuat direktori libs/shared-utils
  • Menyalin semua file dari shared-utils ke dalamnya
  • Mengkomit semuanya ke repositori Anda
  • Mencatat koneksi untuk pembaruan di masa mendatang

Memahami flag:

  • --prefix=libs/shared-utils: Lokasi subtree dalam proyek Anda. Anda harus menggunakan prefix yang persis sama untuk semua operasi selanjutnya. Mengubahnya sekali saja dan Anda akan mencari-cari di Stack Overflow jam 2 pagi mencoba memahami mengapa semuanya rusak.

  • --squash: Menggabungkan seluruh riwayat commit subtree menjadi satu commit di proyek Anda. Ini membuat riwayat proyek Anda lebih rapi. Tanpa --squash, Anda akan melihat setiap commit dari repo asli di riwayat proyek Anda, yang bisa berlebihan.

Kapan men-squash: Gunakan --squash kecuali Anda perlu mempertahankan atribusi commit terperinci dari repo asli. Untuk sebagian besar proyek data dengan utilitas bersama, riwayat yang di-squash lebih rapi dan mudah digunakan. Saya selalu menggunakannya.

Setelah menjalankan ini, Anda akan melihat commit baru di proyek Anda dengan pesan seperti "Add 'libs/shared-utils/' from commit 'abc123'". Direktori libs/shared-utils kini berisi semua file, dan Anda bisa langsung menggunakannya.

git subtree pull

Perintah pull memperbarui subtree Anda dengan perubahan dari repositori asli. Jika tim library bersama memperbaiki bug atau menambahkan fitur, ini cara Anda mendapatkan pembaruan tersebut.

Sintaks dasar:

git subtree pull --prefix=<directory> <remote-url> <branch> --squash

Contoh nyata:

# Tarik perubahan terbaru dari shared-utils
git subtree pull --prefix=libs/shared-utils \
  https://github.com/yourteam/shared-utils.git \
  main \
  --squash

Apa yang dilakukan perintah ini:

  • Mengambil commit baru dari repositori remote
  • Menggabungkannya ke dalam direktori libs/shared-utils Anda
  • Membuat merge commit di proyek Anda

Prefix harus persis sama. Jika Anda menggunakan libs/shared-utils saat add, Anda harus menggunakan libs/shared-utils untuk pull. Menggunakan prefix berbeda tidak akan berhasil. Percayalah.

Konsistensi squash: Jika Anda menggunakan --squash saat add, Anda harus menggunakan --squash untuk setiap pull. Mencampur pembaruan yang di-squash dan tidak di-squash menciptakan riwayat yang membingungkan. Saya belajar ini dengan cara yang sulit.

Menangani konflik: Jika Anda telah memodifikasi file di libs/shared-utils dan file yang sama juga berubah di hulu, Anda akan mendapatkan konflik merge. Selesaikan seperti Anda menyelesaikan konflik merge Git apa pun—edit file, stage, dan selesaikan merge.

Dokumentasikan di README tim apakah Anda menggunakan --squash atau tidak, agar semua orang tetap konsisten.

git subtree push

Perintah push mengirim perubahan yang Anda buat di folder subtree kembali ke repositori asli.

Sintaks dasar:

git subtree push --prefix=<directory> <remote-url> <branch>

Contoh nyata:

# Dorong perubahan dari libs/shared-utils kembali ke repo asli
git subtree push --prefix=libs/shared-utils \
  https://github.com/yourteam/shared-utils.git \
  main

Apa yang dilakukan perintah ini:

  • Mengekstrak hanya commit yang memengaruhi libs/shared-utils
  • Menulis ulang seakan-akan dibuat di root shared-utils
  • Mendorong commit tersebut ke repositori asli

Kapan digunakan: Anda memelihara library bersama di dalam repositori aplikasi dan ingin menyumbangkan perbaikan kembali. Misalnya Anda menambahkan fungsi validasi data yang berguna ke shared-utils saat mengerjakan proyek data-pipeline, dan proyek lain harus bisa memanfaatkannya.

Anggap push sebagai kebalikan dari pull. Pull membawa perubahan masuk; push mengirimkan perubahan keluar. Git mengekstrak hanya riwayat yang relevan dan menerjemahkannya kembali ke struktur repositori asli. Cukup cerdas.

Anda memerlukan akses tulis ke repositori asli. Jika tidak punya izin, Anda perlu melakukan fork repo, push ke fork Anda, dan membuat pull request.

git subtree split

Perintah split mengekstrak riwayat subdirektori ke cabang tersendiri.

Sintaks dasar:

git subtree split --prefix=<directory> -b <new-branch-name>

Berikut contoh nyata:

# Ekstrak libs/shared-utils ke cabangnya sendiri
git subtree split --prefix=libs/shared-utils -b shared-utils-extracted

Apa yang dilakukan perintah ini:

  • Membuat cabang baru yang hanya berisi commit yang memengaruhi libs/shared-utils
  • Cabang ini terlihat seperti repositori mandiri hanya untuk direktori tersebut
  • Cabang asli tetap tidak berubah

Kasus penggunaan umum:

Memisahkan library dari monorepo: Pipeline pemrosesan data Anda telah membesar, dan Anda ingin mengekstrak komponen yang dapat digunakan ulang sebagai library mandiri. Split membuat cabang hanya dengan riwayat komponen tersebut, yang kemudian dapat Anda push ke repositori baru.

Menerbitkan subdirektori sebagai proyek tersendiri: Anda membangun modul visualisasi data yang berguna di dalam proyek analisis dan ingin membagikannya sebagai paket mandiri. Split mengekstraknya dengan riwayat penuh yang tetap utuh.

Contoh alur kerja membuat repo mandiri baru:

# Ekstrak subdirektori
git subtree split --prefix=libs/shared-utils -b shared-utils-standalone

# Buat repo baru dan push ke sana
git remote add shared-utils-origin https://github.com/yourteam/shared-utils-new.git
git push shared-utils-origin shared-utils-standalone:main

Sekarang shared-utils-new adalah repositori lengkap dengan riwayat penuh hanya untuk subdirektori tersebut.

git subtree vs. submodule

Inilah yang sering ditanyakan orang: subtree versus submodule.

Keduanya memungkinkan Anda menyertakan kode eksternal di repositori, tetapi ada perbedaan. Jika Anda perlu penjepitan versi yang presisi, atau jika ukuran repo terbatas, gunakan submodule. Jika tim Anda memiliki tingkat kemampuan Git yang beragam dan Anda menginginkan kesederhanaan, gunakan subtree. Selain itu, keduanya bisa bekerja.

Aspek

git subtree

git submodule

Kompleksitas penyiapan

Sedang (perintah langsung)

Tinggi (memerlukan langkah init terpisah)

Pengalaman clone

Sederhana (satu clone, semuanya berfungsi)

Kompleks (clone + git submodule update --init)

Ukuran repositori

Lebih besar (mencakup konten subtree penuh + riwayat)

Lebih kecil (hanya penunjuk ke repo lain)

Onboarding developer

Mudah (semuanya berfungsi setelah clone)

Lebih sulit (harus memahami alur kerja submodule)

Kompleksitas CI/CD

Sederhana (clone dan langsung jalan)

Lebih kompleks (harus menginisialisasi submodule)

Penjepitan versi

Kurang presisi (menggabungkan commit terbaru atau tertentu)

Presisi (hash commit persis)

Alur pembaruan

git subtree pull (menggabungkan perubahan)

cd submodule && git pull (manual)

Risiko "berfungsi di mesin saya"

Lebih rendah (semuanya dikomit)

Lebih tinggi (keadaan submodule bisa menyimpang)

Mendorong perubahan kembali

git subtree push

git push normal di dalam submodule

Pemisahan tanggung jawab

Campur (kode berada di repo utama)

Jelas (submodule adalah repo terpisah)

Gunakan git submodule ketika Anda memerlukan:

  • Penjepitan versi ketat (harus menggunakan commit X tepat dari library Y)
  • Pemisahan yang jelas antar proyek (benar-benar independen)
  • Beberapa proyek berbagi dependensi yang sama pada versi berbeda
  • Ukuran repositori utama yang kecil penting bagi alur kerja Anda

Gunakan git subtree ketika Anda menginginkan:

  • Tanpa langkah inisialisasi tambahan
  • Anggota tim baru meng-clone sekali lalu menjalankan pengujian
  • Lebih sedikit konsep Git yang perlu dipelajari tim Anda
  • Vendoring dependensi yang sesekali ditarik pembaruannya

Tidak ada yang selalu lebih baik. Pilihan bergantung pada apakah Anda lebih menghargai kesederhanaan dibanding kontrol versi yang ketat. Menurut saya: Untuk tim data science di mana sebagian besar orang fokus pada analisis alih-alih seluk-beluk Git, subtree sering mengurangi friksi. Untuk tim platform yang mengelola layanan dengan persyaratan dependensi, submodule masuk akal.

Kapan Tidak Menggunakan git subtree

Jangan gunakan git subtree saat ukuran repositori merupakan batas keras. Subtree membengkakkan ukuran repo karena mencakup konten dan riwayat penuh. Jika Anda mendekati batas platform Git atau jika kecepatan jaringan sangat penting, submodule lebih ringan.

Juga, jangan gunakan git subtree jika Anda memerlukan penjepitan versi ketat. Anda harus menggunakan tepat versi 2.3.1 dari library dan tidak ada yang lain. Submodule menjepit ke commit persis; subtree menggabungkan rentang commit.

Jangan gunakan git subtree jika repo eksternal sering berubah. Subtree diperbarui setiap hari dengan perubahan signifikan. Terus-menerus menarik pembaruan menciptakan riwayat merge yang berantakan. Pertimbangkan apakah Anda benar-benar perlu menyematkannya atau apakah pengelola paket akan lebih rapi.

Terakhir, jangan gunakan git subtree jika pemisahan organisasi diperlukan. Konten subtree memiliki kontrol akses, lisensi, atau kepemilikan yang berbeda. Menjaganya di repositori terpisah membuat batasan lebih jelas.

Keuntungan git subtree

Pengalaman clone satu repositori: Jalankan git clone, dan selesai. Semua yang Anda butuhkan ada. Ini mengurangi friksi onboarding bagi tim di mana tidak semua orang ahli Git.

Lebih sedikit komponen bergerak dibanding submodule: Tidak ada langkah inisialisasi terpisah. Tidak ada keadaan HEAD terlepas yang perlu dijelaskan. Tidak ada kebingungan “submodule Anda tidak sinkron”. Alur kerja lebih dekat ke operasi Git standar (add, pull, push).

Kesederhanaan CI/CD: Skrip continuous integration Anda lebih sederhana. Dengan subtree, Anda clone dan jalankan pengujian. Dengan submodule, Anda clone, inisialisasi secara rekursif, lalu jalankan pengujian. Langkah ekstra itu membuat build gagal saat terlupa.

Bekerja baik untuk tim dengan kenyamanan Git yang beragam: Praktisi data junior tidak perlu memahami mekanisme submodule. Mereka menggunakan perintah Git yang familiar dan semuanya berfungsi.

Bagus untuk vendoring dengan pembaruan sesekali: Anda menyertakan versi 1.2 dari sebuah library. Enam bulan kemudian, versi 1.3 punya perbaikan bug yang Anda inginkan. Tarik dengan satu perintah. Anda tidak terjebak dengan kode salinan yang tak terpelihara, namun juga tidak terus-menerus melacak perubahan hulu.

Keterbatasan dan Kompromi git subtree

Repositori tumbuh signifikan: Repo Anda berisi kode Anda dan kode subtree beserta riwayat commit penuh (kecuali Anda menggunakan --squash, yang membantu). Subtree 50MB menambah sekitar 50MB ke ukuran repo Anda.

Untuk subtree besar atau banyak subtree, ini bertambah. Pertimbangkan apakah kemudahan ini sepadan dengan ruang disk dan waktu clone.

  • Kompleksitas grafik riwayat: Bahkan dengan --squash, merge commit untuk pembaruan subtree menambah kompleksitas pada riwayat Git Anda. Jika Anda sering menarik pembaruan subtree, grafik commit Anda menjadi berantakan.

  • Kebingungan perbedaan dengan upstream: Jika Anda memodifikasi file subtree dan upstream juga mengubahnya, konflik merge terjadi. Menyelesaikan konflik di subtree bisa membingungkan karena Anda menggabungkan repo orang lain ke subdirektori milik Anda.

  • Alur push punya jebakan: git subtree push perlu menulis ulang riwayat, yang bisa lambat untuk subtree besar. Jika Anda membuat banyak commit di folder subtree, push bisa memakan waktu. Bersabarlah.

  • Konflik merge tetap terjadi: Jika Anda dan upstream sama-sama memodifikasi file yang sama, Anda harus menyelesaikan konflik. Ini bukan khusus subtree, dan subtree tidak secara ajaib mencegah konflik Git.

  • Diperlukan disiplin: Menggunakan nilai --prefix berbeda atau flag --squash yang tidak konsisten menimbulkan masalah. Tim perlu mendokumentasikan dan mengikuti alur kerja yang sama.

Keterbatasan ini bukan penghalang, tetapi patut diketahui sejak awal. Komprominya: alur kerja lebih sederhana dengan imbalan ukuran repo lebih besar dan potensi kompleksitas riwayat.

Kesalahan Umum Saat Menggunakan git subtree

Saat mulai menggunakan git subtree, waspadai masalah umum berikut. Ini mudah dihindari setelah Anda mengetahuinya.

Penggunaan --squash yang tidak konsisten

Anda menggunakan --squash saat menambahkan subtree tetapi lupa saat git subtree pull. Sekarang riwayat Anda memiliki commit subtree yang di-squash dan tidak di-squash, membuatnya membingungkan.

Solusinya adalah mendokumentasikan di README proyek. Tulis catatan seperti, "Selalu gunakan --squash untuk subtree shared-utils."

Prefix salah atau berubah-ubah

Anda menambahkan subtree dengan --prefix=libs/shared-utils tetapi kemudian mencoba pull dengan --prefix=libs/utils. Ini tidak berfungsi karena Git tidak dapat menemukan subtree.

Solusinya adalah menggunakan prefix yang persis sama setiap saat. Pertimbangkan untuk mendokumentasikannya dalam skrip, seperti ini:

# scripts/update-subtree.sh
#!/bin/bash
git subtree pull --prefix=libs/shared-utils \
  https://github.com/yourteam/shared-utils.git \
  main \
  --squash

Mengharapkan subtree berperilaku seperti submodule

Anda mengira bisa cd libs/shared-utils && git checkout untuk mengganti versi. Itu tidak berfungsi karena konten subtree hanyalah file di repo Anda, bukan repositori Git terpisah.

Solusinya adalah memahami bahwa subtree menggabungkan commit tertentu. Untuk “menurunkan versi” subtree, Anda perlu menemukan dan menggabungkan commit yang lebih lama atau membalikkan commit pembaruan subtree.

Tidak mendokumentasikan alur kerja

Anggota tim tidak tahu apakah harus menggunakan --squash, URL remote apa yang digunakan, atau kapan harus mendorong perubahan kembali. Jika atau ketika semua orang melakukannya berbeda, itu akan menciptakan riwayat yang tidak konsisten.

Solusinya adalah menambahkan bagian ke README Anda:

## Memperbarui shared-utils

## Untuk menarik perubahan terbaru:
git subtree pull --prefix=libs/shared-utils https://github.com/yourteam/shared-utils.git main --squash

## Untuk mendorong perubahan kembali:
git subtree push --prefix=libs/shared-utils https://github.com/yourteam/shared-utils.git main

Terakhir, memodifikasi file subtree tanpa perencanaan

Anda mengedit file di libs/shared-utils untuk proyek spesifik Anda, tetapi tidak pernah mendorong kembali. Enam bulan kemudian, Anda menarik pembaruan dan terjadi konflik karena perubahan Anda dan perubahan upstream bertabrakan.

Solusinya: Jika Anda memodifikasi file subtree, dorong perubahan kembali ke shared-utils jika bermanfaat untuk semua orang, atau terima bahwa Anda perlu menangani konflik saat pembaruan.

Kesimpulan

Git subtree menukar ukuran repositori dan kompleksitas riwayat dengan kesederhanaan alur kerja. Untuk tim data science di mana sebagian besar orang fokus pada analisis alih-alih seluk-beluk Git, subtree mengurangi friksi. Anggota tim baru meng-clone repo dan langsung mulai bekerja.

Untuk mempelajari lebih lanjut tentang alur kerja Git, jelajahi Introduction to Git kami.


Oluseye Jeremiah's photo
Author
Oluseye Jeremiah
LinkedIn

Penulis teknis yang mengkhususkan diri pada AI, ML, dan ilmu data, membuat gagasan kompleks menjadi jelas dan mudah diakses.

Topik
Git

Belajar Git bersama DataCamp

Kursus

Pengantar Git

2 jam
100.4K
Pelajari dasar-dasar Git untuk version control dalam proyek perangkat lunak dan data Anda.
Lihat DetailRight Arrow
Mulai Kursus
Lihat SelengkapnyaRight Arrow
Terkait

blogs

Spaghetti Plot dan Jalur Badai

Temukan alasan mengapa Anda sebaiknya (tidak) menggunakan spaghetti plot untuk menyampaikan ketidakpastian jalur prediksi badai serta dampaknya terhadap interpretasi.
Hugo Bowne-Anderson's photo

Hugo Bowne-Anderson

13 mnt

blogs

Tutorial Korelasi di R

Dapatkan pengenalan dasar-dasar korelasi di R: pelajari lebih lanjut tentang koefisien korelasi, matriks korelasi, plotting korelasi, dan sebagainya.
David Woods's photo

David Woods

13 mnt

blogs

12 Alternatif ChatGPT Terbaik yang Bisa Anda Coba pada 2026

Artikel ini menyajikan daftar alternatif ChatGPT yang akan meningkatkan produktivitas Anda.
Javier Canales Luna's photo

Javier Canales Luna

14 mnt

blogs

40 Pertanyaan Wawancara DBMS Teratas di 2026

Kuasai pertanyaan wawancara basis data, dari konsep SQL dasar hingga skenario desain sistem tingkat lanjut. Panduan mendalam ini mencakup semua yang Anda perlukan untuk sukses di wawancara DBMS dan meraih peran berikutnya.
Dario Radečić's photo

Dario Radečić

15 mnt

Lihat SelengkapnyaLihat Selengkapnya