Saya baru mengenal kontrol versi dan saya memahami bahwa "melakukan" pada dasarnya adalah membuat cadangan sambil memperbarui versi 'terkini' dari apa yang Anda kerjakan.
Apa yang saya tidak mengerti adalah apa pementasan adalah dari perspektif praktis. Apakah pementasan adalah sesuatu yang hanya ada dalam nama atau apakah itu memiliki tujuan? Ketika Anda berkomitmen, bagaimanapun juga itu akan melakukan segalanya, bukan?
Sunting: Saya pikir saya mungkin membingungkan terminologi. Apakah file 'bertahap' sama dengan file 'terlacak'?
Jawaban:
Ketika Anda mengkomit itu hanya akan mengkomit perubahan dalam indeks (file "bertahap"). Ada banyak kegunaan untuk ini, tetapi yang paling jelas adalah memecah perubahan kerja Anda menjadi bagian-bagian yang lebih kecil dan mandiri. Mungkin Anda memperbaiki bug saat Anda menerapkan fitur. Anda dapat
git add
hanya file itu (ataugit add -p
menambahkan hanya sebagian dari file!) Dan kemudian melakukan perbaikan bug itu sebelum melakukan yang lainnya. Jika Anda menggunakangit commit -a
maka Anda hanya memaksakanadd
segalanya tepat sebelum komit. Jangan gunakan-a
jika Anda ingin memanfaatkan file pementasan.Anda juga dapat memperlakukan file bertahap sebagai copy pekerjaan perantara dengan
--cached
ke banyak perintah. Misalnya,git diff --cached
akan menunjukkan kepada Anda bagaimana perbedaan panggungHEAD
sehingga Anda dapat melihat apa yang akan Anda lakukan tanpa mencampurkan perubahan kerja lainnya.sumber
git reset --hard
.git diff --staged
dan periksa file mana yang Anda ubah dan di mana dan mulailah membuat perubahan lain.sumber
Salah satu tujuan praktis pementasan adalah pemisahan logis dari file commit.
Karena pementasan memungkinkan Anda untuk terus mengedit file / direktori kerja, dan melakukan beberapa bagian saat Anda merasa semuanya sudah siap, Anda dapat menggunakan tahapan terpisah untuk pengeditan yang tidak terkait secara logis.
Misalkan Anda memiliki 4 file
fileA.html
,fileB.html
,fileC.html
danfileD.html
. Anda membuat perubahan ke semua 4 file dan siap untuk mengkomit tetapi perubahanfileA.html
danfileB.html
secara logis terkait (misalnya, implementasi fitur baru yang sama di kedua file) sementara perubahan difileC.html
danfileD.html
terpisah dan secara logis tidak terkait dengan file sebelumnya. Anda dapat file tahap pertamafileA.html
danfileB.html
dan komit mereka.Kemudian di langkah berikutnya Anda tahap dan melakukan perubahan ke dua file yang tersisa.
sumber
git commit -m "Implemented new feature XYZ" fileA.html fileB.html
akan bekerja dengan baik tanpa perlu perintah git add. Saya berasal dari dunia subversi di mana pementasan bukanlah sebuah konsep, jadi, saya tidak yakin tentang kegunaan pementasan gitLebih mudah untuk memahami penggunaan perintah git
add
dancommit
jika Anda membayangkan file log disimpan di repositori Anda di Github. File log proyek khas untuk saya mungkin terlihat seperti:Saya biasanya memulai hari saya dengan
git pull
permintaan dan mengakhirinya dengangit push
permintaan. Jadi semua yang ada di dalam catatan hari sesuai dengan apa yang terjadi di antara mereka. Selama setiap hari, ada satu atau lebih tugas logis yang saya selesaikan yang memerlukan perubahan beberapa file. File yang diedit selama tugas itu terdaftar dalam indeks.Masing-masing sub tugas ini (Tugas A dan Tugas B di sini) adalah komitmen individu. The
git add
perintah menambahkan file ke daftar 'Index File Berubah'. Proses ini disebut juga pementasan. Thegit commit
catatan perintah / memfinalisasi perubahan dan daftar indeks yang sesuai bersama dengan pesan khusus.Ingatlah bahwa Anda masih hanya mengubah salinan lokal dari repositori Anda dan bukan yang ada di Github. Setelah ini, hanya ketika Anda melakukan 'git push' lakukan semua perubahan yang tercatat ini, bersama dengan file indeks Anda untuk setiap komit, masuk ke repositori utama (di Github).
Sebagai contoh, untuk mendapatkan entri kedua di file log imajiner itu, saya akan melakukan:
Singkatnya,
git add
dangit commit
memungkinkan Anda memecah perubahan ke repositori utama menjadi sub-perubahan logis sistematis. Seperti yang ditunjukkan oleh jawaban dan komentar lain, tentu saja ada lebih banyak kegunaan darinya. Namun, ini adalah salah satu penggunaan yang paling umum dan prinsip pendorong di balik Git sebagai sistem kontrol revisi multi-tahap tidak seperti yang populer lainnya seperti Svn.sumber
Untuk memperluas jawaban Ben Jackson , yang bagus, mari kita lihat pertanyaan aslinya dengan saksama. (Lihat jawabannya untuk pertanyaan tipe mengapa repot ; ini lebih tentang apa yang sedang terjadi .)
Ini tidak cukup benar. Cadangan dan dan kontrol versi tentu saja terkait — seberapa kuatnya bergantung pada beberapa hal yang sampai batas tertentu merupakan masalah opini — tetapi tentu ada beberapa perbedaan, jika hanya dalam maksud: Cadangan biasanya dirancang untuk pemulihan bencana (mesin gagal, api menghancurkan seluruh gedung termasuk semua media penyimpanan, dll.). Kontrol versi biasanya dirancang untuk interaksi yang lebih mendetail dan menawarkan fitur yang tidak dapat dilakukan backup. Cadangan biasanya disimpan untuk beberapa waktu, kemudian dibuang sebagai "terlalu lama": yang terpenting adalah cadangan yang lebih baru. Kontrol versi biasanya menyimpan setiap versi yang dikomit selamanya.
Iya dan tidak. Desain Git di sini agak aneh. Ada sistem kontrol versi yang tidak memerlukan langkah penahapan terpisah. Misalnya, Mercurial, yang sangat mirip dengan Git dalam hal penggunaan, tidak memerlukan
hg add
langkah terpisah , di luar langkah pertama yang memperkenalkan file baru. Dengan Mercurial, Anda menggunakanhg
perintah yang memilih beberapa komit, lalu Anda melakukan pekerjaan Anda, lalu Anda menjalankanhg commit
, dan selesai. Dengan Git, Anda menggunakangit checkout
, 1 lalu Anda melakukan pekerjaan Anda, lalu Anda jalankangit add
, dan kemudiangit commit
. Mengapa perlugit add
langkah ekstra ?Rahasianya di sini adalah apa yang disebut Git, dengan berbagai cara, indeks , atau area pementasan , atau kadang-kadang — jarang sekali saat ini — cache . Ini semua adalah nama untuk hal yang sama.
Tidak, tapi ini saling terkait. Sebuah dilacak file yang ada dalam indeks Git ini. Untuk memahami indeks dengan benar, sebaiknya mulai dengan memahami komit.
Sejak Git versi 2.23, Anda dapat menggunakan
git switch
bukangit checkout
. Untuk kasus khusus ini, kedua perintah ini melakukan hal yang persis sama. Perintah baru ada karenagit checkout
terlalu banyak diisi; mereka dibagi menjadi dua perintah terpisah,git switch
dangit restore
, untuk membuatnya lebih mudah dan lebih aman menggunakan Git.Komit
Di Git, komit menyimpan cuplikan lengkap dari setiap file yang diketahui Git. (File mana yang diketahui Git? Kita akan melihatnya di bagian selanjutnya.) Snapshot ini disimpan dalam bentuk khusus, read-only, Git-only, terkompresi dan de-duplikasi, yang secara umum hanya Git sendiri yang dapat membaca . (Ada lebih banyak hal di setiap komit daripada hanya snapshot ini, tetapi hanya itu yang akan kita bahas di sini.)
De-duplikasi membantu dengan ruang: kami biasanya hanya mengubah beberapa file, lalu membuat komit baru. Jadi sebagian besar file dalam komit sebagian besar sama dengan file di komit sebelumnya. Dengan menggunakan kembali file tersebut secara langsung, Git menghemat banyak ruang: jika kita hanya menyentuh satu file, komit baru hanya membutuhkan ruang untuk satu salinan baru. Bahkan kemudian dikompresi — terkadang sangat terkompresi, meskipun ini benar-benar terjadi kemudian — sehingga
.git
direktori sebenarnya bisa lebih kecil dari file yang ada di dalamnya, setelah diperluas ke file normal sehari-hari. De-duplikasi aman karena file yang dikomit akan dibekukan sepanjang waktu. Tidak ada yang bisa mengubahnya, jadi aman untuk komitmen bergantung pada salinan satu sama lain.Karena file yang disimpan dalam format khusus Git yang dibekukan untuk sepanjang masa ini, Git harus mengembangkan setiap file menjadi salinan biasa sehari-hari. Salinan biasa ini bukanlah salinan Git : ini adalah salinan Anda , lakukan sesuka Anda. Git hanya akan menuliskannya ketika Anda menyuruhnya, sehingga Anda memiliki salinan untuk dikerjakan. Salinan yang dapat digunakan ini ada di pohon kerja atau pohon kerja Anda .
Artinya adalah ketika Anda memeriksa beberapa komit tertentu, otomatis ada dua salinan dari setiap file:
Git memiliki salinan Git-ified yang dibekukan untuk semua waktu dalam komit saat ini . Anda tidak dapat mengubah salinan ini (meskipun Anda tentu saja dapat memilih komit yang berbeda, atau membuat komit baru).
Anda memiliki, di pohon kerja Anda, salinan format normal. Anda dapat melakukan apa pun yang Anda inginkan, menggunakan perintah apa pun di komputer Anda.
Sistem kontrol versi lain (termasuk Mercurial seperti yang disebutkan di atas) berhenti di sini, dengan dua salinan ini. Anda cukup mengubah salinan pohon kerja Anda, lalu komit. Git ... tidak.
Indeks
Di antara dua salinan ini, Git menyimpan salinan ketiga 2 dari setiap file. Salinan ketiga ini dalam format beku , tetapi tidak seperti salinan beku dalam komit, Anda dapat mengubahnya. Untuk mengubahnya, Anda menggunakan
git add
.The
git add
berarti perintah membuat salinan indeks file sesuai dengan copy pekerjaan-pohon . Artinya, Anda memberi tahu Git: Ganti salinan beku-format, de-duplikat yang ada di indeks sekarang, dengan mengompresi salinan work-tree saya yang telah diperbarui, menghapus duplikatnya, dan menyiapkannya untuk dibekukan menjadi komit baru. Jika Anda tidak menggunakangit add
, indeks masih menyimpan salinan format beku dari komit saat ini.Ketika Anda menjalankan
git commit
, Git paket up apa yang ada di indeks saat itu untuk digunakan sebagai snapshot baru. Karena sudah dalam format beku, dan sudah diduplikasi sebelumnya, Git tidak perlu melakukan banyak pekerjaan ekstra.Ini juga menjelaskan tentang file yang tidak terlacak . File yang tidak terlacak adalah file yang ada di pohon kerja Anda tetapi tidak ada dalam indeks Git sekarang . Tidak peduli bagaimana file itu berakhir dalam keadaan ini. Mungkin Anda menyalinnya dari tempat lain di komputer Anda, ke pohon kerja Anda. Mungkin Anda membuatnya segar di sini. Mungkin ada adalah salinan dalam indeks Git, tapi Anda dihapus copy bahwa dengan
git rm --cached
. Dengan satu atau lain cara, ada salinannya di sini di pohon kerja Anda, tetapi tidak ada salinannya di indeks Git. Jika Anda membuat komit baru sekarang, file itu tidak akan ada di komit baru.Perhatikan bahwa
git checkout
awalnya mengisi indeks Git dari komit yang Anda periksa. Jadi indeks mulai cocok dengan komit. Git juga mengisi pohon kerja Anda dari sumber yang sama ini. Jadi, awalnya, ketiganya cocok. Ketika Anda mengubah file di pohon kerja Anda dangit add
mereka, sekarang indeks dan pohon kerja Anda cocok. Kemudian Anda menjalankangit commit
dan Git membuat komit baru dari indeks, dan sekarang ketiganya cocok lagi.Karena Git membuat komit baru dari indeks, kita dapat menjelaskannya sebagai berikut : Indeks Git memegang komit berikutnya yang Anda rencanakan. Ini mengabaikan peran yang diperluas yang diambil oleh indeks Git selama penggabungan yang berkonflik, tetapi kami ingin mengabaikannya untuk saat ini. :-)
Hanya itu saja — tetapi masih cukup rumit! Ini sangat rumit karena tidak ada cara mudah untuk melihat dengan tepat apa yang ada di indeks Git. 3 Tapi ada adalah perintah Git yang memberitahu Anda apa yang terjadi, dengan cara yang cukup berguna, dan perintah yang
git status
.2 Secara teknis, ini sebenarnya bukan salinan sama sekali. Sebagai gantinya, ini adalah referensi ke file Git-ified, pra-duplikat dan semuanya. Ada lebih banyak hal di sini juga, seperti mode, nama file, nomor pementasan, dan beberapa data cache untuk membuat Git bekerja dengan cepat. Tetapi kecuali Anda mulai bekerja dengan beberapa perintah tingkat rendah Git —
git ls-files --stage
dangit update-index
khususnya — Anda bisa menganggapnya sebagai salinan.3 The
git ls-files --stage
perintah akan menampilkan nama dan nomor pementasan setiap file dalam indeks Git, tapi biasanya ini tidak pula sangat berguna.git status
The
git status
perintah benar-benar bekerja dengan menjalankan dua terpisahgit diff
perintah untuk Anda (dan juga melakukan beberapa hal yang berguna lainnya, seperti memberitahu Anda yang cabang Anda berada di).Yang pertama
git diff
membandingkan komit saat ini — yang, ingat, dibekukan sepanjang waktu — dengan apa pun yang ada di indeks Git. Untuk file yang sama , Git tidak akan mengatakan apa-apa. Untuk file yang berbeda , Git akan memberitahu Anda bahwa file ini dalam staging untuk komit . Ini termasuk semua file baru — jika komit tidak adasub.py
di dalamnya, tetapi indeks ada di dalamnya, maka file ini ditambahkan — dan semua file yang dihapus, yang (dan sedang) di komit tetapi tidak adasub.py
di dalamnya indeks lagi (git rm
, mungkin).Yang kedua
git diff
membandingkan semua file di indeks Git dengan file di pohon kerja Anda. Untuk file yang sama , Git tidak mengatakan apa-apa. Untuk file yang berbeda , Git akan memberitahu Anda bahwa file ini tidak dipentaskan untuk komit . Tidak seperti diff pertama, daftar khusus ini tidak menyertakan file yang semuanya baru: jika file tersebutuntracked
ada di work-tree Anda, tetapi tidak ada di indeks Git, Git hanya menambahkannya ke daftar file yang tidak terlacak . 4Pada akhirnya, setelah akumulasi file-file yang tidak terlacak dalam daftar,
git status
akan mengumumkan mereka nama-nama file juga, tapi ada pengecualian khusus: jika nama file terdaftar dalam.gitignore
berkas, yang menekan daftar terakhir ini. Perhatikan bahwa mencantumkan file terlacak — yang ada di indeks Git —.gitignore
tidak berpengaruh di sini : file tersebut ada dalam indeks, sehingga dibandingkan, dan dikomit, meskipun terdaftar di.gitignore
. File abaikan hanya menyembunyikan keluhan "file tidak terlacak". 54 Bila menggunakan versi pendek dari
git status
-git status -s
-the file tidak terlacak tidak sebagai dipisahkan-out, tetapi prinsipnya adalah sama. Mengumpulkan file seperti ini juga memungkinkangit status
meringkas banyak nama file yang tidak terlacak dengan hanya mencetak nama direktori, terkadang. Untuk mendapatkan daftar lengkapnya, gunakangit status -uall
ataugit status -u
.5 Mendaftar file juga membuat secara massal menambahkan banyak operasi file seperti
git add .
ataugit add *
melewati file yang tidak terlacak. Bagian ini menjadi sedikit lebih rumit, karena Anda dapat menggunakangit add --force
untuk menambahkan file yang biasanya akan dilewati. Ada beberapa kasus khusus yang biasanya kecil, yang semuanya bertambah seperti ini: file tersebut.gitignore
mungkin dipanggil dengan lebih tepat.git-do-not-complain-about-these-untracked-files-and-do-not-auto-add-them
atau sesuatu yang sama beratnya. Tapi itu terlalu konyol, jadi.gitignore
memang begitu .git add -u
,,git commit -a
dllAda beberapa pintasan praktis yang perlu diketahui di sini:
git add .
akan menambahkan semua file yang diperbarui di direktori saat ini dan setiap sub-direktori. Hal ini berlaku.gitignore
, jadi jika file yang saat ini tidak terlacak tidak dikeluhkan olehgit status
, itu tidak akan ditambahkan secara otomatis.git add -u
akan otomatis menambahkan semua file yang diperbarui di mana saja di pohon kerja Anda . 6 Ini hanya mempengaruhi file yang dilacak . Perhatikan bahwa jika Anda telah menghapus salinan pohon kerja, ini juga akan menghapus salinan indeks (git add
lakukan ini sebagai bagian dari membuat indeks cocok dengan pohon kerja ).git add -A
seperti berlarigit add .
dari tingkat teratas pohon kerja Anda (tapi lihat catatan kaki 6).Selain itu, Anda dapat berlari
git commit -a
, yang kira-kira setara dengan 7 untuk berlarigit add -u
lalugit commit
. Artinya, ini memberi Anda perilaku yang sama yang nyaman di Mercurial.Saya biasanya menyarankan untuk tidak mengikuti
git commit -a
pola: Saya menemukan bahwa lebih baik untukgit status
sering menggunakan , melihat lebih dekat pada output , dan jika statusnya tidak seperti yang Anda harapkan, cari tahu mengapa demikian. Menggunakangit commit -a
, terlalu mudah untuk secara tidak sengaja mengubah file dan melakukan perubahan yang tidak ingin Anda lakukan. Tapi ini sebagian besar masalah selera / pendapat.6 Jika versi Git Anda mendahului Git 2.0, berhati-hatilah di sini:
git add -u
hanya berfungsi pada direktori dan sub-direktori saat ini, jadi Anda harus naik ke level teratas dari pohon kerja Anda terlebih dahulu. Thegit add -A
pilihan memiliki masalah serupa.7 Saya katakan kira-kira setara karena
git commit -a
sebenarnya bekerja dengan membuat indeks tambahan, dan menggunakan indeks lain itu untuk melakukan komit. Jika komit berhasil , Anda mendapatkan efek yang sama seperti melakukangit add -u && git commit
. Jika komit tidak berfungsi — jika Anda membuat Git melewati komit dengan salah satu dari banyak cara yang dapat Anda lakukan — maka tidak ada file yang di-git add
beri setelahnya, karena Git membuang indeks tambahan sementara dan kembali menggunakan indeks utama .Ada komplikasi tambahan yang datang jika Anda menggunakan di
git commit --only
sini. Dalam kasus ini, Git membuat indeks ketiga , dan segalanya menjadi sangat rumit, terutama jika Anda menggunakan hook pra-komit. Ini adalah alasan lain untuk menggunakangit add
operasi terpisah .sumber
Area pementasan membantu kami menyusun komitmen dengan lebih fleksibel. Dengan membuat, maksud saya memecah komitmen menjadi unit logis. Ini sangat penting jika Anda menginginkan perangkat lunak yang dapat dipelihara. Cara paling jelas untuk mencapai ini:
Anda dapat mengerjakan beberapa fitur / bug dalam satu direktori kerja dan masih membuat komitmen yang berarti. Memiliki satu direktori kerja yang berisi semua pekerjaan aktif kami juga sangat nyaman. (Ini dapat dilakukan tanpa staging area, hanya selama perubahan tidak pernah tumpang tindih dengan file. Dan Anda juga memiliki tanggung jawab tambahan untuk melacak secara manual apakah perubahan tersebut tumpang tindih)
Anda dapat menemukan lebih banyak contoh di sini: Penggunaan Indeks
Dan bagian terbaiknya adalah, keuntungannya tidak berhenti dengan daftar alur kerja ini. Jika alur kerja unik muncul, Anda hampir bisa yakin bahwa area pementasan akan membantu Anda.
sumber
Saya melihat pentingnya menggunakan panggung untuk membuat komitmen lebih kecil seperti yang disebutkan oleh @Ben Jackson dan @Tapashee Tabassum Urmi dan terkadang saya menggunakannya untuk tujuan itu, tetapi saya terutama menggunakannya untuk membuat komitmen saya lebih besar! inilah poin saya:
Katakanlah saya ingin menambahkan fitur kecil yang memerlukan beberapa langkah kecil. Saya tidak melihat gunanya memiliki komit terpisah untuk langkah-langkah yang lebih kecil dan membanjiri timeline saya. Namun saya ingin menyimpan setiap langkah dan kembali jika perlu,
Saya hanya melakukan langkah-langkah yang lebih kecil di atas satu sama lain dan ketika saya merasa itu layak untuk sebuah komitmen, saya berkomitmen. Dengan cara ini saya menghapus komit yang tidak perlu dari timeline namun dapat membatalkan (checkout) langkah terakhir.
Saya melihat cara lain untuk melakukan ini (menyederhanakan riwayat git) yang mungkin Anda gunakan tergantung pada preferensi Anda:
sumber
Ini seperti kotak centang yang memberikan kemampuan untuk memilih file apa yang akan digunakan.
Misalnya, jika saya telah mengedit
fileA.txt
danfileB.txt
. Tapi saya hanya ingin melakukan perubahanfileA.txt
. karena saya belum selesai denganfileB.txt
.Saya cukup menggunakan
git add fileA.txt
dan berkomitmen menggunakangit commit -m "changed fileA.txt"
dan terus bekerja denganfileB.txt
dan setelah selesai saya dapat berkomitmenfileB.txt
dengan mudahsumber