Bagaimana cara saya melakukan hanya perubahan nama file case-sensitive dalam Git?

1303

Saya telah berubah nama beberapa file dengan de-mengkapitalisasi huruf pertama, seperti dalam Name.jpguntuk name.jpg. Git tidak mengenali perubahan ini dan saya harus menghapus file dan mengunggahnya lagi. Apakah ada cara agar Git peka terhadap huruf besar-kecil saat memeriksa perubahan nama file? Saya belum membuat perubahan pada file itu sendiri.

Gil Shulman
sumber
4
@njika ini tidak sepenuhnya benar, Git sebenarnya memiliki pengaturan konfigurasi yang mengontrol apakah ia mengabaikan sensitivitas huruf besar atau kecil.
2
duplikat yang mungkin dari Apakah git tidak case sensitif
6
Lihat stackoverflow.com/a/24979063/6309 : sejak git 2.0.1, sebuah git mvkarya sederhana .
VonC
kemungkinan duplikat Git: Mengubah kapitalisasi nama file
KyleMit
Lihat posting ini. Saya dapat melakukan tetapi hanya menggunakan git commit -m "msg" tanpa path file sebagai parameter. Itu memperbarui indeks dan memeriksa file. [Link] stackoverflow.com/questions/35790113/…
ARKS

Jawaban:

1518

Anda dapat menggunakan git mv :

git mv -f OldFileNameCase newfilenamecase
Keith Smiley
sumber
12
ini memberi saya 'direktori sumber kosong' sementara tidak
WiseStrawberry
6
Menggunakan MacOS di sini (case-insensitive FS) dan -f bekerja! Terima kasih atas tipnya
caesarsol
49
Dalam versi terbaru, Anda tidak lagi memerlukan -fbendera.
Joshua Pinter
8
Jangan lupa untuk memberikan path file lengkap. Jelas, saya tahu, tetapi mendapatkan saya untuk sementara waktu
rickrizzo
7
Ke atas sebagai komentar: Anda lakukan perlu -fberalih dengan git terbaru (2.18) jika tidak, anda bisa mendapatkan fatal: destination existskesalahan.
DeepSpace101
1038

Git memiliki pengaturan konfigurasi yang mengatakan itu apakah menjadi kasus sensitif atau tidak sensitif: core.ignorecase. Untuk memberi tahu Git sebagai case-senstive, cukup setel pengaturan ini ke false:

git config core.ignorecase false

Dokumentasi

Dari git configdokumentasi :

core.ignorecase

Jika benar, opsi ini memungkinkan berbagai solusi untuk memungkinkan git bekerja lebih baik pada sistem file yang tidak peka terhadap huruf besar-kecil, seperti FAT. Sebagai contoh, jika daftar direktori menemukan makefilekapan git mengharapkan Makefile, git akan menganggap itu benar-benar file yang sama, dan terus mengingatnya sebagai Makefile.

Defaultnya salah, kecuali git-clone (1) atau git-init (1) akan menyelidiki dan menetapkan core.ignorecasetrue jika sesuai ketika repositori dibuat.

Sistem file case-insensitive

Dua sistem operasi paling populer yang memiliki sistem file case-insensitive yang saya tahu adalah

  • Windows
  • OS X

sumber
9
Sebagai tambahan, saya tidak berpikir bahwa Mac OS X itu sendiri tidak peka terhadap huruf besar-kecil. Sebaliknya, itu adalah sistem file yang menentukan sensitivitas huruf. Saat memformat partisi HFS +, pengguna dapat memilih apakah akan membuatnya case-sensitive atau tidak sensitif. Case case-insensitive adalah default.
spaaarky21
225
Tampaknya sangat layak dicatat dalam jawaban ini bahwa pengaturan opsi ini falsepada sistem file case-insensitive adalah ide yang buruk . Ini belum tentu jelas. Sebagai contoh, saya baru saja mencoba ini di Mac saya, berpikir itu akan memperbaiki masalah saya, kemudian mengganti nama file dari productPageCtrl.jsmenjadi ProductPageCtrl.js. git statusmelihat file baru bernama ProductPageCtrl.jstetapi tidak berpikir yang productPageCtrl.jstelah dihapus. Ketika saya menambahkan file baru, melakukan, dan mendorong ke GitHub, repo GitHub sekarang berisi kedua file meskipun repo lokal saya (seharusnya up to date) hanya punya satu.
Mark Amery
5
@MarkAmery Kedengarannya sangat mirip bug di klien Git Anda. Apakah Anda mengajukan laporan?
Domi
24
@Domi ini bukan bug, ini perilaku yang diharapkan. Sebenarnya ini adalah ide yang buruk untuk mengatur ini menjadi salah pada sistem file yang tidak sensitif karena inilah yang terjadi. Alasan mengapa git tidak melihat file huruf kecil telah dihapus adalah bahwa sistem file tidak melaporkannya sebagai terhapus karena mengabaikan case sementara git tidak dengan opsi ini disetel ke false. Ini bukan berarti nama file tidak memiliki huruf kecil vs huruf besar pada ntfs atau gemuk, hanya saja pencarian nama file mengabaikan kasus.
ohcibi
15
@Domi git adalah cukup pintar. Itulah mengapa Anda tidak boleh menjadikan ini false pada sistem file case-insensitive. Gunakan git mvuntuk memindahkan file dan melihat bagaimana git mengelolanya. Jika Anda memindahkan file tanpa git, tidak ada yang bisa dilakukan git karena sistem file tidak mengatakan yang sebenarnya kepada git. Ini adalah masalah ntfs / fat / hfs dan sejenisnya dan bukan git / linux.
ohcibi
158

Menggunakan SourceTree, saya bisa melakukan ini semua dari UI

  1. Ganti nama FILE.ext menjadiwhatever.ext
  2. Panggung file itu
  3. Sekarang ganti nama whatever.ext menjadifile.ext
  4. Panggung lagi file itu

Agak membosankan, tetapi jika Anda hanya perlu melakukannya pada beberapa file, itu cukup cepat

CBarr
sumber
5
Sama dengan git bash
Alex78191
3
"Tahap file itu" adalah bagian penting - tidak ada jawaban lain di atas yang berfungsi untuk saya. Ini benar-benar bekerja dengan prompt perintah Windows biasa.
Vlad Sabev
1
Saya tidak menyadari ini berhasil melalui area pementasan. Tetapi dalam kasus saya, saya ingin memodifikasi nama folder serta beberapa file dalam folder tersebut. Jadi saya pertama-tama mengganti nama semua folder menjadi nama sementara. Mengkomit nama baru (semua file di dalam) dan file "dihapus". Git menandai mereka semua sebagai "diganti namanya". Kemudian ganti nama semua folder itu kembali ke versi case baru dan komit lagi. Akhirnya, gabungkan kedua komitmen itu. Tetapi berdasarkan apa yang Anda tulis, saya bisa melakukan semuanya melalui area sating secara langsung, tanpa membuat 2 commit + merge.
ThermoX
3
Bekerja juga dengan gitkraken pada nama folder.
Philippe Matray
Saya menulis Skrip Python 3 untuk melakukan pekerjaan yang membosankan ini: stackoverflow.com/a/58159822/4934640
pengguna
126

Inilah yang saya lakukan pada OS X:

git mv File file.tmp
git mv file.tmp file

Dua langkah karena kalau tidak saya mendapat kesalahan "file exist". Mungkin itu bisa dilakukan dalam satu langkah dengan menambahkan --cachedatau semacamnya.

Sijmen Mulder
sumber
21
seperti yang disarankan oleh jawaban teratas, -f(gaya) adalah bendera yang Anda cari
rperryng
5
@ rperryng - tidak, -fflag tidak membantu jika FS yang mendasari adalah case-sensitive. Namun, solusi dua langkah berhasil untuk saya
HEKTO
Menggunakan FS case-insensitive (di Mac) dan -fbekerja! Terima kasih atas tipnya
caesarsol
Ini juga berfungsi dengan folder di windows tanpa -fbendera.
nich
git -c "core.ignorecase=false" add .akan mempertimbangkan file yang kasusnya telah diubah untuk komit.
nietonfir
67

Terkadang berguna untuk sementara mengubah sensitivitas kasus Git:

Metode # 1 - Ubah sensitivitas case untuk satu perintah:

git -c core.ignorecase=true checkout mybranchuntuk mematikan sensitivitas huruf untuk satu checkoutperintah. Atau lebih umum: . (Kredit untuk VonC untuk menyarankan ini di komentar.)git -c core.ignorecase= <<true or false>> <<command>>

Metode # 2 - Ubah sensitivitas case untuk beberapa perintah:

Untuk mengubah pengaturan lebih lama (mis. Jika beberapa perintah harus dijalankan sebelum mengubahnya kembali):

  1. git config core.ignorecase(ini mengembalikan pengaturan saat ini, misalnya false).
  2. git config core.ignorecase <<true or false>> - atur pengaturan baru yang diinginkan.
  3. ... Jalankan beberapa perintah lain ...
  4. git config core.ignorecase <<false or true>> - atur nilai konfigurasi kembali ke pengaturan sebelumnya.
Steve Chambers
sumber
1
Kenapa tidak langsung git -c core.ignorecase=<true or false> checkout <<branch>>? Tidak ada yang mengatur ulang setelah.
VonC
2
Saya memiliki pengalaman aneh tentang core.ignorecase yang diusulkan bekerja ketika mengubah dari huruf kecil ke huruf besar, tetapi tidak untuk huruf besar menjadi huruf kecil. tampaknya satu-satunya solusi yang dapat diandalkan adalah berhenti menggunakan OS yang gagal mengenali kasus nama file.
aspiringGuru
Apakah ada alasan mengapa itu harus menjadi perubahan sementara? Apakah itu akan menimbulkan masalah jika saya membiarkan pengaturannya berubah menjadi case sensitif?
cytsunny
Ini mungkin tergantung pada beberapa faktor, khususnya apakah sistem file target peka huruf besar-kecil - lihat en.wikipedia.org/wiki/Case_sensitivity#In_filesystems . Perubahan sementara mungkin diperlukan jika sistem file penyebaran memiliki sensitivitas huruf yang berbeda dengan sistem file yang digunakan untuk pengembangan. Juga dalam kasus saya, saya bekerja di tim di mana setiap orang diharapkan memiliki pengaturan Git yang sama (yaitu case sensitif) jadi jika saya mematikannya itu perlu bersifat sementara.
Steve Chambers
44

Di bawah OSX, untuk menghindari masalah ini dan menghindari masalah lain dengan mengembangkan pada kasus-sensitif filesystem, Anda dapat menggunakan Disk Utility untuk membuat kasus sensitif drive virtual / disk image.

Jalankan utilitas disk, buat disk image baru, dan gunakan pengaturan berikut (atau ubah sesuka Anda, tetapi tetap perhatikan huruf besar-kecil):

Screenshot Utilitas Disk Mac

Pastikan untuk memberi tahu git bahwa ini ada pada kasus sensitif FS:

git config core.ignorecase false
pengguna1821510
sumber
15
Nah, nuklir menjalankan boot drive sepenuhnya case-sensitive pada OSX. Anda harus hidup tanpa aplikasi yang ditulis dengan buruk (ahem, Adobe), atau menjalankannya dengan VM kasus-bodoh mereka sendiri, tetapi itu sangat berharga jika Anda membuat kode terutama untuk sistem * nix.
Mike Marcacci
1
Ini adalah satu-satunya opsi yang berfungsi dengan baik. Saya sudah mencoba sisanya dan Anda berakhir dengan acar. Selesaikan masalah dengan benar dengan melakukan ini.
John Hunt
2
Perhatikan bahwa Disk Utility memiliki bug OS X 10.11 - Ini tidak akan membuat gambar case sensitif. Anda perlu menggunakan alat baris perintah hdiutil. apple.stackexchange.com/questions/217915/...
dellsala
7
Dengan APFS di High Sierra ini bahkan lebih mudah. Klik ikon drive dengan plus dan tambahkan volume case-sensitive tanpa batas ukuran. Itu hanya berbagi ruang dengan volume utama dan mount di / Volume / nama volume.
Michael Fox
21

Saya mencoba solusi berikut dari jawaban lain dan tidak berhasil:

Jika repositori Anda di-host dari jarak jauh (GitHub, GitLab, BitBucket), Anda dapat mengubah nama file asalnya (GitHub.com) dan memaksanya mengganti nama file dengan cara top-down.

Instruksi di bawah ini berkaitan dengan GitHub, namun ide umum di baliknya harus berlaku untuk platform hosting repositori jarak jauh. Ingatlah jenis file yang Anda coba ubah namanya, yaitu apakah itu tipe file yang dianggap GitHub dapat diedit (kode, teks, dll.) Atau tidak dapat diedit (gambar, biner, dll) di dalam browser.

  1. Kunjungi GitHub.com
  2. Arahkan ke repositori Anda di GitHub.com dan pilih cabang tempat Anda bekerja
  3. Dengan menggunakan alat navigasi file situs, navigasikan ke file yang ingin Anda ganti namanya
  4. Apakah GitHub memungkinkan Anda untuk mengedit file di dalam browser?
    • a.) Dapat diedit
      1. Klik ikon "Edit file ini" (sepertinya pensil)
      2. Ubah nama file dalam input teks nama file
    • b.) Tidak dapat diedit
      1. Buka tombol "Unduh" di tab baru dan simpan file ke komputer Anda
      2. Ganti nama file yang diunduh
      3. Pada tab sebelumnya di GitHub.com, klik ikon "Hapus file ini" (sepertinya tempat sampah)
      4. Pastikan branchnametombol radio "Komit langsung ke cabang" dipilih dan klik tombol "Komit perubahan"
      5. Dalam direktori yang sama di GitHub.com, klik tombol "Unggah file"
      6. Unggah file yang diganti nama dari komputer Anda
  5. Pastikan branchnametombol radio "Komit langsung ke cabang" dipilih dan klik tombol "Komit perubahan"
  6. Secara lokal, checkout / ambil / tarik cabang
  7. Selesai
gmeben
sumber
Saya berganti nama langsung di BitBucket dan berhasil. Terima kasih.
rsc
Senang mendengarnya. Teknik ini secara teoritis harus bekerja pada platform hosting repositori mana pun tetapi saya tertarik untuk mengetahui apakah ada yang tidak dapat digunakan.
gmeben
Tidak berfungsi untuk file yang tidak dapat diedit di browser, seperti gambar atau PDF; tidak ada opsi edit, jelas.
Abhijit Sarkar
@AbhijitSarkar Poin bagus. Saya memperbarui jawaban saya untuk kasus-kasus itu. Saya menguji dan memverifikasi instruksi ini berfungsi.
gmeben
Adakah yang bisa mengubah nama direktori dengan cara ini?
Solvitieg
21

Mirip dengan jawaban @ Sijmen, inilah yang bekerja untuk saya di OSX ketika mengganti nama direktori (terinspirasi oleh jawaban ini dari posting lain):

git mv CSS CSS2
git mv CSS2 css

Cukup melakukan git mv CSS cssmemberi kesalahan argumen yang tidak valid: fatal: renaming '/static/CSS' failed: Invalid argumentmungkin karena sistem file OSX adalah case-sensitive

ps BTW jika Anda menggunakan Django, collectstatic juga tidak akan mengenali perbedaan kasus dan Anda harus melakukan di atas, secara manual, di direktori root statis juga

Anupam
sumber
19

1) ganti nama file Name.jpgmenjadiname1.jpg

2) melakukan file yang dihapus Name.jpg

3) ganti nama file name1.jpgmenjadiname.jpg

4) mengubah file yang ditambahkan name.jpgke komit sebelumnya

git add
git commit --amend
Razon
sumber
2
Saya mendapatkan ini fatal: bad source, source=name1.jpg, destination=name.jpgpada langkah 3. Apakah Anda punya saran? Thx
Anthony Kong
1
Anda tidak dapat melakukan komit, adil git add.
Alex78191
Terlihat sangat berantakan, bukan? Atau tambalan monyet.
jeromej
18

Saya menggunakan langkah-langkah berikut:

git rm -r --cached .
git add --all .
git commit -a -m "Versioning untracked files"
git push origin master

Bagi saya adalah solusi sederhana

andrewvergel
sumber
Ini solusinya. Dan tidak seperti jawaban lain, ia bekerja dengan baik ketika Anda melakukan perubahan nama batch. Di glamourphilly.org, kami harus mengubah setiap .Jpg menjadi .jpg. Di Finder Anda dapat melakukan perubahan nama batch seperti itu dan jawaban ini memungkinkan Anda memeriksanya.
William Entriken
11

Kita dapat menggunakan perintah git mv. Contoh di bawah ini, jika kita mengganti nama file abcDEF.js menjadi abcdef.js maka kita dapat menjalankan perintah berikut dari terminal

git mv -f .\abcDEF.js  .\abcdef.js
Sandeep Shukla
sumber
8

Mac OSX High Sierra 10.13 memperbaikinya. Buat saja partisi APFS virtual untuk proyek git Anda, secara default ia tidak memiliki batas ukuran dan tidak membutuhkan ruang.

  1. Dalam Disk Utility, klik tombol + ketika disk Container dipilih
  2. Pilih APFS (Case-Sensitive) dalam format
  3. Beri nama Sensitive
  4. Keuntungan
  5. Opsional: Buat folder dengan nama Sensitive gitdanln -s /Volumes/Sensitive/git /Users/johndoe/git

Drive Anda akan masuk /Volumes/Sensitive/

masukkan deskripsi gambar di sini

Bagaimana cara saya melakukan hanya perubahan nama file case-sensitive dalam Git?

Ray Foss
sumber
Saya suka saran ini, itu menyelesaikan masalah dengan elegan dan tanpa rasa sakit tanpa menggunakan solusi yang buruk. Terima kasih!
Phil Gleghorn
4

Saya telah menghadapi masalah ini beberapa kali di MacOS. Git peka huruf besar-kecil tetapi Mac hanya melindungi huruf.

Seseorang mengkomit file: Foobar.javadan setelah beberapa hari memutuskan untuk mengganti namanya FooBar.java. Ketika Anda menarik kode terbaru itu gagalThe following untracked working tree files would be overwritten by checkout...

Satu-satunya cara yang dapat diandalkan yang pernah saya lihat yang memperbaiki ini adalah:

  1. git rm Foobar.java
  2. Komit dengan pesan yang tidak bisa Anda lewatkan git commit -m 'TEMP COMMIT!!'
  3. Tarik
  4. Ini akan memunculkan konflik yang memaksa Anda untuk menggabungkan konflik - karena perubahan Anda menghapusnya, tetapi perubahan lainnya berganti nama (karenanya masalahnya)
    1. Terima perubahan Anda yang merupakan 'penghapusan'
    2. git rebase --continue
  5. Sekarang menjatuhkan solusi Anda git rebase -i HEAD~2dan dropyangTEMP COMMIT!!
  6. Konfirmasikan bahwa file tersebut sekarang dipanggil FooBar.java
Ashwin Jayaprakash
sumber
3

Ketika Anda telah melakukan banyak penggantian nama file dan beberapa di antaranya hanya merupakan penggantian casing, sulit untuk mengingat yang mana. secara manual "git pindahkan" file tersebut dapat bekerja. Jadi apa yang akan saya lakukan selama tugas perubahan nama file adalah:

  1. hapus semua file dan folder non-git ke folder / repositori lain.
  2. komit folder git kosong saat ini (ini akan ditampilkan ketika semua file dihapus.)
  3. tambahkan semua file kembali ke folder git asli / repositori.
  4. komit folder git yang tidak kosong saat ini.

Ini akan memperbaiki semua masalah kasing tanpa mencoba mencari tahu file atau folder mana yang Anda ganti namanya.

Ricardo Virtudazo Jr
sumber
Mengapa tidak git commmit --amenddi dalam paragraf 4? Jika tidak, akan ada komitmen ekstra dengan penghapusan semua file. Atau Anda bisa menggunakannya git rebase -idengan squash.
Alex78191
1

Jika tidak ada yang berhasil, gunakan nama file git rm untuk menghapus file dari disk dan menambahkannya kembali.

Gopal Pandey
sumber
0

Saya mengambil jawaban @CBarr dan menulis Skrip Python 3 untuk melakukannya dengan daftar file:

#!/usr/bin/env python3
# -*- coding: UTF-8 -*-

import os
import shlex
import subprocess

def run_command(absolute_path, command_name):
    print( "Running", command_name, absolute_path )

    command = shlex.split( command_name )
    command_line_interface = subprocess.Popen( 
          command, stdout=subprocess.PIPE, cwd=absolute_path )

    output = command_line_interface.communicate()[0]
    print( output )

    if command_line_interface.returncode != 0:
        raise RuntimeError( "A process exited with the error '%s'..." % ( 
              command_line_interface.returncode ) )

def main():
    FILENAMES_MAPPING = \
    [
        (r"F:\\SublimeText\\Data", r"README.MD", r"README.md"),
        (r"F:\\SublimeText\\Data\\Packages\\Alignment", r"readme.md", r"README.md"),
        (r"F:\\SublimeText\\Data\\Packages\\AmxxEditor", r"README.MD", r"README.md"),
    ]

    for absolute_path, oldname, newname in FILENAMES_MAPPING:
        run_command( absolute_path, "git mv '%s' '%s1'" % ( oldname, newname ) )
        run_command( absolute_path, "git add '%s1'" % ( newname ) )
        run_command( absolute_path, 
             "git commit -m 'Normalized the \'%s\' with case-sensitive name'" % (
              newname ) )

        run_command( absolute_path, "git mv '%s1' '%s'" % ( newname, newname ) )
        run_command( absolute_path, "git add '%s'" % ( newname ) )
        run_command( absolute_path, "git commit --amend --no-edit" )

if __name__ == "__main__":
    main()
pengguna
sumber