Halo, Habr! Saya sajikan kepada Anda terjemahan artikel "Git for Computer Scientists" oleh Tommi Virtanen.
GIT Inside Out: An Introduction
Dari diri saya sendiri: Saya secara berkala membaca artikel tentang bagaimana berbagai teknologi populer diatur di bawah tenda, saya menemukan materi ini . Artikel itu tampak menarik dengan adanya skema sederhana dan dapat dimengerti, yang dirasakan jauh lebih baik daripada lembaran teks yang membosankan. Saya memutuskan untuk menerjemahkan ke dalam bahasa Rusia. Gambar diambil dari aslinya.
Siapa yang akan tertarik dan mungkin bermanfaat: orang yang bekerja dengan Git setiap hari (mis., Setiap detik, jika bukan pengembang perangkat lunak pertama), dan yang ingin lebih memahami mekanisme kerjanya.
Catatan: untuk pemahaman yang lebih baik tentang artikel, seseorang harus memiliki gagasan tentang binatang buas seperti grafik asiklik terarah (DAG) .
Penyimpanan objek
Repositori objek Git, secara kasar, adalah DAG yang berisi berbagai jenis objek. Objek disimpan dalam bentuk terkompresi dan diidentifikasi oleh hash SHA-1 (ini BUKAN hash dari isi file yang mewakili objek, tetapi presentasinya di Git).
Gumpalan

Blob adalah objek sederhana, hanya kumpulan byte. Itu bisa berupa file, tautan simbolik, atau apa pun. Semantik ditentukan oleh objek yang menunjuk ke gumpalan ini.
Pohon

Objek dari tipe "tree" menggambarkan direktori (direktori). Mereka dapat menunjuk ke gumpalan yang menyimpan konten file, serta ke pohon lain, sehingga menciptakan struktur subdirektori.
Jika sebuah simpul menunjuk ke simpul lain di DAG, mereka mengatakan bahwa itu tergantung pada simpul itu, mis. tidak bisa ada tanpanya. Tidak ada satu poin pun yang dapat dihapus menggunakan pengumpulan sampah (perintah git gc ) atau dikembalikan menggunakan perintah git fsck --lost-found .
Berkomitmen

Komit mengacu pada pohon yang mewakili keadaan file di Git pada saat komit dibuat. Juga, komit dapat merujuk ke komit lain yang orang tuanya:
- Jika komit memiliki lebih dari 1 induk, ini berarti bahwa komit tersebut menggambarkan operasi gabungan (gabungan)
- Jika komit tidak memiliki orang tua, inilah yang disebut komit awal (awal) (mis. Yang pertama dalam repositori)
- Mungkin juga ada kasus ketika ada lebih dari 1 komit awal dalam repositori - ini biasanya berarti menggabungkan dua repositori terpisah
Tubuh objek komit adalah pesan komit .
Referensi (tautan)

Tautan (atau pos atau cabang) mirip dengan stiker dengan catatan yang disisipkan pada simpul DAG, semacam catatan, atau penanda - “Saya bekerja di sini”. Tidak seperti node DAG, yang tidak dapat diubah, dan hanya dapat ditambahkan, tautan dapat dipindahkan sesuka Anda. Mereka tidak disimpan dalam sejarah dan tidak ditransfer langsung di antara repositori.
Perintah git commit menambahkan node baru ke DAG dan memindahkan bookmark ke sana untuk cabang saat ini.
Tautan ada di namespace kepala / branchname , tetapi bagian dari kepala bisa dihilangkan.
Tautan HEAD berdiri terpisah - tidak menunjuk ke sebuah simpul, tetapi ke tautan lain - ini adalah penunjuk ke cabang aktif saat ini.
Referensi jarak jauh

Ini, secara umum, stiker dengan warna berbeda. Perbedaannya adalah bahwa tautan jarak jauh berada dalam ruang nama yang berbeda dan juga dikelola oleh server jarak jauh. Untuk memperbaruinya, gunakan perintah git fetch .
Tag

Tag adalah kombinasi dari simpul DAG dan stiker (warna lain). Tag menunjuk ke komit, dan termasuk pesan opsional dan tanda tangan GPG. Stiker (tautan) adalah cara sederhana untuk mengakses tag, dan jika hilang, ia dapat dipulihkan dengan perintah git fsck --lost-found .
Dengan demikian, repositori Git adalah kombinasi dari DAG dan tautan.
Ceritanya
Sekarang, mengetahui bagaimana Git menyimpan riwayat versi, mari kita coba menggambarkan berbagai operasi, serta memahami bagaimana Git berbeda dari sistem yang mewakili sejarah sebagai perubahan linear untuk setiap cabang.

Repositori paling sederhana. Kami baru saja menyalin ( git klon ) repositori jarak jauh dengan komit tunggal.

Di sini kita membaca ( git fetch ) repositori jarak jauh dan mendapat 1 komit baru, tetapi belum menggabungkannya dengan cabang kami.

Inilah yang terjadi setelah menjalankan perintah git merge remote / MYSERVER / master . Karena penggabungan dilakukan sebagai maju cepat (tidak ada komit lokal di cabang lokal kami), berikut ini terjadi: file copy pekerjaan kami berubah, dan penunjuk ke cabang juga dipindahkan.

Jalankan git commit secara lokal lalu git ambil . Sekarang kami memiliki komit lokal dan jarak jauh. Jelas, Anda perlu penggabungan .

Ini adalah hasil dari perintah git merge remote / MYSERVER / master . Karena kami memiliki komit lokal, ini bukan fast forward, dan komit terpisah dibuat untuk penggabungan DAG. Perhatikan - ia memiliki 2 komitmen orang tua.

Ini adalah bagaimana pohon kami akan menjaga beberapa commit, di kedua cabang (lokal dan jarak jauh) + bergabung. Anda dapat melihat dengan jelas bagaimana Git DAG menangkap seluruh riwayat tindakan kami.

Namun, kisah seperti itu sulit dibaca. Jika Anda belum menerbitkan cabang Anda, atau telah setuju dengan anggota tim lain bahwa mereka tidak boleh membangunnya dalam pekerjaan mereka, Anda memiliki alternatif: Anda dapat rebase cabang Anda. Dalam hal ini, komit Anda digantikan oleh komit lain, dengan induk yang berbeda, di mana tautan ke cabang juga bergerak.
Dalam hal ini, komit lama Anda akan tetap berada di DAG hingga pengumpulan sampah. Pada prinsipnya, ini adalah semacam asuransi, jika terjadi kesalahan. Jika Anda masih memiliki tautan ke komit lama, maka tautan tersebut akan disimpan selama tautan itu ada.
Anda TIDAK boleh rebase untuk cabang di atas yang orang lain buat komit. Anda dapat memulihkannya (dan bahkan tidak terlalu sulit), tetapi ini menambah kebingungan dan banyak pekerjaan yang tidak berguna.

Begini tampilannya setelah pengumpulan sampah (atau mengabaikan komitmen yang tidak dapat diakses), dan membuat komit baru di atas cabang tempat rebase diterapkan.

Juga, dengan rebase, Anda dapat memindahkan beberapa komit pada saat yang bersamaan.
Itu saja. Semoga materi ini bermanfaat.