Saya telah menggunakan Perforce selama beberapa tahun. Saya ingin beralih menggunakan git untuk kode pribadi saya, tetapi semua tutorial git yang saya lihat berasumsi bahwa Anda adalah kontrol sumber lengkap n00b (yang membuatnya sangat membosankan) atau Anda terbiasa svn (yang bukan saya).
Saya tahu p4, dan saya juga memahami ide di balik sistem kendali sumber terdistribusi (jadi saya tidak perlu promosi dagang, terima kasih). Yang saya inginkan adalah tabel terjemahan dari perintah p4 ke perintah git yang setara, serta perintah "tidak bisa hidup tanpanya" yang tidak memiliki padanan p4.
Karena saya curiga setiap pengguna p4 menggunakan subset berbeda dari p4, berikut adalah beberapa hal yang biasa saya lakukan di p4 yang ingin saya lakukan di git yang tidak langsung terlihat dari dokumen yang saya lihat :
- membuat beberapa daftar perubahan tertunda dalam satu klien. (
p4 change
) - edit daftar perubahan yang tertunda. (juga
p4 change
) - lihat daftar semua daftar perubahan saya yang tertunda (
p4 changes -s pending
) - daftar semua file yang diubah di klien saya (
p4 opened
) atau dalam daftar perubahan yang tertunda (p4 describe
) - lihat perbedaan dari daftar perubahan yang tertunda (saya menggunakan skrip pembungkus untuk ini yang menggunakan
p4 diff
danp4 describe
) - untuk file tertentu, lihat daftar perubahan yang dikirimkan yang mempengaruhi baris mana (
p4 annotate
) - untuk file tertentu, lihat daftar deskripsi dari daftar perubahan yang mempengaruhi file (
p4 log
) - kirimkan daftar perubahan yang tertunda (
p4 submit -c
) - batalkan daftar perubahan yang tertunda (
p4 revert
)
Banyak dari ini berputar di sekitar "daftar perubahan". "changelist" adalah terminologi p4. Apa istilah setara git?
Kedengarannya seperti branch mungkin adalah apa yang digunakan pengguna git sebagai pengganti dari apa yang disebut daftar perubahan p4. Agak membingungkan, karena p4 juga memiliki sesuatu yang disebut cabang meskipun tampaknya hanya konsep yang terkait secara samar. (Meskipun saya selalu berpikir konsep p4 tentang sebuah cabang cukup aneh, ini berbeda lagi dari konsep RCS klasik tentang sebuah cabang.)
Bagaimanapun ... Saya tidak yakin bagaimana mencapai apa yang biasanya saya lakukan di daftar perubahan p4 dengan cabang git. Di p4 saya bisa melakukan sesuatu seperti ini:
$ p4 edit a.txt
$ p4 change a.txt
Change 12345 created.
Pada titik ini saya memiliki daftar perubahan yang berisi a.txt. Saya dapat mengedit deskripsi dan terus bekerja tanpa mengirimkan daftar perubahan. Selain itu, jika ternyata saya perlu membuat beberapa perubahan pada beberapa file lain, seperti misalnya perbaikan bug di beberapa lapisan kode lainnya, saya dapat melakukannya di klien yang sama:
$ p4 edit z.txt
$ p4 change z.txt
Change 12346 created.
Sekarang saya memiliki dua daftar perubahan terpisah di klien yang sama. Saya dapat mengerjakan ini secara bersamaan, dan saya tidak perlu melakukan apa pun untuk "beralih di antara" keduanya. Jika tiba waktunya untuk berkomitmen, saya dapat mengirimkannya secara terpisah:
$ p4 submit -c 12346 # this will submit the changes to z.txt
$ p4 submit -c 12345 # this will submit the changes to a.txt
Saya tidak tahu cara mereplikasi ini di git. Dari percobaan saya, tidak tampak yang git add
terkait dengan cabang saat ini. Sejauh yang saya tahu, kapan saya git commit
akan mengkomit semua file yang saya git add
-ed tidak peduli di cabang mana saya berada saat itu:
$ git init
Initialized empty Git repository in /home/laurence/git-playground/.git/
$ ls
a.txt w.txt z.txt
$ git add -A .
$ git commit
Initial commit.
3 files changed, 3 insertions(+), 0 deletions(-)
create mode 100644 a.txt
create mode 100644 w.txt
create mode 100644 z.txt
$ vi a.txt z.txt
2 files to edit
$ git status
# On branch master
# Changed but not updated:
# (use "git add <file>..." to update what will be committed)
# (use "git checkout -- <file>..." to discard changes in working directory)
#
# modified: a.txt
# modified: z.txt
#
no changes added to commit (use "git add" and/or "git commit -a")
$ git branch aardvark
$ git checkout aardvark
M a.txt
M z.txt
Switched to branch 'aardvark'
$ git add a.txt
$ git checkout master
M a.txt
M z.txt
Switched to branch 'master'
$ git branch zebra
$ git checkout zebra
M a.txt
M z.txt
Switched to branch 'zebra'
$ git add z.txt
$ git status
# On branch zebra
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
# modified: a.txt
# modified: z.txt
#
$ git checkout aardvark
M a.txt
M z.txt
Switched to branch 'aardvark'
$ git status
# On branch aardvark
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
# modified: a.txt
# modified: z.txt
Dalam contoh ini, cabang aardvark dan zebra tampaknya berisi sekumpulan perubahan yang persis sama, dan berdasarkan keluarannya git status
tampaknya melakukan komit di salah satu cabang tersebut akan memiliki efek yang sama. Apakah saya melakukan sesuatu yang salah?
Jawaban:
Saya belum banyak menggunakan paksa jadi ini mungkin bukan terjemahan 1: 1. Kemudian lagi sistem kendali sumber terdistribusi seperti git dan mercurial memiliki alur kerja yang berbeda sehingga sebenarnya tidak ada (dan seharusnya tidak ada) terjemahan 1: 1. Bagaimanapun, ini dia:
Buat beberapa daftar perubahan tertunda -> Gunakan cabang sebagai gantinya. Dalam git, cabang ringan dan cepat, membutuhkan waktu kurang dari satu detik untuk dibuat dan biasanya kurang dari dua detik untuk bergabung. Jangan takut bercabang dan sering melakukan rebase.
Atau lakukan semuanya dalam satu baris:
Lihat daftar semua daftar perubahan tertunda -> Karena persamaan dari beberapa daftar perubahan tertunda adalah beberapa cabang lihat saja cabangnya:
Jika Anda ingin melihat cabang jarak jauh juga:
Merupakan praktik yang baik untuk segera menghapus cabang setelah penggabungan berhasil sehingga Anda tidak perlu melacak cabang mana yang menunggu untuk digabungkan dan yang telah digabungkan.
Buat daftar semua file yang diubah -> Untuk satu "daftar perubahan" yang tertunda di cabang tertentu, git memiliki konsep indeks atau cache. Untuk melakukan perubahan, Anda harus menambahkan file ke indeks ini terlebih dahulu. Ini memungkinkan Anda untuk secara manual memilih grup file mana yang mewakili satu perubahan atau mengabaikan file yang tidak relevan. Untuk melihat status file mana yang ditambahkan, atau tidak ke indeks ini, lakukan saja:
Lihat diff dari daftar perubahan tertunda -> Ada dua bagian untuk ini. Pertama untuk melihat perbedaan antara direktori kerja dan indeks:
Tetapi jika Anda ingin mengetahui perbedaan antara apa yang Anda ketik sekarang dan komit terakhir maka Anda benar-benar meminta perbedaan antara direktori kerja + index dan HEAD:
Untuk file tertentu, lihat daftar perubahan yang dikirimkan yang mempengaruhi baris mana -> Ini mudah:
atau bahkan lebih baik, jika Anda berada di lingkungan jendela:
Git gui membutuhkan waktu lebih lama untuk mengurai file (itu ditulis di tcl bukan C) tetapi memiliki banyak fitur rapi termasuk kemampuan untuk "perjalanan waktu" kembali ke masa lalu dengan mengklik ID komit. Saya hanya berharap mereka menerapkan fitur untuk "perjalanan waktu" ke masa depan sehingga saya dapat mengetahui bagaimana bug tertentu akhirnya akan diselesaikan ;-)
Untuk file tertentu, lihat daftar deskripsi changelists yang mempengaruhi file -> juga mudah:
Tapi git log adalah alat yang jauh lebih kuat dari ini. Sebenarnya sebagian besar skrip pribadi saya mendukung git log untuk membaca repositori. Baca halaman manual.
Kirimkan daftar perubahan yang tertunda -> Juga mudah:
Lihat jawaban saya atas pertanyaan sebelumnya untuk melihat alur kerja git khas saya: Learning Git. Perlu tahu apakah saya berada di jalur yang benar
Jika Anda mengikuti alur kerja yang saya uraikan maka Anda akan menemukan alat seperti gitk jauh lebih berharga karena memungkinkan Anda untuk melihat kelompok perubahan dengan jelas.
Jawaban tambahan:
Git sangat fleksibel dan ada beberapa cara untuk melakukan apa yang Anda gambarkan. Hal yang perlu diingat adalah selalu memulai cabang baru untuk setiap fitur yang Anda kerjakan. Ini berarti cabang master tidak tersentuh sehingga Anda selalu dapat kembali ke sana untuk melakukan perbaikan bug. Bekerja di git seseorang hampir selalu dimulai dengan:
Sekarang Anda dapat mengedit file a.txt. Untuk bekerja secara bersamaan pada fitur lain, lakukan:
Sekarang Anda dapat mengedit file z.txt. Untuk beralih kembali ke a.txt:
Tapi tunggu, ada perubahan pada new-feature-z dan git tidak akan membiarkan Anda berpindah cabang. Saat ini Anda memiliki dua pilihan. Yang pertama adalah yang paling sederhana, lakukan semua perubahan ke cabang saat ini:
Ini yang saya rekomendasikan. Tetapi jika Anda benar-benar belum siap untuk memasukkan kode, Anda dapat menyimpannya untuk sementara:
Sekarang Anda dapat beralih ke cabang new-feature-a. Untuk kembali ke kode yang sedang Anda kerjakan, cukup masukkan simpanan:
Setelah semua selesai, gabungkan kembali semua perubahan ke master:
Karena penggabungan sangat cepat dan mudah (mudah karena konflik jarang terjadi dan resolusi konflik, ketika terjadi, tidak terlalu sulit) kami menggunakan cabang di git untuk semuanya.
Berikut contoh lain dari penggunaan umum cabang di git yang tidak Anda lihat di alat kendali sumber lainnya (kecuali mungkin lincah):
Perlu terus mengubah file konfigurasi untuk mencerminkan lingkungan dev Anda? Kemudian gunakan cabang:
Sekarang edit file konfigurasi Anda di editor favorit Anda lalu lakukan perubahan:
Sekarang setiap cabang baru bisa mulai dari cabang dev-config alih-alih master:
Setelah Anda selesai, hapus hasil edit di dev-config dari new-feature-branch menggunakan rebase interaktif:
Hapus komit yang tidak Anda inginkan, lalu simpan. Sekarang Anda memiliki cabang yang bersih tanpa pengeditan konfigurasi khusus. Saatnya untuk bergabung kembali menjadi master:
Perlu dicatat bahwa menghapus pengeditan
git rebase -i
bahkan bekerja ketika semua perubahan terjadi dalam file yang sama. Git mengingat perubahan, bukan konten file *.* Catatan: sebenarnya, secara teknis tidak sepenuhnya benar tetapi sebagai pengguna seperti itulah rasanya
Lebih banyak jawaban tambahan:
Jadi, dari komentar Anda, sepertinya Anda ingin memiliki dua cabang yang ada secara bersamaan sehingga Anda dapat menguji cara kerja kode gabungan. Nah, ini adalah cara yang baik untuk menggambarkan kekuatan dan fleksibilitas cabang.
Pertama, sebuah kata tentang implikasi percabangan murah dan riwayat yang dapat dimodifikasi pada alur kerja Anda. Ketika saya menggunakan CVS dan SVN, saya selalu agak enggan untuk berkomitmen. Itu karena melakukan kode yang tidak stabil pasti akan mengacaukan kode kerja orang lain. Tapi dengan keberanian aku kehilangan rasa takut itu. Itu karena dalam git orang lain tidak akan mendapatkan perubahan saya sampai saya menggabungkannya menjadi master. Jadi sekarang saya menemukan diri saya melakukan kode setiap 5 baris yang saya tulis. Anda tidak membutuhkan pandangan jauh ke depan yang sempurna untuk berkomitmen. Anda hanya perlu mengubah pola pikir Anda: commit-to-branch == add-to-changeset, merge-to-master == commit-changeset.
Jadi, kembali ke contoh. Begini cara saya melakukannya. Katakanlah Anda memiliki cabang
new-feature-z
dan ingin mengujinyanew-feature-a
. Saya hanya akan membuat cabang baru untuk mengujinya:Sekarang Anda bisa mengujinya. Jika Anda perlu memodifikasi sesuatu untuk membuat feature-z berfungsi dengan feature-a, lakukanlah. Jika demikian, Anda dapat menggabungkan kembali perubahan ke cabang yang relevan. Gunakan
git rebase -i
untuk menghapus perubahan yang tidak relevan dari gabungan.Sebagai alternatif, Anda juga dapat menggunakan git rebase untuk mengubah sementara basis new-feature-z untuk menunjuk ke new-feature-a:
Sekarang riwayat cabang diubah sehingga new-feature-z akan didasarkan pada new-feature-a, bukan master. Sekarang Anda bisa mengujinya. Setiap perubahan yang dilakukan di cabang ini akan menjadi milik cabang new-feature-z. Jika Anda perlu memodifikasi fitur-baru-cukup beralih kembali ke sana dan rebase untuk mendapatkan perubahan baru:
Setelah selesai, cukup rebase kembali ke master untuk menghapus perubahan dari new-feature-a:
Jangan takut untuk memulai cabang baru. Jangan takut untuk memulai cabang sekali pakai. Jangan takut membuang ranting. Dan karena merge == submit dan commit == add-to-changeset jangan takut untuk sering melakukan. Ingat, komit adalah alat pembatalan utama pengembang.
Oh, dan satu hal lagi, di git cabang yang dihapus masih ada di repositori Anda. Jadi, jika Anda tidak sengaja menghapus sesuatu yang kemudian Anda sadari berguna, Anda selalu bisa mendapatkannya kembali dengan mencari riwayatnya. Jadi jangan takut membuang ranting.
sumber
Saya tidak memiliki cukup pengalaman p4 untuk menghasilkan lembar contekan yang sebenarnya, tetapi setidaknya ada beberapa kesamaan untuk digunakan kembali. Sebuah "perubahan" p4 adalah "komit" git.
Perubahan pada ruang kerja lokal Anda akan ditambahkan ke "indeks" dengan
git add
, dan indeks kemudian dikomitmenkan dengangit commit
. Jadi, indeks adalah daftar perubahan Anda yang tertunda, untuk semua maksud dan tujuan.Anda melihat perubahan dengan
git diff
dangit status
, di managit diff
biasanya menunjukkan perubahan antara ruang kerja dan indeks, tetapigit diff --cached
menunjukkan perubahan antara indeks dan repositori (= daftar perubahan tertunda Anda).Untuk informasi yang lebih mendalam, saya merekomendasikan http://progit.org/book/ . Karena Anda mengetahui kontrol versi secara umum, Anda mungkin dapat membaca sekilas banyak dan mengekstrak informasi khusus git ...
sumber
Saya menderita seperti Anda dengan kurangnya konsep "daftar perubahan" yang tidak persis sama dengan cabang git.
Saya akan menulis skrip kecil yang akan membuat file daftar perubahan dengan daftar file di daftar perubahan itu.
Perintah lain untuk mengirimkan hanya daftar perubahan tertentu dengan memanggil git commit -a @ change_list_contents.txt dan kemudian "git commit"
Semoga itu bisa membantu, Elias
sumber
Ada alternatif yang lebih ringan di git yang bisa menjadi bagian dari alur kerja Anda; menggunakan area pementasan git.
Saya sering hanya membuat perubahan kemudian mengirimkan sebagai beberapa komit (misalnya menambahkan pernyataan debug, refactor, benar-benar memperbaiki bug). Daripada menyiapkan daftar perubahan perforce Anda, lalu buat perubahan, lalu kirim, Anda cukup membuat perubahan Anda lalu memilih cara mengirimkannya (secara opsional menggunakan area staging git).
Anda dapat memasukkan file tertentu dari baris perintah dengan:
Atau secara eksplisit mementaskan file terlebih dahulu:
git gui akan membiarkan Anda memilih baris atau bongkahan dari dalam file untuk membuat komit di area pementasan. Ini sangat berguna jika Anda memiliki perubahan dalam satu file yang Anda inginkan dalam komit yang berbeda. Setelah beralih dari git ke perforce dan ini adalah satu hal yang sangat saya rindukan.
Ada sedikit peringatan yang perlu diingat dengan alur kerja ini. Jika Anda membuat perubahan A dan B ke file, uji file tersebut, lalu komit A maka Anda belum menguji komit itu (terlepas dari B).
sumber
Ini tidak menjawab pertanyaan Anda secara spesifik, tetapi saya tidak tahu apakah Anda mengetahui bahwa versi 2 Pengguna, 5 Ruang Kerja dari perforce gratis untuk diunduh dan digunakan dari situs web perforce .
Dengan cara ini Anda dapat menggunakan perforce di rumah untuk proyek pribadi Anda jika Anda mau. Satu-satunya gangguan adalah 5 ruang kerja yang bisa sedikit membatasi, tetapi cukup luar biasa untuk memiliki paksa tersedia untuk digunakan di rumah.
sumber
Setelah menggunakan Perforce dan git secara cukup ekstensif, hanya ada satu cara yang bisa saya lihat untuk mendekati daftar perubahan Perforce dengan git.
Hal pertama yang harus dipahami adalah bahwa untuk mengimplementasikan fungsionalitas ini dengan benar di git sedemikian rupa sehingga ini bukan kluge lengkap, misalnya mencoba menyekolkannya menjadi cabang, akan memerlukan perubahan berikut: git akan memerlukan beberapa area staging untuk satu cabang .
Daftar perubahan Perforce mengizinkan alur kerja yang tidak memiliki padanan di git. Pertimbangkan alur kerja berikut ini:
Jika Anda mencoba melakukan ini menggunakan cabang di git, Anda akan mendapatkan dua cabang, salah satunya memiliki perubahan ke file
A
, yang lain memiliki perubahan ke fileB
, tetapi tidak ada tempat di mana Anda dapat melihat perubahan pada kedua fileA
danB
di waktu yang sama.Perkiraan terdekat saya bisa melihat adalah dengan menggunakan
git add . -p
dan kemudian menggunakan'a'
dan'd'
sub-perintah untuk memilih atau menolak seluruh file. Namun itu tidak sepenuhnya sama, dan perbedaannya di sini berasal dari perbedaan mendasar dalam modus operandi umum kedua sistem tersebut.Git (dan subversi, tidak penting untuk diskusi ini) memungkinkan file diubah tanpa memberi tahu siapa pun sebelumnya. Anda cukup mengubah file, dan kemudian biarkan git mengurutkannya saat Anda melakukan perubahan. Perforce mengharuskan Anda untuk secara aktif memeriksa file sebelum perubahan diizinkan, dan untuk alasan inilah daftar perubahan harus ada. Intinya, Perforce mengharuskan Anda untuk menambahkan file ke indeks sebelum mengubahnya. Oleh karena itu perlunya banyak daftar perubahan di Perforce, dan juga alasan mengapa git tidak memiliki padanan. Itu tidak membutuhkan mereka.
sumber
Dengan Git 2.27 (Kuartal 2 2020), "
git p4
" mempelajari empat hook baru dan juga--no-verify
opsi " " untuk melewati mereka (danp4-pre-submit
hook " " yang ada ).Lihat commit 1ec4a0a , commit 38ecf75 , commit cd1e0dc (14 Feb 2020), dan commit 4935c45 , commit aa8b766 , commit 9f59ca4 , commit 6b602a2 (11 Feb 2020) oleh Ben Keene (
seraphire
) .(Digabung oleh Junio C Hamano -
gitster
- di commit 5f2ec21 , 22 Apr 2020)Sebelum Git 2.28 (Kuartal 3 2020), opsi "
--prepare-p4-only
" seharusnya berhenti setelah memutar ulang satu set perubahan, tetapi terus berjalan (karena kesalahan?)Lihat commit 2dfdd70 (12 Mei 2020) oleh Ben Keene (
seraphire
) .(Digabung oleh Junio C Hamano -
gitster
- di commit 7a8fec9 , 02 Jun 2020)sumber