git mv und nur den Fall des Verzeichnisses ändern

259

Während ich eine ähnliche Frage fand, fand ich keine Antwort auf mein Problem

Wenn ich versuche, das Verzeichnis von FOO in foo umzubenennen, git mv FOO foobekomme ich

fatal: renaming 'FOO' failed: Invalid argument

OK. Also versuche ich esgit mv FOO foo2 && git mv foo2 foo

Aber wenn ich versuche, mich zu verpflichten, git commit .bekomme ich

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

Wenn ich das Verzeichnis über git add foonichts hinzufüge, ändert sich nichts und git commit .ich erhalte wieder die gleiche Nachricht.

Was mache ich falsch? Ich dachte, ich verwende ein System mit Groß- und Kleinschreibung (OSX). Warum kann ich das Verzeichnis nicht einfach umbenennen?

oschrenk
quelle
10
Das Dateisystem von OS X unterscheidet nicht zwischen Groß- und Kleinschreibung.
Mipadi
2
@mipadi Es kann im Groß- / Kleinschreibung-Modus betrieben werden, dies ist jedoch normalerweise standardmäßig deaktiviert.
GordonM
1
Diese Frage und ihre Antworten sind auch in Windows nützlich. Betrachten Sie das Deaktivieren von "osx"
Barett
1
Siehe stackoverflow.com/a/24979063/6309 : Seit Git 2.0.1 git mvfunktioniert ein einfaches .
VonC
Unter Windows können Sie die reguläre Version verwenden, git mv foo Foowenn Sie eine Cygwin-Shell verwenden.
Andrew Scott

Antworten:

409

Sie befinden sich in einer Umgebung, in der die Groß- und Kleinschreibung nicht berücksichtigt wird. Darüber hinaus -Akümmert sich das Hinzufügen ohne das nicht um die entfernte Seite des, mvwie Git es versteht. Warnung! Stellen Sie sicher, dass keine anderen Änderungen oder nicht verfolgten Dateien vorhanden sind, wenn Sie dies tun. Andernfalls werden sie im Rahmen dieser Änderung festgeschrieben! git stash -uMach das zuerst und dann git stash popdanach. Weiter: Um dies zu umgehen, gehen Sie wie folgt vor:

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

Auf diese Weise können Sie das Arbeitsverzeichnis ändern, die beiden Festschreibungen festschreiben und anschließend reduzieren. Sie können die Datei einfach in den Index verschieben, aber für jemanden, der neu in Git ist, ist es möglicherweise nicht explizit genug, was passiert. Die kürzere Version ist

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

Wie in einem der Kommentare vorgeschlagen, können Sie auch eine interaktive Neufestsetzung durchführen ( git rebase -i HEAD~5wenn der falsche Fall vor 5 Commits eingeführt wurde), um den Fall dort zu beheben und den falschen Fall überhaupt nicht im Verlauf anzuzeigen . Sie müssen vorsichtig sein, wenn Sie dies tun, da die Commit-Hashes von da an anders sein werden und andere ihre Arbeit mit der jüngsten Vergangenheit des Zweigs neu zusammenführen oder neu zusammenführen müssen.

Dies hängt mit der Korrektur des Dateinamens zusammen: Bei Git wird nicht zwischen Groß- und Kleinschreibung unterschieden?

Adam Dymitruk
quelle
1
Vielen Dank. Das hat mich verrückt gemacht. Ich wusste nichts über die Option -A oder --amend.
Oschrenk
7
Seien Sie vorsichtig mit dem -A, da es rekursiv alle Inhalte in Ihrem aktuellen Verzeichnis hinzufügt, einschließlich nicht verfolgter Inhalte. Könnte besser sein, nur git add foo2.
rich.e
2
Das ist richtig. Sie müssen jedoch sowohl die Entfernung von foo2 als auch die Zugabe von FOO separat durchführen. -Akümmert sich um beides. Umgekehrt für den ersten Schritt. Ich werde die Warnung hinzufügen. Vielen Dank!
Adam Dymitruk
Sie können Ihren Verlauf auch mit einer interaktiven Rebase bereinigen git rebase -i HEAD~2. Hinweis: Um dies zu vereinfachen, legen Sie die endgültige Nachricht in Ihrem ersten Commit fest und korrigieren Sie die zweite.
Alex B.
5
Ich hatte Erfolg mit git mv foo foo2; git mv foo2 FOO; Git Commit
Chris
146

Sie möchten die Option core.ignorecaseauf false setzen, wodurch Git auf Dateisysteme achtet, die dies nicht nativ unterstützen. So aktivieren Sie in Ihrem Repo:

$ git config core.ignorecase false

Dann können Sie die Datei mit umbenennen git mvund es wird wie erwartet funktionieren.

Mipadi
quelle
1
Ich denke, dass dies an anderer Stelle unerwünschte Auswirkungen haben kann. Bei Systemen, bei denen die Groß- und Kleinschreibung nicht berücksichtigt wird, sollte Git denken, dass es sich um dasselbe Verzeichnis handelt.
Adam Dymitruk
2
Ich habe die Option zu meiner globalen Konfiguration hinzugefügt, aber es hat nicht geholfen
oschrenk
3
Ich sehe ein seltsames Verhalten bei der Verwendung mit OSX. hrm I modified a file that doesn't exist.. hrm error: The following untracked working tree files would be overwritten by checkout:aber ... diese Dateien existieren nicht.
Skylar Saveland
Genau das habe ich gesucht. Ich verwende CentOS 5.6 und es hat den Fallwechsel nicht aufgegriffen.
Crmpicco
5
Das funktioniert nicht! In Git 1.8.3 behandelt Git die umbenannte Datei als neue Datei, anstatt sie zu entfernen + hinzuzufügen. Wenn Sie dies festlegen, bleiben im Repository zwei gleiche Dateien, z. B. foo und FOO, vorhanden! Aber beim Auschecken erscheint nur eine Datei (aber ein Fall kann den anderen dominieren)
Johnny Wong
68

Ich konnte dies mithilfe von Git 1.7.7 mithilfe eines temporären Dateinamens beheben:

$ git mv improper_Case improve_case2
$ git mv improve_case2 improve_case
$ git commit -m "<your message>"
mgadda
quelle
Interessant. Vielleicht hat GIT seitdem etwas verbessert. Wenn ich erneut auf dieses Problem stoße, versuche ich es erneut.
Oschrenk
viel einfacher auf diese Weise
mehr
Arbeitete für mich unter macOS.
Mr_Pouet
14

( git mv-freie Variante.)

Ich bin auf dieses Problem in Git unter Mac OS X 10.9 gestoßen. Ich habe es wie folgt gelöst:

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

Dadurch wird das Verzeichnis zum Löschen in Git freigegeben, es werden jedoch keine physischen Dateien entfernt ( --cached). Dadurch wird auch das Verzeichnis mit der richtigen Groß- und Kleinschreibung in nicht verfolgten Dateien angezeigt.

So können Sie Folgendes tun:

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

Git erkennt dann, dass Sie die Dateien umbenannt haben, und wenn Sie dies tun git status, sollten Sie eine Reihe von renamed:Zeilen sehen. Überprüfen Sie sie und stellen Sie sicher, dass sie korrekt aussehen. In diesem Fall können Sie die Änderungen normal übernehmen.

wizonesolutions
quelle
Ich habe festgestellt, dass der mvBefehl nicht funktioniert hat, um das Verzeichnis tatsächlich umzubenennen. Ich musste es im Finder umbenennen. Ansonsten funktioniert dieses Update einwandfrei.
Adam S
9

Dies ist eine schnelle und fehlerfreie Lösung:

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

Warnung! Benennen Sie immer alle Dateien im umbenannten Ordner um (verwenden /*).

Benennen Sie einzelne Dateien nicht um. Dies führt zu einem Fehler, der in dieser Antwort beschrieben wird .

Wenn Sie zuerst das Ergebnis sehen möchten, verwenden Sie -n:

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

Nachdem Sie eine mv:

  1. Änderungen festschreiben
  2. Kasse zu einer anderen Revision
  3. Kasse zurück.

Jetzt sollte Git den Ordner BEIDE in seinen internen Dateien und im Dateisystem umbenannt haben.

Nick Volynkin
quelle
Ist dies nur für Git 2.0.1, wie ich in den obigen Kommentaren erwähnt habe? (unter Bezugnahme auf stackoverflow.com/a/24979063/6309 )
VonC
8

Erzwinge es mit der Option -f:

git mv -f FOO foo
konyak
quelle
Arbeite nicht für mich. Meine Einstellung ist .git / config's "ignorecase = true". Die Umbenennung kann auf diese Weise nicht im Staging-Bereich bereitgestellt werden. (Git Version 1.8.3.msysgit.0) Die Lösung von Adam Dymitruk ist die einzig richtige Antwort.
Johnny Wong
@ JohnnyWong ändern Sie Ihre Einstellung auf false, es hat bei mir funktioniert
Inder Kumar Rathore
Wird dies dann auf allen Computern anderer Benutzer aktualisiert, wenn diese ziehen, auch wenn ihr Computer so eingestellt ist, dass Groß- und Kleinschreibung ignoriert wird?
Bryce
@Bryce Nein, Sie müssen die Änderungen festschreiben und in das zentrale Repo übertragen, bevor andere Benutzer die Änderungen abrufen können.
Konyak
3

Ich hatte ein verwandtes Problem.

Ein Ordner mit dem Namen 'Pro' (zuerst erstellt) und ein anderer 'Pro' (versehentlich erstellt). Auf dem Mac ist es dasselbe, aber je nach Git unterschiedlich.

$ git config core.ignorecase false

Die Git-Konfiguration benannte die Dateien in den richtigen Ordner um (danke) und erstellte auch Geisterdateien in 'pro' (Nein !!). Ich konnte dem Track keine Änderungen an Geisterdateien hinzufügen und andere Zweige nicht auschecken, es sei denn, ich habe diese Dateien bei mir, und ich konnte sie auch nicht irgendwie zurücksetzen.

Stattdessen habe ich es getan

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

Um es besonders sicher zu machen, habe ich es in einem separaten Fix-Zweig gemacht und dann wieder zum Hauptzweig zusammengeführt

Kann ein Guru für das von erstellte Ghost-File-Problem erklären, wie und warum? Danke im Voraus.

Seeliang
quelle
2

Sie verwenden in OS X kein Dateisystem, bei dem zwischen Groß- und Kleinschreibung unterschieden wird, es sei denn, Sie wählen dies explizit aus. Bei HFS + kann zwischen Groß- und Kleinschreibung unterschieden werden, bei der Standardeinstellung wird jedoch zwischen Groß- und Kleinschreibung unterschieden.

Nicholas Knight
quelle
4
Die Verwendung des Dateisystems mit Groß- und Kleinschreibung unter OS X ist keine gute Idee. Viele Apps funktionieren NICHT richtig, ich habe daraus gelernt. Ein besonderes Problem ist, dass Adobe Photoshop die Installation ablehnt und angibt, dass das Dateisystem, bei dem zwischen Groß- und Kleinschreibung unterschieden wird, nicht unterstützt wird.
Jpswain
1

Hier ist eine wirklich einfache Lösung für alle Gitfoo auf dieser Seite.

  1. Kopieren Sie die Dateien manuell aus Ihrem Projekt.
  2. git rm alle Dateien.
  3. Git Commit wie gewohnt.
  4. Fügen Sie die Dateien manuell wieder hinzu.
  5. git füge alle Dateien hinzu.
  6. Git Commit wie gewohnt.
  7. profitieren.
Fragen Sie Designer
quelle
1
Dies funktioniert lokal, aber wenn jemand anderes zieht, ändert dies nichts an seinem Fall.
Jason
Vielen Dank dafür, dass Sie mir geholfen haben, die doppelten Einträge in git in verschiedenen Fällen zu beheben. Ich habe eine Variante davon verwendet. Einfach den übergeordneten Ordner umbenannt. Habe ein Commit gemacht. Dann umbenannter übergeordneter Ordner zurück zum Original. Und habe ein zweites Commit gemacht. Jetzt sind die älteren Einträge mit dem anderen Fall weg.
Dreamerkumar
0

Wenn Sie die Antwort von Adam Dymitruk verbessern (dumm, dass SO seine Antwort nicht kommentieren lässt), werden mit "git mv" automatisch genau die verschobenen Dateien bereitgestellt. Es ist kein Verstauen erforderlich und das riskante "git add -A" kann vermieden werden:

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'.";
Rainer Blome
quelle
0

Dies hat bei Windows unter Windows hervorragend funktioniert. Benutzte Powershell mit folgendem:

  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. (Optional) git push

Dank Adams Antwort oben.

Tony
quelle