git mv và chỉ thay đổi trường hợp của thư mục


259

Trong khi tôi tìm thấy câu hỏi tương tự, tôi đã không tìm thấy câu trả lời cho vấn đề của mình

Khi tôi cố đổi tên thư mục từ FOO thành foo thông qua git mv FOO footôi nhận được

fatal: renaming 'FOO' failed: Invalid argument

ĐỒNG Ý. Vì vậy tôi cố gắnggit mv FOO foo2 && git mv foo2 foo

Nhưng khi tôi cố gắng cam kết thông qua git commit .tôi nhận được

# 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)

Khi tôi thêm thư mục thông qua git add fookhông có gì thay đổi và git commit .đưa lại cho tôi cùng một tin nhắn.

Tôi đang làm gì sai? Tôi nghĩ rằng tôi đang sử dụng một hệ thống phân biệt chữ hoa chữ thường (OSX) tại sao tôi không thể đổi tên thư mục?


10
Hệ thống tệp của OS X không phân biệt chữ hoa chữ thường.
mipadi

2
@mipadi Nó có thể hoạt động ở chế độ phân biệt chữ hoa chữ thường nhưng thường bị tắt theo mặc định.
GordonM

1
Câu hỏi này và câu trả lời của nó cũng hữu ích trong Windows. Xem xét bỏ chặn "osx"
Barett

1
Xem stackoverflow.com/a/24979063/6309 : kể từ git 2.0.1, một git mvcông việc đơn giản .
VonC

Trên windows bạn có thể sử dụng thường xuyên git mv foo Foonếu bạn sử dụng vỏ cygwin.
Andrew Scott

Câu trả lời:


409

Bạn đang ở trong một trường hợp không nhạy cảm. Hơn nữa, việc thêm vào -Asẽ không quan tâm đến khía cạnh loại bỏ của mvGit vì nó hiểu nó. Cảnh báo! Đảm bảo rằng không có thay đổi nào khác hoặc các tệp không bị theo dõi khi bạn thực hiện việc này hoặc chúng sẽ được cam kết là một phần của thay đổi này! git stash -uđầu tiên, làm điều này và sau đó git stash popsau. Tiếp tục: Để giải quyết vấn đề này, hãy làm như sau:

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

Đó là cách rút ra để thay đổi thư mục làm việc, cam kết và sau đó thu gọn 2 cam kết. Bạn chỉ có thể di chuyển tệp trong chỉ mục, nhưng với người mới biết về git, nó có thể không đủ rõ ràng về những gì đang xảy ra. Phiên bản ngắn hơn là

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

Như được đề xuất trong một trong các ý kiến, bạn cũng có thể thực hiện một rebase tương tác ( git rebase -i HEAD~5nếu trường hợp sai được đưa ra 5 lần xác nhận trước đó) để khắc phục trường hợp đó và không có trường hợp sai xuất hiện ở bất kỳ đâu trong lịch sử. Bạn phải cẩn thận nếu bạn làm điều này vì các băm cam kết từ đó trở đi sẽ khác và những người khác sẽ phải khởi động lại hoặc hợp nhất lại công việc của họ với quá khứ gần đây của chi nhánh.

Điều này có liên quan đến việc sửa tên của tệp: git không phân biệt chữ hoa chữ thường?


1
Cảm ơn. Điều này đã khiến tôi phát điên. Tôi không biết về tùy chọn -A hoặc --amend.
oschrenk

7
Cẩn thận với -A, vì nó sẽ thêm đệ quy tất cả nội dung trong thư mục hiện tại của bạn, bao gồm cả những thứ chưa được theo dõi. Có thể tốt hơn để chỉ git add foo2.
giàu.e

2
Đúng rồi. Tuy nhiên, bạn sẽ cần phải loại bỏ cả foo2 cũng như bổ sung FOO riêng. -Achăm sóc cả hai. Ngược lại cho bước đầu tiên. Tôi sẽ thêm cảnh báo. Cảm ơn!
Adam Dymitruk

Bạn cũng có thể làm sạch lịch sử của mình với một rebase tương tác git rebase -i HEAD~2. Lưu ý: Để đơn giản hóa việc này, hãy đặt thông báo cuối cùng trong cam kết đầu tiên của bạn và sửa lỗi thứ hai.
Alex B.

5
Tôi đã thành công với git mv foo foo2; git mv foo2 FOO; cam kết git
Chris

146

Bạn muốn đặt tùy chọn core.ignorecasethành false, điều này sẽ khiến Git chú ý đến trường hợp trên các hệ thống tệp không hỗ trợ nó. Để kích hoạt trong repo của bạn:

$ git config core.ignorecase false

Sau đó, bạn có thể đổi tên tệp git mvvà nó sẽ hoạt động như mong đợi.


1
Tôi nghĩ rằng điều này có thể có tác dụng không mong muốn ở nơi khác. Các hệ thống không nhạy cảm nên để Git nghĩ rằng đó là cùng một dir.
Adam Dymitruk

2
Tôi đã thêm tùy chọn vào cấu hình toàn cầu của mình nhưng không được
oschrenk

3
Tôi thấy một số hành vi kỳ lạ khi sử dụng điều này với OSX. hrm I modified a file that doesn't exist.. hrm error: The following untracked working tree files would be overwritten by checkout:nhưng ... những tập tin đó không tồn tại.
Skylar Saveland

Đây chính xác là những gì tôi đang tìm kiếm. Tôi đang chạy CentOS 5.6 và nó không nhận được sự thay đổi của vỏ máy.
crmpicco

5
Điều này không hiệu quả! Trên Git 1.8.3, Git sẽ coi tệp đã đổi tên thành tệp mới, thay vì xóa + thêm. Cam kết như vậy sẽ để lại kho lưu trữ với hai tệp giống nhau, ví dụ foo và FOO đều tồn tại! Nhưng khi thanh toán chỉ có một tệp xuất hiện (nhưng một trường hợp có thể chiếm ưu thế so với trường hợp khác)
Johnny Wong

68

Tôi đã có thể giải quyết vấn đề này bằng cách sử dụng git 1.7.7 bằng cách sử dụng tên tệp tạm thời:

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

Hấp dẫn. Có lẽ GIT đã cải thiện một cái gì đó kể từ đó. Khi tôi vấp phải vấn đề này một lần nữa, tôi sẽ thử lại lần nữa.
oschrenk

Làm theo cách này dễ dàng hơn nhiều
olore

Làm việc cho tôi trên macOS.
Mr_Pouet

14

( git mvbiến thể miễn phí.)

Tôi gặp vấn đề này trong Git trên Mac OS X 10.9. Tôi đã giải quyết nó như sau:

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

Đó là giai đoạn thư mục để xóa trong Git nhưng thực tế không xóa bất kỳ tệp vật lý nào ( --cached). Điều này cũng làm cho thư mục, bây giờ với trường hợp thích hợp, hiển thị trong các tệp không bị theo dõi.

Vì vậy, bạn có thể làm điều này:

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

Git sau đó sẽ nhận ra rằng bạn đã đổi tên các tệp và khi bạn thực hiện, git statusbạn sẽ thấy một số renamed:dòng. Kiểm tra chúng và đảm bảo chúng trông chính xác, và nếu vậy, bạn có thể cam kết thay đổi bình thường.


Tôi thấy rằng mvlệnh không hoạt động để thực sự đổi tên thư mục; Tôi đã phải đổi tên nó trong Finder. Khác hơn là sửa chữa này hoạt động hoàn hảo.
Adam S

9

Đây là một giải pháp nhanh chóng và an toàn cho lỗi:

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

Cảnh báo! Luôn đổi tên tất cả các tệp trong thư mục được đổi tên (sử dụng /*).

Không đổi tên tập tin duy nhất. Điều này dẫn đến một lỗi, được mô tả trong câu trả lời này .

Nếu trước tiên bạn muốn xem kết quả trước, hãy sử dụng -n:

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

Sau khi bạn thực hiện mv:

  1. Cam kết thay đổi
  2. Thanh toán cho bất kỳ sửa đổi nào khác
  3. Thanh toán lại.

Bây giờ Git nên đổi tên thư mục CẢ HAI trong các tệp bên trong và trong hệ thống tệp.


Đây có phải chỉ dành cho Git 2.0.1 như tôi đã đề cập trong các câu hỏi bình luận ở trên không? (tham khảo stackoverflow.com/a/24979063/6309 )
VonC

8

Buộc nó với tùy chọn -f:

git mv -f FOO foo

Không làm việc cho tôi. Cài đặt của tôi là "ignorecase = true" .git / config. Việc đổi tên không thể được dàn dựng trong khu vực dàn dựng bằng cách này. (Phiên bản Git 1.8.3.msysgit.0) Giải pháp của Adam Dymitruk là câu trả lời đúng duy nhất.
Johnny Wong

@JohnnyWong thay đổi cài đặt của bạn thành false, nó hoạt động với tôi
Inder Kumar Rathore

Điều này sau đó sẽ cập nhật trên tất cả các máy tính của người dùng khác nếu họ kéo, ngay cả khi máy tính của họ được đặt để bỏ qua trường hợp?
Bryce

@Bryce Không, bạn sẽ cần phải thực hiện các thay đổi và đẩy chúng vào repo trung tâm trước khi những người dùng khác có thể thực hiện các thay đổi.
konyak

3

Tôi đã có một vấn đề liên quan.

Một thư mục có tên 'Pro' (được tạo trước) và một 'pro' khác (được tạo do nhầm lẫn). Trong Mac, đó là điều tương tự, nhưng khác nhau theo git.

$ git config core.ignorecase false

cấu hình git đổi tên các tệp thành thư mục bên phải (cảm ơn) và cũng tạo các tệp ma trong 'pro' (Không !!). Tôi không thể thêm các thay đổi tệp ma vào bản nhạc và tôi không thể kiểm tra các chi nhánh khác trừ khi mang theo những tệp đó bên mình và tôi cũng không thể thiết lập lại bằng cách nào đó.

Thay vào đó, tôi đã làm

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

Để làm cho nó an toàn hơn, tôi đã thực hiện nó trong một nhánh sửa lỗi riêng biệt, và sau đó tôi đã hợp nhất trở lại nhánh chính

Đối với vấn đề tập tin ma được tạo bởi, bất kỳ guru nào có thể giải thích Làm thế nào và tại sao? Cảm ơn trước.


2

Bạn không sử dụng hệ thống tệp phân biệt chữ hoa chữ thường trong OS X trừ khi bạn chọn rõ ràng như vậy. HFS + có thể phân biệt chữ hoa chữ thường, nhưng mặc định là không phân biệt chữ hoa chữ thường.


4
Sử dụng hệ thống tệp phân biệt chữ hoa chữ thường trên OS X không phải là ý kiến ​​hay. Rất nhiều ứng dụng KHÔNG hoạt động chính xác, tôi đã học được từ việc thử này. Một vấn đề cụ thể là Adobe Photoshop sẽ từ chối cài đặt nói rằng hệ thống tệp phân biệt chữ hoa chữ thường không được hỗ trợ.
jpswain

1

Đây là một giải pháp thực sự đơn giản xung quanh tất cả các gitfoo trên trang này.

  1. Sao chép các tập tin ra khỏi dự án của bạn bằng tay.
  2. git rm tất cả các tập tin.
  3. git cam kết như bình thường.
  4. thêm các tập tin trở lại bằng tay.
  5. git thêm tất cả các tập tin.
  6. git cam kết như bình thường.
  7. lợi nhuận.

1
Điều này hoạt động tại địa phương, nhưng nếu người khác thực hiện việc đó sẽ không thay đổi trường hợp của họ.
Jason

Cảm ơn vì điều này đã giúp tôi sửa các mục kép trong git với các trường hợp khác nhau. Tôi đã sử dụng một biến thể của điều này. Chỉ cần đổi tên thư mục cha. Đã cam kết. Sau đó đổi tên thư mục cha trở lại ban đầu. Và đã làm một cam kết thứ hai. Bây giờ các mục cũ hơn với các trường hợp khác nhau đã biến mất.
dreamerkumar

0

Cải thiện câu trả lời của Adam Dymitruk (ngớ ngẩn rằng SO không cho phép tôi nhận xét câu trả lời của anh ấy), sử dụng "git mv" sẽ tự động tạo giai đoạn chính xác cho các tệp được di chuyển. Không cần stashing và có thể tránh được "git add -A" đầy rủi ro:

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

Điều này làm việc rất tốt cho tôi trên Windows. Quyền hạn được sử dụng với những điều sau đây:

  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. (không bắt buộc) git push

Nhờ câu trả lời của Adam ở trên.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.