Git Behind The Scene: Objects

We need to understand that git consists of four distinct but related object.

These objects are:

  • commit
  • tree
  • blob
  • tag

They are saved in .git/objects/ directory.

We refer them to as objects because they are being compressed -- using a library called zlib (when repo gets large, it uses something called as packfiles).

So if you try to open it directly using text editor or something, it won't work. You need to decompress it first.

Git is very reliable, it is unlikely for Git to delete an object, unless you do a reset --hard. If you did, it will delete the commits, trees, and blobs that you create for the commits you specified in the reset (it won't delete objects created on previous snapshots).

Hashing

Hashing is a function which converts an arbitrary input size to a unique fixed-length output. The idea is that it has to be deterministic, and every input has to have it's own unique output, so there can't be two inputs with the same output, we refer them to as collision.

As far as I know, the hashing function that is being used is SHA-1.

Every Git object is being hashed for identification.

Commit Object

A commit object has to be the most familiar among developers who have used Git previously.

It holds information about the author of the snapshot, when it was saved, a description of why it was saved, and most importantly: reference to the snapshot itself (tree).
Commit Object

To hash a commit object, you are required to provide the following information:

  • commit message
  • committer
  • commit date
  • author
  • author date
  • tree hash (snapshot)
  • parent tree hash

Those are the stuff that are going to be hashed.

What's the format?

commit {size}\0{content}  

Where,

  • {size}: the number of bytes in {content}

  • {content}:

tree {tree_sha}  
{parents}
author {author_name} <{author_email}> {author_date_seconds} {author_date_timezone}  
committer {committer_name} <{committer_email}> {committer_date_seconds} {committer_date_timezone}

{commit message}

So how does it look like? Well, it's just a plain string. Not all the string is printable since it contains hidden characters like NUL, line feed, etc.

tree d8329fc1cc938780ffdd9f94e0d364e0ea74f579  
author Scott Chacon <schacon@gmail.com> 1243040974 -0700  
committer Scott Chacon <schacon@gmail.com> 1243040974 -0700

first commit  

Tree Object

Format:

tree [content size]\0[Entries having references to other trees and blobs]  

Where,

  • [Entries having references to other trees and blobs]:
[mode] [file/folder name]\0[SHA-1 of referencing blob or tree]

What does it look like?

tree 192\0  
40000 octopus-admin\0 a84943494657751ce187be401d6bf59ef7a2583c  
40000 octopus-deployment\0 14f589a30cf4bd0ce2d7103aa7186abe0167427f  
40000 octopus-product\0 ec559319a263bc7b476e5f01dd2578f255d734fd  
100644 pom.xml\0 97e5b6b292d248869780d7b0c65834bfb645e32a  
40000 src\0 6e63db37acba41266493ba8fb68c76f83f1bc9dd  

Blob Object

Format:

blob [size of string] NUL [string]  

References

Tutorial Git: Push, Pull, dan Fetch

Salah satu hal paling sering ditemui ketika kita sedang menggunakan Git adalah fitur push, pull, dan fetch.

Seorang bisa saling berkolaborasi dan fokus pada satu hal spesifik tanpa perlu khawatir akan pekerjaan orang lain melalui fitur-fitur ini.

Kita menggunakan push biasanya untuk melakukan branch update ke remote repository. Untuk melakukan hal ini, kita perlu mengetahui remote repository yang hendak kita push. Untuk itu mari kita gunakan fitur berikut.

git remote

Anda bisa menggunakan git remote untuk menambahkan, mengubah, mengecek, atau menghapus remote repository.

Sebelum anda melakukan push, biasanya anda akan mengecek remote repository apa sajakah yang sudah terdaftar di repositori lokal anda:

git remote  

dan untuk mengecek remote repository secara lebih detail:

git remote -v  

Akan muncul nama remote repository anda, diikuti URL, dan pilihan antara fetch atau push.

Apabila ternyata remote repository yang hendak anda tuju belum terdaftar, maka silakan tambahkan terlebih dahulu:

git remote add <nama> <url>  

Pastikan letak remote  dan add  tidak tertukar.

Ketika anda melakukan git clone, Git akan secara otomatis menambahkan remote repository yang mengacu pada remote repository yang anda clone. Git akan menamainya origin.

git push

Nah, untuk melakukan push, anda cukup mengikuti langkah berikut:

git push <remote> <branch>  

remote: remote adalah nama remote repository yang hendak anda tuju.

branch: nama branch lokal yang hendak anda push.

Biasanya nama branch berpengaruh untuk menentukan apakah suatu branch akan ditambahkan di remote repository atau malah mengupdate branch yang sudah ada.

Anda hanya bisa melakukan push ke repositori yang anda miliki. Perihal push ke repositori milik orang lain, langkah yang bisa anda lakukan adalah:

  1.  fork repositori mereka (secara online).

  2. clone *repositori yang telah anda *fork.

  3. tambahkan remote repository yang mengacu ke repositori awal yang anda fork sebagai upstream.

Langkah tiga bukan merupakan suatu kewajiban.

Anda biasanya menambahkan upstream apabila anda ingin mengupdate local branch anda agar up-to-date dengan remote repository yang bersangkutan.

Selanjutnya anda tinggal melakukan push ke repositori yang telah anda fork dan secara manual melakukan pull request.

Pemilik repositori akan me-review perubahan-perubahan yang telah anda buat dan menentukan apakah perlu untuk dilakukan merging.

git pull dan git fetch

git fetch sebenarnya merupakan bagian dari git pull.

Ketika anda mengeksekusi perintah git pull, secara default Git akan melakukan fetching lalu merging.

git fetch akan menyimpan remote branch *sebagai *local branch anda. Semua remote branch yang anda fetch akan disimpan sebagai local remote branch di<root>/remotes//.

Setelah disimpan, Git akan meng-copy ke local branch anda.

Ketika <namaBranch> dinyatakan sebagai HEAD, artinya branch tersebut adalah default branch untuk *repository *yang bersangkutan.

Biasanya git fetch mengambil peran ketika anda hanya ingin mengintip pekerjaan kawan anda, atau ketika remote branch dan local branch melakukan banyak perubahan yang serupa sehingga merging akan menjadi kendala.

Tutorial Git: Repositori

Repositori adalah project folder anda, berisikan segala informasi, working directorybranch, dan hal-hal lainnya yang berhubungan dengan projek anda.

Sebuah repositori normalnya ditandai dengan adanya subdirectory .git di dalam project root-nya (repositori). Sebuah file/directory yang namanya diawali dengan tanda baca titik (.) menandakan direktori tersebut hidden.

Saya menggunakan terminal dan Bash di MacOS, sehingga tutorial Bash berikut mungkin tidak relevan bagi anda.

Untuk melihat apakah sebuah direktori memiliki file-file tersembunyi, anda bisa membuka terminal, lakukan perintah sehingga anda sekarang berada di direktori yang diinginkan (menggunakan cd ). Lalu, jalankan perintah berikut:

ls -a  

atau

ls -l  

menggunakan ls -a

Subdirectory .git tersebut berisi metadata terhadap repositori anda.

isi file git

Sebuah repositori dibagi menjadi dua tipe: repositori biasa dan repositori bare.

Bedanya, repositori bare tidak punya working directory sama sekali. Jadi isi dari repositori kurang lebih seperti file .git pada gambar di atas. Yang bisa kita lakukan terhadap repositori bare hanya kira-kira sebatas push dan pull.

Normalnya, ketika anda menciptakan sebuah repositori atau melakukan git clone, anda akan disuguhi sebuah working directory yang bisa anda tambahkan fileedit files, dll. Working directory anda akan sesuai dengan branch yang sedang di-checkout. Ketika anda mengubah branchworking directory anda akan secara otomatis berubah. Tapi di repositori yang bare, tidak ada working directory sama sekali.

Nah, pertanyaannya untuk apa memiliki repositori yang bare?

Biasanya bare repository dipergunakan sebagai central repository. Sebatas sharing pada rekan tim atau orang lain.

Setiap ada yang ingin melakukan perubahan, yang ia lakukan adalah sebatas melakukan push saja, tidak mengubah secara langsung.

git init

Untuk membuat sebuah repositori yang baru (lokal dan non-bare), buka terminal dan berikan perintah berikut:

git init  

Pastikan sebelumnya anda sudah berada di direktori yang diinginkan.

Anda juga bisa langsung menspesifikasi direktori yang dimaksud dalam terminal:

git init <direktori>  

Kalau anda menginginkan repositori yang bare:

git init --bare <direktori>  

Sekarang anda bisa menambahkan file, membuat file baru, atau mengubah file dalam working directory anda (khusus repositori bare).

Setiap file yang anda tambahkan akan tersimpan sebagai untracked files, dan akan selalu tampak di working directory walaupun anda sudah bergonta ganti branch.

Tiap perubahan pada file berstatus untracked tidak akan terbaca layaknya file-file lain yang sudah secara eksplisit ditambahkan. Untuk menambahkan file ke dalam branch tersendiri, anda harus melakukan commit pada file yang bersangkutan.

git clone

Cara lain untuk membuat sebuah repositori adalah dengan:

git clone

adalah alamat dimana repositori tersebut berada. Apabila anda menggunakan Github, maka anda tinggal mengcopy-paste alamat repositori bersangkutan di halaman repositori di Github.

Repositori akan diunduh menggunakan protokol HTTP/S atau SSH.

git config

Git config berguna untuk mensetting beberapa konfigurasi repositori kita, secara lokal (terikat pada satu repositori khusus) maupun global (menjadi default untuk semua repositori).

Beberapa konfigurasi yang bisa anda lakukan adalah:

git config --global user.name <name>

git config --global user.email <email>

git config --global alias.<alias-name> <git-command>  

Anda juga bisa melakukan perubahan secara langsung (tidak harus melalui command line interface):

git config --global --edit  

Tutorial Git: Dasar-Dasar dan Pengenalan

Git adalah salah satu version control system, semacam source code manager atau project management untuk kode-kode yang kita ciptakan.

Sebelum Git sudah hadir beberapa pionir lainnya, salah satunya adalah SVN (Subversion) oleh Apache. Akan tetapi pamor SVN tampaknya kalah dibandingkan dengan Git, oleh sebab itu Git menjadi *version control system *paling populer sekarang. Saya sendiri belum pernah mencoba SVN sehingga saya tidak dapat berpendapat lebih lanjut perihal teknologi tersebut.

Apa yang membuat version control system begitu spesial adalah kemampuannya untuk merevert kembali kode-kode kita sekarang ke versi terdahulunya. Ibaratnya kita melakukan undo. Jadi tidak perlu khawatir apabila setelah melakukan sekian banyak perubahan pada program anda, tiba-tiba program anda crash. Anda selalu dapat mengundo kode anda.

Bukan itu saja, version control system seperti Git memiliki fitur branch, dimana anda dan tim anda bisa mengerjakan beberapa fitur yang berbeda secara bersamaan. Anda juga bisa melakukan merging (menggabungkan) branch-branch anda, sehingga apa yang dikerjakan oleh tim anda bisa disatukan pada satu branch yang sama pada akhirnya.

Setiap version control system yang baik sejatinya memiliki log atau history terhadap segala perubahan (commit) yang anda ciptakan. Perubahan yang tercatat berupa:

  • Penjelasan terhadap perubahan yang terjadi
  • Tanggal
  • Siapa yang membuat perubahan tersebut

Dengan catatan macam itu, kita bisa mengetahui dengan jelas perubahan-perubahan yang telah terjadi, sehingga antar anggota tim tidak bingung dengan perubahan yang telah dibuat oleh anggota lainnya. History juga memungkinkan kita untuk melakukan tracing terhadap potensi bug.

Mungkin beberapa dari kalian rancu antara Git dengan Github.

Github adalah tempat meyimpan repositori kalian secara remote (online). Jadi semua repositori yang kalian ciptakan secara lokal (di komputer kalian), bisa kalian push (upload) ke Github sehingga segala bentuk perubahan tersimpan di cloud.

git_central-repo

Kenapa harus ditaruh di Github? Ya sebenarnya banyak website-website lainnya yang menawarkan service yang sama, seperti Gitlab. Akan tetapi, Github-lah yang terpopuler untuk penyimpanan repositori dan tempat berkolaborasi untuk para developers.

Dengan menyimpan repositori di cloud, anggota tim kita bisa mengunduh perubahan-perubahan yang telah terjadi ke komputer mereka. Hal ini menjadikan central repository kita berada di cloud, semua bentuk pengembangan pada akhirnya kita push ke central repository tersebut.