Saya pernah membaca bahwa ketika mengganti nama file di git , Anda harus melakukan perubahan apa pun, melakukan penggantian nama, lalu memformat file yang diubah namanya. Git akan mengenali file dari konten, daripada melihatnya sebagai file baru yang tidak terlacak, dan menyimpan sejarah perubahan.
Namun, melakukan hal ini malam ini akhirnya saya kembalikan git mv
.
> $ git status
# On branch master
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
# modified: index.html
#
Ganti nama stylesheet saya di Finder dari iphone.css
menjadimobile.css
> $ git status
# On branch master
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
# modified: index.html
#
# Changed but not updated:
# (use "git add/rm <file>..." to update what will be committed)
# (use "git checkout -- <file>..." to discard changes in working directory)
#
# deleted: css/iphone.css
#
# Untracked files:
# (use "git add <file>..." to include in what will be committed)
#
# css/mobile.css
Jadi git sekarang berpikir saya sudah menghapus satu file CSS, dan menambahkan yang baru. Bukan yang saya inginkan, mari batalkan ganti nama dan biarkan git melakukan pekerjaan.
> $ git reset HEAD .
Unstaged changes after reset:
M css/iphone.css
M index.html
Kembali ke tempat saya mulai.
> $ git status
# On branch master
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
# modified: index.html
#
Mari kita gunakan git mv
saja.
> $ git mv css/iphone.css css/mobile.css
> $ git status
# On branch master
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
# renamed: css/iphone.css -> css/mobile.css
#
# 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: index.html
#
Sepertinya kita baik-baik saja. Jadi mengapa git tidak mengenali nama baru pertama kali ketika saya menggunakan Finder?
add+rm
ataumv
- menghasilkan hasil yang sama. Git kemudian menggunakan rename / copy detection untuk memberi tahu Anda bahwa itu adalah rename. Sumber yang Anda kutip juga tidak akurat. Tidak masalah apakah Anda memodifikasi + mengganti nama di komit yang sama atau tidak. Ketika Anda melakukan diff di kedua modifikasi dan ganti nama, deteksi ganti nama akan melihatnya sebagai perubahan nama + modifikasi, atau jika modifikasi adalah penulisan ulang total, itu akan ditampilkan sebagai ditambahkan dan dihapus - masih tidak peduli bagaimana Anda melakukan Itu.git mv old new
secara otomatis memperbarui indeks. Ketika Anda mengganti nama di luar Git, Anda harus melakukangit add new
dangit rm old
melakukan perubahan pada indeks. Setelah selesai, inigit status
akan berfungsi seperti yang Anda harapkan.public_html
dir, yang dilacak di git. Setelah dilakukangit add .
dangit commit
, masih menunjukkan banyak file 'dihapus' digit status
. Saya melakukangit commit -a
dan penghapusan dilakukan tetapi sekarang saya tidak memiliki riwayat pada file yang hiduppublic_html
sekarang. Alur kerja ini tidak semulus yang saya inginkan.Jawaban:
Untuk
git mv
itu halaman buku panduan mengatakanJadi, pada awalnya, Anda harus memperbarui indeks sendiri (dengan menggunakan
git add mobile.css
). Namungit status
akan tetap menampilkan dua file berbedaAnda bisa mendapatkan output berbeda dengan menjalankan
git commit --dry-run -a
, yang menghasilkan apa yang Anda harapkan:Saya tidak bisa memberi tahu Anda dengan tepat mengapa kita melihat perbedaan antara
git status
dangit commit --dry-run -a
, tapi ini adalah petunjuk dari Linus :A
dry-run
menggunakan mekanisme penggantian nama yang sebenarnya, sementara yanggit status
mungkin tidak.sumber
git add mobile.css
. Tanpanyagit status -a
hanya akan 'melihat' penghapusaniphone.css
file yang sebelumnya dilacak tetapi tidak akan menyentuh file baru yang tidak terlacakmobile.css
. Juga,git status -a
tidak valid dengan Git 1.7.0 dan yang lebih baru. "" Git status "bukan" git commit --dry-run "lagi." di kernel.org/pub/software/scm/git/docs/RelNotes-1.7.0.txt . Gunakangit commit --dry-run -a
jika Anda ingin fungsi ini. Seperti yang orang lain katakan, perbarui saja indeks dangit status
hanya akan berfungsi seperti yang diharapkan OP.git commit
hal yang normal itu tidak akan melakukan file yang diubah namanya dan pohon yang bekerja masih sama.git commit -a
mengalahkan hampir setiap aspek dari alur kerja / model berpikir git — setiap perubahan dilakukan. bagaimana jika Anda hanya ingin mengubah nama file, tetapi komit perubahanindex.html
di komit lain?mobile.css
yang seharusnya saya sebutkan. Tapi itulah inti dari jawaban saya: halaman manual mengatakan ituthe index is updated
ketika Anda menggunakangit-mv
. Terima kasih atasstatus -a
klarifikasi, saya menggunakan git 1.6.4git status
tidak mendeteksi penggantian nama. Berjalangit commit -a --dry-run
setelah menambahkan file "baru" saya menunjukkan nama dan akhirnya memberi saya kepercayaan untuk melakukan!git status
sekarang berperilaku sepertigit commit
.Anda harus menambahkan dua file yang dimodifikasi ke indeks sebelum git akan mengenalinya sebagai langkah.
Satu-satunya perbedaan antara
mv old new
dangit mv old new
adalah bahwa git mv juga menambahkan file ke indeks.mv old new
makagit add -A
akan bekerja juga.Perhatikan bahwa Anda tidak bisa hanya menggunakan
git add .
karena itu tidak menambah kepindahan ke indeks.Lihat Perbedaan antara "git add -A" dan "git add."
sumber
git add -A
tautannya, sangat berguna, karena saya mencari jalan pintas seperti itu!git add .
tidak menambah kepindahan ke indeks.Hal terbaik adalah mencobanya sendiri.
Sekarang status git dan komit git --dry-run -a menunjukkan dua hasil yang berbeda di mana status git menunjukkan bbb.txt sebagai file baru / aaa.txt dihapus, dan perintah --dry-run perintah menunjukkan nama sebenarnya.
Sekarang lanjutkan dan lakukan check-in.
Sekarang Anda dapat melihat bahwa file tersebut sebenarnya diganti namanya, dan apa yang ditampilkan dalam status git salah.
Moral dari cerita ini: Jika Anda tidak yakin apakah file Anda diganti namanya, berikan "git commit --dry-run -a". Jika itu menunjukkan bahwa file diubah namanya, Anda baik untuk pergi.
sumber
Untuk git 1.7.x perintah berikut ini berfungsi untuk saya:
Tidak perlu untuk git add, karena file asli (yaitu css / mobile.css) sudah ada di file yang dikomit sebelumnya.
sumber
Anda harus ke
git add css/mobile.css
file baru dangit rm css/iphone.css
, jadi git tahu tentang itu. maka akan menampilkan output yang sama digit status
Anda dapat melihatnya dengan jelas di keluaran status (nama baru file):
dan (nama lama):
saya pikir di balik layar
git mv
tidak lebih dari skrip pembungkus yang melakukan hal itu: hapus file dari indeks dan tambahkan dengan nama yang berbedasumber
git rm css/iphone.css
karena saya pikir ini akan menghapus sejarah yang ada. Mungkin saya salah paham alur kerja di git.git rm
tidak akan menghapus riwayat. Itu hanya menghapus entri dari indeks sehingga komit berikutnya tidak akan memiliki entri. Namun, itu masih akan ada dalam komitmen leluhur. Yang mungkin Anda bingung adalah bahwa (misalnya)git log -- new
akan berhenti pada titik di mana Anda berkomitmengit mv old new
. Jika Anda ingin mengikuti penggantian nama, gunakangit log --follow -- new
.Mari kita pikirkan file Anda dari perspektif git.
Repositori Anda memiliki (antara lain)
dan itu di bawah kontrol git:
Uji ini dengan:
Saat kamu melakukan
Dari perspektif git,
Jadi, git menyarankan tentang file-file yang sudah dikenalnya ( iphone.css ) dan file-file baru yang dideteksinya ( mobile.css ) tetapi hanya ketika file-file tersebut berada dalam indeks atau HEAD git mulai memeriksa isinya.
Saat ini, penghapusan "iphone.css" maupun mobile.css tidak ada dalam indeks.
Tambahkan penghapusan iphone.css ke indeks
git memberi tahu Anda apa yang telah terjadi: ( iphone.css dihapus. Tidak ada lagi yang terjadi)
lalu tambahkan file baru mobile.css
Kali ini penghapusan dan file baru sedang dalam indeks. Sekarang git mendeteksi konteksnya sama dan mengeksposnya sebagai ganti nama. Bahkan jika file 50% mirip itu akan mendeteksi itu sebagai nama, yang memungkinkan Anda mengubah mobile.css sedikit sambil menjaga operasi sebagai nama.
Lihat ini dapat direproduksi pada
git diff
. Sekarang file Anda berada di indeks yang harus Anda gunakan--cached
. Edit sedikit mobile.css , tambahkan itu ke indeks dan lihat perbedaan antara:dan
-M
adalah opsi "detect renames" untukgit diff
.-M
kependekan-M50%
(50% atau lebih kesamaan akan membuat git mengekspresikannya sebagai ganti nama) tetapi Anda dapat mengurangi ini menjadi-M20%
(20%) jika Anda banyak mengedit mobile.css.sumber
Langkah 1: ganti nama file dari file lama ke file baru
Langkah2: git melakukan dan menambahkan komentar
Langkah 3: dorong perubahan ini ke jarak jauh
sumber
git mv
, file baru sudah ada dalam indeks.Di situlah Anda salah.
Hanya setelah Anda menambahkan file, git akan mengenalinya dari konten.
sumber
Anda tidak menampilkan hasil gerakan pencari Anda. Saya percaya jika Anda melakukan pemindahan melalui Finder dan kemudian melakukannya
git add css/mobile.css ; git rm css/iphone.css
, git akan menghitung hash dari file baru dan baru kemudian menyadari bahwa hash dari file-file tersebut cocok (dan dengan demikian itu adalah nama baru).sumber
Dalam kasus di mana Anda benar-benar harus mengganti nama file secara manual, misalnya. menggunakan skrip untuk batch mengubah nama banyak file, kemudian menggunakan
git add -A .
bekerja untuk saya.sumber
Untuk pengguna Xcode: Jika Anda mengganti nama file Anda di Xcode, Anda melihat ikon lencana berubah untuk ditambahkan. Jika Anda melakukan komit menggunakan XCode, Anda sebenarnya akan membuat file baru dan kehilangan histori.
Penanganannya mudah tetapi Anda harus melakukannya sebelum berkomitmen menggunakan Xcode:
diganti namanya: Project / OldName.h -> Project / NewName.h diganti nama: Project / OldName.m -> Project / NewName.m
Kemudian kembali ke XCode dan Anda akan melihat lencana berubah dari A ke M dan itu disimpan untuk melakukan perubahan furtur dalam menggunakan xcode sekarang.
sumber