git mv dan hanya mengubah case dari direktori


259

Sementara saya menemukan pertanyaan serupa , saya tidak menemukan jawaban untuk masalah saya

Ketika saya mencoba untuk mengubah nama direktori dari FOO ke foo melalui git mv FOO foosaya dapatkan

fatal: renaming 'FOO' failed: Invalid argument

BAIK. Jadi saya cobagit mv FOO foo2 && git mv foo2 foo

Tetapi ketika saya mencoba melakukan melalui git commit .saya dapatkan

# On branch master
# Untracked files:
#   (use "git add <file>..." to include in what will be committed)
#
# foo
nothing added to commit but untracked files present (use "git add" to track)

Ketika saya menambahkan direktori melalui git add fooperubahan tidak ada dan git commit .memberi saya pesan yang sama lagi.

Apa yang saya lakukan salah? Saya pikir saya menggunakan sistem case-sensitive (OSX) mengapa saya tidak bisa mengubah nama direktori?


10
Sistem file OS X tidak peka huruf besar-kecil.
mipadi

2
@mipadi Dapat beroperasi dalam mode peka huruf besar kecil tetapi biasanya dinonaktifkan secara default.
GordonM

1
Pertanyaan ini & jawabannya juga berguna di Windows. Pertimbangkan untuk membatalkan tanda "osx"
Barett

1
Lihat stackoverflow.com/a/24979063/6309 : sejak git 2.0.1, sebuah git mvkarya sederhana .
VonC

Di windows, Anda dapat menggunakan reguler git mv foo Foojika Anda menggunakan shell cygwin.
Andrew Scott

Jawaban:


409

Anda berada dalam lingkungan yang tidak sensitif. Lebih jauh lagi, menambahkan tanpa -Aitu tidak akan menangani sisi penghapusan mvseperti yang dipahami Git. Peringatan! Pastikan tidak ada perubahan lain atau file yang tidak terlacak ada saat Anda melakukan ini atau mereka akan berkomitmen sebagai bagian dari perubahan ini! git stash -upertama, lakukan ini dan kemudian git stash popsetelah itu. Melanjutkan: Untuk menyiasati ini, lakukan hal berikut:

mv foo foo2
git add -A
git commit -m "renaming"
mv foo2 FOO
git add -A
git commit --amend -m "renamed foo to FOO"

Itulah cara yang diambil untuk mengubah direktori kerja, melakukan dan kemudian menciutkan 2 komitmen. Anda bisa memindahkan file dalam indeks, tetapi untuk seseorang yang baru git, mungkin tidak cukup eksplisit tentang apa yang terjadi. Versi yang lebih pendek adalah

git mv foo foo2
git mv foo2 FOO
git commit -m "changed case of dir"

Seperti yang disarankan dalam salah satu komentar, Anda juga dapat melakukan rebase interaktif ( git rebase -i HEAD~5jika case yang salah diperkenalkan 5 komit yang lalu) untuk memperbaiki case di sana dan tidak ada case yang salah muncul di mana saja dalam sejarah sama sekali. Anda harus berhati-hati jika melakukan ini karena hash komit sejak saat itu akan berbeda dan yang lain harus rebase atau menggabungkan kembali pekerjaan mereka dengan masa lalu cabang.

Ini terkait dengan mengoreksi nama file: Apakah git tidak case-sensitive?


1
Terima kasih. Ini membuatku gila. Saya tidak tahu tentang opsi -A atau --amend.
oschrenk

7
Hati-hati dengan -A, karena itu akan secara rekursif menambahkan semua konten di direktori Anda saat ini, termasuk hal-hal yang tidak terlacak. Mungkin lebih baik untuk adil git add foo2.
rich.e

2
Itu betul. Namun Anda harus melakukan tahap penghapusan foo2 dan penambahan FOO secara terpisah. -Amengurus keduanya. Begitu juga sebaliknya untuk langkah pertama. Saya akan menambahkan peringatan. Terima kasih!
Adam Dymitruk

Anda juga dapat membersihkan riwayat Anda dengan rebase interaktif git rebase -i HEAD~2. Catatan: Untuk menyederhanakan ini, atur pesan terakhir di komit pertama Anda dan perbaiki yang kedua.
Alex B.

5
Saya sukses dengan git mv foo foo2; git mv foo2 FOO; git commit
Chris

146

Anda ingin mengatur opsi core.ignorecasemenjadi false, yang akan membuat Git memperhatikan kasus pada sistem file yang tidak mendukungnya. Untuk mengaktifkan di repo Anda:

$ git config core.ignorecase false

Kemudian Anda dapat mengganti nama file dengan git mvdan itu akan berfungsi seperti yang diharapkan.


1
Saya pikir ini mungkin memiliki efek yang tidak diinginkan di tempat lain. Sistem case sensitive harus membuat Git berpikir bahwa itu adalah dir yang sama.
Adam Dymitruk

2
Saya menambahkan opsi ke konfigurasi global saya tetapi tidak membantu
oschrenk

3
Saya melihat beberapa perilaku aneh menggunakan ini dengan OSX. hrm I modified a file that doesn't exist.. hrm error: The following untracked working tree files would be overwritten by checkout:tapi ... file-file itu tidak ada.
Skylar Saveland

Ini persis apa yang saya cari. Saya menjalankan CentOS 5.6 dan tidak menerima perubahan kasing.
crmpicco

5
Ini tidak berfungsi! Pada Git 1.8.3, Git akan memperlakukan file yang diubah namanya sebagai file baru, alih-alih dihapus + ditambahkan. Mengkomit seperti itu akan meninggalkan repositori dengan dua file yang sama, misalnya foo dan FOO keduanya ada! Tetapi ketika checkout hanya satu file yang muncul (tetapi satu case mungkin mendominasi lebih dari case lainnya)
Johnny Wong

68

Saya dapat menyelesaikan ini, menggunakan git 1.7.7 dengan menggunakan nama file sementara:

$ git mv improper_Case improve_case2
$ git mv improve_case2 improve_case
$ git commit -m "<your message>"

Menarik. Mungkin GIT meningkatkan sesuatu sejak itu. Ketika saya akan menemukan masalah ini lagi, saya akan mencoba ini lagi.
oschrenk

jauh lebih mudah melakukannya dengan cara ini
sebelumnya

Bekerja untuk saya di macOS.
Mr_Pouet

14

( git mvvarian -gratis)

Saya mengalami masalah ini di Git pada Mac OS X 10.9. Saya menyelesaikannya sebagai berikut:

git rm -r --cached /path/to/directory

Itu tahapan direktori untuk dihapus di Git tetapi sebenarnya tidak menghapus file fisik ( --cached). Ini juga membuat direktori, sekarang dengan case yang tepat, muncul di file yang tidak terlacak.

Jadi Anda bisa melakukan ini:

mv /path/to/directory /path/to/DIRECTORY
git add -A /path/to/DIRECTORY

Git kemudian akan mengenali bahwa Anda telah mengganti nama file, dan ketika Anda melakukannya, git statusAnda akan melihat sejumlah renamed:baris. Periksa dan pastikan mereka terlihat benar, dan jika demikian, Anda dapat melakukan perubahan secara normal.


Saya menemukan bahwa mvperintah itu tidak berfungsi untuk benar-benar mengganti nama direktori; Saya harus mengganti nama dalam Finder. Selain itu perbaikan ini berfungsi dengan baik.
Adam S

9

Ini adalah solusi cepat dan aman bug:

git mv -f path/to/foo/* path/to/FOO/

Peringatan! Selalu ganti nama semua file di folder yang diubah namanya (gunakan /*).

Jangan ganti nama file tunggal. Ini mengarah ke bug, dijelaskan dalam jawaban ini .

Jika Anda ingin melihat hasilnya terlebih dahulu, gunakan -n:

git mv -f -n path/to/foo/* path/to/FOO/

Setelah Anda membuat mv:

  1. Komit perubahan
  2. Periksa revisi lainnya
  3. Checkout kembali.

Sekarang Git seharusnya mengganti nama folder BOTH dalam file internal dan sistem file.


Apakah ini hanya untuk Git 2.0.1 seperti yang saya sebutkan di komentar pertanyaan di atas? (mengacu pada stackoverflow.com/a/24979063/6309 )
VonC

8

Paksa dengan opsi -f:

git mv -f FOO foo

Tidak bekerja untukku. Pengaturan saya adalah .git / config's "ignorecase = true". Ganti nama tidak dapat dipentaskan di area pementasan dengan cara ini. (Git versi 1.8.3.msysgit.0) Solusi Adam Dymitruk adalah satu-satunya jawaban yang tepat.
Johnny Wong

@JohnnyWong ubah pengaturan Anda menjadi false, itu berhasil untuk saya
Inder Kumar Rathore

Apakah ini akan diperbarui pada semua komputer pengguna lain jika mereka menarik, bahkan jika komputer mereka diatur untuk mengabaikan kasus?
Bryce

@Bryce Tidak, Anda harus melakukan perubahan dan mendorongnya ke repo pusat sebelum pengguna lain dapat menarik perubahan.
konyak

3

Saya punya satu masalah terkait.

Satu folder bernama 'Pro' (dibuat pertama) dan lainnya 'pro' (dibuat karena kesalahan). Di Mac, itu adalah hal yang sama, tetapi berbeda menurut git.

$ git config core.ignorecase false

git config mengubah nama file ke folder kanan (terima kasih), dan juga membuat file ghost di 'pro' (Tidak !!). Saya tidak bisa menambahkan perubahan file ghost ke trek dan saya tidak bisa checkout cabang lain kecuali membawa file-file itu dengan saya, dan saya juga tidak bisa mengatur ulang entah bagaimana.

Alih-alih itu, saya melakukannya

$ git rm -r --cached pro
$ git status // => pro files removed, new Pro files untracked
$ git add Pro

Untuk membuatnya lebih aman, saya melakukannya di cabang perbaikan yang terpisah, dan kemudian saya bergabung kembali ke cabang utama

Untuk masalah file hantu yang dibuat oleh, dapatkah guru menjelaskan Bagaimana dan Mengapa? Terima kasih sebelumnya.


2

Anda tidak menggunakan sistem file case-sensitive dalam OS X kecuali Anda memilihnya secara eksplisit. HFS + bisa case-sensitive, tetapi standarnya adalah case-sensitive.


4
Menggunakan sistem file case-sensitive pada OS X bukanlah ide yang baik. Banyak aplikasi TIDAK bekerja dengan benar, saya belajar dari mencoba ini. Satu masalah khusus adalah bahwa Adobe Photoshop akan menolak untuk menginstal mengatakan bahwa sistem file case-sensitive tidak didukung.
jpswain

1

Inilah solusi yang sangat sederhana di sekitar semua gitfoo di halaman ini.

  1. Salin file dari proyek Anda secara manual.
  2. git rm semua file.
  3. git melakukan seperti biasa.
  4. tambahkan file kembali secara manual.
  5. git tambahkan semua file.
  6. git melakukan seperti biasa.
  7. keuntungan.

1
Ini berfungsi secara lokal, tetapi jika orang lain melakukan penarikan, itu tidak akan mengubah kasus mereka.
Jason

Terima kasih untuk ini membantu saya memperbaiki entri ganda di git dengan kasus yang berbeda. Saya menggunakan varian ini. Baru saja mengganti nama folder induknya. Melakukan komit. Kemudian berganti nama folder induk kembali ke aslinya. Dan melakukan komitmen kedua. Sekarang entri lama dengan kasus yang berbeda hilang.
dreamerkumar

0

Meningkatkan jawaban Adam Dymitruk (konyol bahwa SO tidak membiarkan saya mengomentari jawabannya), dengan menggunakan "git mv" akan secara otomatis menampilkan persis file yang dipindahkan. Tidak diperlukan simpanan dan "git add -A" yang berisiko dapat dihindari:

old="abc";    new="ABC";
tmp="$old-renamed";
git mv "$old" "$tmp";
git commit -m "Renamed '$old' to '$tmp'.";
git mv "$tmp" "$new";
git commit --amend -m "Renamed '$old' to '$new'.";

0

Ini bekerja baik untuk saya di Windows. PowerShell bekas dengan yang berikut ini:

  1. mv .\Folder-With-Wrong-Casing .\temp
  2. git add -A
  3. git commit -m "renamed folder with wrong casing to temp"
  4. mv .\temp .\Folder-with-Correct-Casing
  5. git add -A
  6. git commit --amend -m "Renamed to proper casing"
  7. (pilihan) git push

Berkat jawaban Adam di atas.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.