521 Stimmen

Handhabung von Dateiumbenennungen in Git

Das hatte ich gelesen, als Umbenennen von Dateien in Git Wenn Sie die Datei umbenannt haben, sollten Sie alle Änderungen festschreiben, die Datei umbenennen und dann die umbenannte Datei bereitstellen. Git erkennt die Datei anhand ihres Inhalts, anstatt sie als neue, nicht verfolgte Datei zu betrachten, und behält den Änderungsverlauf bei.

Als ich jedoch heute Abend genau das tat, kehrte ich zurück zu git mv .

> $ git status
# On branch master
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#    modified:   index.html
#

Ich habe mein Stylesheet umbenannt in Finder から iphone.css a mobile.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 denkt nun, ich hätte eine CSS-Datei gelöscht und eine neue hinzugefügt. Das ist nicht das, was ich will. Machen wir die Umbenennung rückgängig und lassen Git die Arbeit machen.

> $ git reset HEAD .
Unstaged changes after reset:
M    css/iphone.css
M    index.html

Ich bin wieder da, wo ich angefangen habe:

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

Es sieht so aus, als wäre alles in Ordnung. Warum hat Git die Umbenennung nicht gleich beim ersten Mal erkannt, als ich den Finder benutzt habe?

386voto

tanascius Punkte 51555

Für git mv die Handbuchseite sagt

Nach erfolgreichem Abschluss wird der Index aktualisiert, [ ]

Daher müssen Sie den Index zunächst selbst aktualisieren (durch Verwendung von git add mobile.css ). Allerdings git status werden immer noch zwei verschiedene Dateien angezeigt:

$ git status
# On branch master
warning: LF will be replaced by CRLF in index.html
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#       modified:   index.html
#       new file:   mobile.css
#
# 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:    iphone.css
#

Sie können eine andere Ausgabe erhalten, indem Sie git commit --dry-run -a was zu dem führt, was Sie erwarten:

Tanascius@H181 /d/temp/blo (master)
$ git commit --dry-run -a
# On branch master
warning: LF will be replaced by CRLF in index.html
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#       modified:   index.html
#       renamed:    iphone.css -> mobile.css
#

Ich kann Ihnen nicht genau sagen, warum wir diese Unterschiede feststellen. zwischen git status y git commit --dry-run -a aber hier ist ein Hinweis von Linus :

git hat wirklich nicht einmal Pflege über das Ganze "Umbenennungserkennung" intern, und alle Commits, die Sie haben mit Umbenennungen vorgenommen haben, sind völlig unabhängig von der Heuristik, die wir dann verwenden, um anzeigen die Umbenennung.

A dry-run verwendet die echten Umbenennungsmechanismen, während ein git status wahrscheinlich nicht.

67voto

GrigorisG Punkte 698

Für Git 1.7.x funktionierten die folgenden Befehle bei mir:

git mv css/iphone.css css/mobile.css
git commit -m 'Rename folder.'

Es bestand keine Notwendigkeit für git add da die Originaldatei (d. h., css/mobile.css ) war bereits zuvor in den übermittelten Dateien enthalten.

19voto

dimuthu Punkte 775

Am besten ist es, wenn Sie es selbst ausprobieren.

mkdir test
cd test
git init
touch aaa.txt
git add .
git commit -a -m "New file"
mv aaa.txt bbb.txt
git add .
git status
git commit --dry-run -a

Jetzt git status y git commit --dry-run -a zeigt zwei unterschiedliche Ergebnisse, bei denen git status zeigt bbb.txt als neue Datei/ aaa.txt wird gelöscht, und die --dry-run Befehle zeigt die tatsächliche Umbenennung an.

~/test$ git status

# On branch master
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#   new file:   bbb.txt
#
# Changes not staged for commit:
#   (use "git add/rm <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
#   deleted:    aaa.txt
#

/test$ git commit --dry-run -a

# On branch master
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#   renamed:    aaa.txt -> bbb.txt
#

Machen Sie jetzt weiter und checken Sie ein.

git commit -a -m "Rename"

Jetzt können Sie sehen, dass die Datei tatsächlich umbenannt wurde, und was in git status ist falsch, zumindest in diesem Fall. Es könnte sein, dass die GIT-Implementierung von underline die beiden Befehle getrennt behandelt.

Die Moral von der Geschicht': Wenn Sie sich nicht sicher sind, ob Ihre Datei umbenannt wurde, führen Sie einen "git commit --dry-run -a" durch. Wenn er anzeigt, dass die Datei umbenannt wurde, ist alles in Ordnung.

16voto

Haimei Punkte 11915

Schritt 1: Umbenennen der Datei von oldfile in newfile

git mv #oldfile #newfile

Schritt 2: git commit und Kommentare hinzufügen

git commit -m "rename oldfile to newfile"

Schritt 3: Übertragen Sie diese Änderung auf den entfernten Server

git push origin #localbranch:#remotebranch

11voto

knittl Punkte 214432

Sie müssen git add css/mobile.css die neue Datei und git rm css/iphone.css damit Git Bescheid weiß. Dann zeigt es die gleiche Ausgabe in git status .

Sie können es in der Statusausgabe deutlich sehen (der neue Name der Datei):

# Untracked files:
#   (use "git add <file>..." to include in what will be committed)

Und (der alte Name):

# Changed but not updated:
#   (use "git add/rm <file>..." to update what will be committed)

Ich denke, hinter den Kulissen git mv ist nichts anderes als ein Wrapper-Skript, das genau das tut: die Datei aus dem Index löschen und sie unter einem anderen Namen hinzufügen

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X