Ich habe gelesen, dass Sie beim Umbenennen von Dateien in Git alle Änderungen festschreiben, Ihre Umbenennung durchführen und dann Ihre umbenannte Datei bereitstellen sollten. Git erkennt die Datei anhand des Inhalts, anstatt sie als neue nicht verfolgte Datei zu betrachten, und behält den Änderungsverlauf bei.
Als ich heute Abend genau das tat, kehrte ich jedoch zurück git mv
.
> $ git status
# On branch master
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
# modified: index.html
#
Benennen Sie mein Stylesheet im Finder von iphone.css
nach ummobile.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
Git glaubt nun, ich hätte eine CSS-Datei gelöscht und eine neue hinzugefügt. Nicht was ich will, lass uns die Umbenennung rückgängig machen und git die Arbeit machen lassen.
> $ git reset HEAD .
Unstaged changes after reset:
M css/iphone.css
M index.html
Zurück zu meinem Ausgangspunkt.
> $ git status
# On branch master
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
# modified: index.html
#
Verwenden wir git mv
stattdessen.
> $ 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
#
Sieht so aus, als wären wir gut. Warum hat git die Umbenennung beim ersten Mal nicht erkannt, als ich Finder verwendet habe?
add+rm
odermv
- es wird das gleiche Ergebnis erzielt. Git verwendet dann die Umbenennungs- / Kopiererkennung, um Sie darüber zu informieren, dass es sich um eine Umbenennung handelt. Die von Ihnen angegebene Quelle ist ebenfalls ungenau. Es ist wirklich egal, ob Sie im selben Commit + umbenennen oder nicht. Wenn Sie einen Unterschied zwischen Ändern und Umbenennen vornehmen, wird dies bei der Umbenennungserkennung als Umbenennen + Ändern angezeigt. Wenn es sich bei der Änderung um eine vollständige Umschreibung handelt, wird sie als hinzugefügt und gelöscht angezeigt - unabhängig davon, wie Sie sie ausgeführt haben es.git mv old new
aktualisiert den Index automatisch. Wenn Sie außerhalb von Git umbenennen, müssen Sie dasgit add new
undgit rm old
die Änderungen am Index vornehmen. Sobald Sie dies getan haben, wird diesgit status
wie erwartet funktionieren.public_html
Verzeichnis verschoben , die in Git verfolgt werden. Nach der Ausführunggit add .
undgit commit
zeigte es immer noch eine Reihe von 'gelöschten' Dateien ingit status
. Ich habe a ausgeführtgit commit -a
und die Löschungen wurden festgeschrieben, aber jetzt habe ich keinen Verlauf für die Dateien, in denenpublic_html
jetzt leben . Dieser Arbeitsablauf ist nicht so reibungslos, wie ich es gerne hätte.Antworten:
Für
git mv
die Handbuchseite heißt esSie müssen den Index also zunächst selbst aktualisieren (mithilfe von
git add mobile.css
). Es werden jedochgit status
weiterhin zwei verschiedene Dateien angezeigtSie können eine andere Ausgabe erhalten, indem Sie ausführen
git commit --dry-run -a
, was zu dem führt, was Sie erwarten:Ich kann Ihnen nicht genau sagen, warum wir diese Unterschiede zwischen
git status
und sehengit commit --dry-run -a
, aber hier ist ein Hinweis von Linus :A
dry-run
verwendet die realen Umbenennungsmechanismen, während a diesgit status
wahrscheinlich nicht tut.quelle
git add mobile.css
. Ohne siegit status -a
hätte nur das Entfernen der zuvor verfolgteniphone.css
Datei "gesehen", aber die neue, nicht verfolgte Datei nicht berührtmobile.css
. Auchgit status -a
ist ungültig mit Git 1.7.0 und höher. "" Git status "ist nicht mehr" git commit --dry-run "." in kernel.org/pub/software/scm/git/docs/RelNotes-1.7.0.txt . Verwendengit commit --dry-run -a
Sie diese Option, wenn Sie diese Funktionalität wünschen. Wie andere gesagt haben, aktualisieren Sie einfach den Index undgit status
es funktioniert genau so, wie es das OP erwartet.git commit
Datei ausführen, wird die umbenannte Datei nicht festgeschrieben, und der Arbeitsbaum ist immer noch derselbe.git commit -a
besiegt so ziemlich jeden Aspekt des Workflow- / Denkmodells von git - jede Änderung wird begangen. Was ist, wenn Sie die Datei nur umbenennen möchten, aber Änderungenindex.html
in einem anderen Commit festschreiben möchten ?mobile.css
was ich hätte erwähnen sollen. Aber das ist der Punkt meiner Antwort: Die Manpage sagt das,the index is updated
wenn Sie verwendengit-mv
. Vielen Dank für diestatus -a
Klarstellung, ich habe Git 1.6.4git status
die Umbenennung nicht entdeckte. Das Ausführengit commit -a --dry-run
nach dem Hinzufügen meiner "neuen" Dateien zeigte die Umbenennungen und gab mir schließlich das Vertrauen, mich zu verpflichten!git status
verhält es sich jetzt wiegit commit
.Sie müssen die beiden geänderten Dateien zum Index hinzufügen, bevor git sie als Verschiebung erkennt.
Der einzige Unterschied zwischen
mv old new
undgit mv old new
besteht darin, dass der Git MV auch die Dateien zum Index hinzufügt.mv old new
danngit add -A
hätte es auch geklappt.Beachten Sie, dass Sie nicht nur verwenden können,
git add .
da dadurch keine Entfernungen zum Index hinzugefügt werden.Siehe Unterschied zwischen "git add -A" und "git add".
quelle
git add -A
Link, sehr nützlich, da ich nach einer solchen Verknüpfung gesucht habe!git add .
nicht umzug zum Index hinzufügen.Am besten probieren Sie es selbst aus.
Jetzt zeigen git status und git commit --dry-run -a zwei verschiedene Ergebnisse an, wobei git status bbb.txt als neue Datei anzeigt / aaa.txt gelöscht wird und die Befehle --dry-run die tatsächliche Umbenennung anzeigen.
Jetzt checken Sie ein.
Jetzt können Sie sehen, dass die Datei tatsächlich umbenannt wurde und was im Git-Status angezeigt wird, falsch ist.
Moral der Geschichte: Wenn Sie nicht sicher sind, ob Ihre Datei umbenannt wurde, geben Sie ein "git commit --dry-run -a" aus. Wenn angezeigt wird, dass die Datei umbenannt wurde, können Sie loslegen.
quelle
Für Git 1.7.x haben die folgenden Befehle für mich funktioniert:
Git add musste nicht hinzugefügt werden, da sich die Originaldatei (dh css / mobile.css) bereits zuvor in den festgeschriebenen Dateien befand.
quelle
du musst
git add css/mobile.css
die neue datei undgit rm css/iphone.css
damit weiß git davon. dann wird die gleiche Ausgabe in angezeigtgit status
Sie können es deutlich in der Statusausgabe sehen (der neue Name der Datei):
und (der alte Name):
Ich denke, hinter den Kulissen
git mv
gibt es nichts weiter als ein Wrapper-Skript, das genau das tut: Löschen Sie die Datei aus dem Index und fügen Sie sie unter einem anderen Namen hinzuquelle
git rm css/iphone.css
müsste, weil ich dachte, dies würde die bestehende Geschichte entfernen. Vielleicht verstehe ich den Workflow in Git falsch.git rm
den Verlauf nicht. Es wird nur ein Eintrag aus dem Index entfernt, sodass das nächste Commit den Eintrag nicht enthält. Es wird jedoch weiterhin in den Ahnen-Commits vorhanden sein. Was Sie möglicherweise verwirren, ist, dass (zum Beispiel)git log -- new
an dem Punkt aufhört, an dem Sie sich verpflichtet habengit mv old new
. Wenn Sie Umbenennungen folgen möchten, verwenden Siegit log --follow -- new
.Lassen Sie uns über Ihre Dateien aus der Git-Perspektive nachdenken.
Ihr Repository hat (unter anderem)
und es ist unter git Kontrolle:
Testen Sie dies mit:
Wenn Sie das tun
Aus Git-Perspektive,
Git berät also über bereits bekannte Dateien ( iphone.css ) und neue erkannte Dateien ( mobile.css ), jedoch nur, wenn sich Dateien im Index befinden oder HEAD git beginnt, deren Inhalt zu überprüfen.
Derzeit sind weder "iphone.css deletion" noch mobile.css im Index.
Fügen Sie dem Index das Löschen von iphone.css hinzu
git sagt dir genau, was passiert ist: ( iphone.css wird gelöscht. Es ist nichts mehr passiert)
Fügen Sie dann die neue Datei mobile.css hinzu
Diesmal befinden sich sowohl das Löschen als auch die neue Datei im Index. Jetzt erkennt git, dass der Kontext identisch ist, und macht ihn als Umbenennung verfügbar. Wenn Dateien zu 50% ähnlich sind, wird dies als Umbenennung erkannt , sodass Sie mobile.css ein wenig ändern können, während der Vorgang als Umbenennung beibehalten wird .
Siehe dies ist reproduzierbar auf
git diff
. Jetzt, da Ihre Dateien im Index sind, müssen Sie verwenden--cached
. Bearbeiten Sie mobile.css ein wenig, fügen Sie das zum Index hinzu und sehen Sie den Unterschied zwischen:und
-M
ist die Option "Umbenennungen erkennen" fürgit diff
.-M
steht für-M50%
(50% oder mehr Ähnlichkeit lässt git es als Umbenennung ausdrücken), aber Sie können dies auf-M20%
(20%) reduzieren, wenn Sie mobile.css häufig bearbeiten.quelle
Schritt 1: Benennen Sie die Datei von oldfile in newfile um
Schritt 2: Git Commit und Kommentare hinzufügen
Schritt 3: Drücken Sie diese Änderung auf Remote-Server
quelle
git mv
befindet sich die neue Datei bereits im Index.Dort bist du falsch gelaufen.
Erst nachdem Sie die Datei hinzugefügt haben, erkennt Git sie anhand des Inhalts.
quelle
Sie haben die Ergebnisse Ihres Finder-Zuges nicht inszeniert. Ich glaube, wenn Sie den Umzug über Finder und dann getan hätten
git add css/mobile.css ; git rm css/iphone.css
, würde git den Hash der neuen Datei berechnen und erst dann erkennen, dass die Hashes der Dateien übereinstimmen (und somit eine Umbenennung).quelle
In Fällen, in denen Sie die Dateien wirklich manuell umbenennen müssen, z. Verwenden eines Skripts zum Batch-Umbenennen einer Reihe von Dateien, dann mit
git add -A .
für mich funktioniert.quelle
Für Xcode-Benutzer: Wenn Sie Ihre Datei in Xcode umbenennen, wird das Ausweissymbol in Anhängen geändert. Wenn Sie ein Commit mit XCode durchführen, erstellen Sie tatsächlich eine neue Datei und verlieren den Verlauf.
Eine Problemumgehung ist einfach, muss jedoch vor dem Festschreiben mit Xcode durchgeführt werden:
umbenannt in: Project / OldName.h -> Project / NewName.h umbenannt in: Project / OldName.m -> Project / NewName.m
Kehren Sie dann zu XCode zurück, und Sie werden sehen, dass das Abzeichen von A nach M geändert wurde. Es ist sicher, weitere Änderungen bei der Verwendung von xcode vorzunehmen.
quelle