it-swarm.com.de

Wie git mark eine gelöschte und eine neue Datei als Dateizug markieren?

Ich habe eine Datei manuell verschoben und dann geändert. Laut Git handelt es sich um eine neue Datei und eine entfernte Datei. Gibt es eine Möglichkeit, Git dazu zu zwingen, es als einen Dateizug zu behandeln?

377
pupeno

Git erkennt das Verschieben/Umbenennen automatisch, wenn Ihre Änderung nicht zu schwerwiegend ist. Einfach git add die neue Datei und git rm die alte Datei. git status zeigt dann an, ob die Umbenennung erkannt wurde. 

zusätzlich müssen Sie für Verzeichnisse verschieben:

  1. cd an den Anfang dieser Verzeichnisstruktur.
  2. git add -A . ausführen
  3. Führen Sie git status aus, um sicherzustellen, dass es sich bei der "neuen Datei" jetzt um eine "umbenannte" Datei handelt

Wenn git status immer noch "new file" und nicht "umbenannt" anzeigt, müssen Sie Hank Gay's advice folgen und den Umzug durchführen und in zwei separaten Commits ändern.

337
Bombe

Machen Sie den Umzug und die Änderung in separaten Commits.

83
Hank Gay

Es ist alles eine Wahrnehmungssache. Git ist im Allgemeinen ziemlich gut darin, Bewegungen zu erkennen, weilGITein Content-Tracker ist

Das hängt wirklich davon ab, wie Ihre "stat" es anzeigt. Der einzige Unterschied ist hier das -M-Flag. 

git log --stat -M

commit 9c034a76d394352134ee2f4ede8a209ebec96288
Author: Kent Fredric
Date:   Fri Jan 9 22:13:51 2009 +1300


        Category Restructure

     lib/Gentoo/Repository.pm                |   10 +++++-----
     lib/Gentoo/{ => Repository}/Base.pm     |    2 +-
     lib/Gentoo/{ => Repository}/Category.pm |   12 ++++++------
     lib/Gentoo/{ => Repository}/Package.pm  |   10 +++++-----
     lib/Gentoo/{ => Repository}/Types.pm    |   10 +++++-----
     5 files changed, 22 insertions(+), 22 deletions(-)

git log --stat

commit 9c034a76d394352134ee2f4ede8a209ebec96288
Author: Kent Fredric
Date:   Fri Jan 9 22:13:51 2009 +1300

    Category Restructure

 lib/Gentoo/Base.pm                |   36 ------------------------
 lib/Gentoo/Category.pm            |   51 ----------------------------------
 lib/Gentoo/Package.pm             |   41 ---------------------------
 lib/Gentoo/Repository.pm          |   10 +++---
 lib/Gentoo/Repository/Base.pm     |   36 ++++++++++++++++++++++++
 lib/Gentoo/Repository/Category.pm |   51 ++++++++++++++++++++++++++++++++++
 lib/Gentoo/Repository/Package.pm  |   41 +++++++++++++++++++++++++++
 lib/Gentoo/Repository/Types.pm    |   55 +++++++++++++++++++++++++++++++++++++
 lib/Gentoo/Types.pm               |   55 -------------------------------------
 9 files changed, 188 insertions(+), 188 deletions(-)

git help log  

   -M
       Detect renames.

   -C
       Detect copies as well as renames. See also --find-copies-harder.
42
Kent Fredric

git diff -M oder git log -M sollten solche Änderungen automatisch als umbenennen mit geringfügigen Änderungen erkennen, solange sie tatsächlich sind . Wenn Ihre geringfügigen Änderungen nicht geringfügig sind, können Sie die Ähnlichkeitsgefahr verringern, z.

$ git log -M20 -p --stat

um die Standardeinstellung um 50% auf 20% zu reduzieren.

28
gitster

Hier ist eine schnelle und schmutzige Lösung für eine oder einige wenige umbenannte und geänderte Dateien, die nicht festgeschrieben sind.

Nehmen wir an, die Datei hatte den Namen foo und jetzt heißt sie bar:

  1. Benennen Sie bar in einen temporären Namen um:

    mv bar side
    
  2. Checkout foo:

    git checkout HEAD foo
    
  3. Benennen Sie foo in bar mit Git um:

    git mv foo bar
    
  4. Benennen Sie Ihre temporäre Datei jetzt wieder in bar um.

    mv side bar
    

Mit diesem letzten Schritt wird der geänderte Inhalt wieder in die Datei zurückgegeben.

Dies kann zwar funktionieren, wenn die verschobene Datei sich inhaltlich vom ursprünglichen Git unterscheidet, wird es als effizienter angesehen, zu entscheiden, dass es sich um ein neues Objekt handelt. Lass mich demonstrieren:

$ git status
On branch workit
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

    new file:   .gitignore
    renamed:    README -> README.md

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

    modified:   README.md
    modified:   work.js

$ git add README.md work.js # why are the changes unstaged, let's add them.
$ git status
On branch workit
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

    new file:   .gitignore
    deleted:    README
    new file:   README.md
    modified:   work.js

$ git stash # what? let's go back a bit
Saved working directory and index state WIP on dir: f7a8685 update
HEAD is now at f7a8685 update
$ git status
On branch workit
Untracked files:
  (use "git add <file>..." to include in what will be committed)

    .idea/

nothing added to commit but untracked files present (use "git add" to track)
$ git stash pop
Removing README
On branch workit
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

    new file:   .gitignore
    new file:   README.md

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:    README
    modified:   work.js

Dropped refs/[email protected]{0} (1ebca3b02e454a400b9fb834ed473c912a00cd2f)
$ git add work.js
$ git status
On branch workit
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

    new file:   .gitignore
    new file:   README.md
    modified:   work.js

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:    README

$ git add README # hang on, I want it removed
$ git status
On branch workit
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

    new file:   .gitignore
    deleted:    README
    new file:   README.md
    modified:   work.js

$ mv README.md Rmd # Still? Try the answer I found.
$ git checkout README
error: pathspec 'README' did not match any file(s) known to git.
$ git checkout HEAD README # Ok the answer needed fixing.
$ git status
On branch workit
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

    new file:   .gitignore
    new file:   README.md
    modified:   work.js

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:    README.md
    modified:   work.js

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

    Rmd

$ git mv README README.md
$ git status
On branch workit
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

    new file:   .gitignore
    renamed:    README -> README.md
    modified:   work.js

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

    modified:   work.js

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

    Rmd

$ mv Rmd README.md
$ git status
On branch workit
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

    new file:   .gitignore
    renamed:    README -> README.md
    modified:   work.js

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

    modified:   README.md
    modified:   work.js

$ # actually that's half of what I wanted; \
  # and the js being modified twice? Git prefers it in this case.
27
user186821

Wenn Sie davon sprechen, dass git status die Umbenennungen nicht anzeigt, versuchen Sie stattdessen git commit --dry-run -a

16
BoD

Wenn Sie TortoiseGit verwenden, ist es wichtig zu beachten, dass Gits automatische Umbenennungserkennung während des Festschreibens erfolgt. Die Tatsache, dass dies geschieht, wird von der Software jedoch nicht immer vorher angezeigt. Ich hatte zwei Dateien in ein anderes Verzeichnis verschoben und einige geringfügige Änderungen vorgenommen. Ich benutze TortoiseGit als Commit-Tool, und in der Liste mit den durchgeführten Änderungen wurden die Dateien angezeigt, die gelöscht und nicht hinzugefügt wurden. Das Ausführen des Git-Status von der Befehlszeile aus zeigte eine ähnliche Situation. Nachdem die Dateien jedoch festgeschrieben wurden, wurden sie im Protokoll als umbenannt angezeigt. Die Antwort auf Ihre Frage lautet: Solange Sie nichts zu drastisches getan haben, sollte Git die Umbenennung automatisch vornehmen. 

Bearbeiten: Wenn Sie die neuen Dateien hinzufügen und dann einen git-Status von der Befehlszeile aus durchführen, sollte die Umbenennung vor dem Festschreiben angezeigt werden.

Bearbeiten 2: Fügen Sie in TortoiseGit außerdem die neuen Dateien im Commit-Dialog hinzu, ohne sie zu übergeben. Wenn Sie dann den Befehl "Protokoll anzeigen" anzeigen und das Arbeitsverzeichnis anzeigen, werden Sie feststellen, ob Git die Umbenennung vor dem Festschreiben erkannt hat.

Die gleiche Frage wurde hier gestellt: https://tortoisegit.org/issue/1389 und wurde als zu protokollierender Fehler hier protokolliert: https://tortoisegit.org/issue/1440 Es wird gedreht Es handelt sich um ein Anzeigeproblem mit dem Festschreibungsdialogfeld von TortoiseGit. Außerdem gibt es eine Art Status im Git-Status, wenn Sie die neuen Dateien nicht hinzugefügt haben.

10
Giles Roberts

Verwenden Sie den Befehl git mv zum Verschieben der Dateien anstelle der OS-Verschiebungsbefehle: https://git-scm.com/docs/git-mv

Bitte beachten Sie, dass der Befehl git mv nur in Git-Versionen 1.8.5 und höher vorhanden ist. Sie müssen möglicherweise Ihr Git aktualisieren, um diesen Befehl verwenden zu können.

3

Oder Sie könnten die Antwort auf diese Frage versuchen hier mit by Amber ! Um es noch einmal zu zitieren:

Brechen Sie zunächst das inszenierte Hinzufügen für die manuell verschobene Datei ab:

$ git reset path/to/newfile
$ mv path/to/newfile path/to/oldfile

Verwenden Sie dann Git, um die Datei zu verschieben:

$ git mv path/to/oldfile path/to/newfile

Wenn Sie den manuellen Umzug bereits ausgeführt haben, möchten Sie natürlich vor dem Umzug auf die Revision zurücksetzen und dann einfach mv von dort aus starten.

2
Zingam

Ich hatte dieses Problem kürzlich, als ich einige Dateien verschob (aber nicht veränderte).

Das Problem ist, dass Git einige Zeilenenden geändert hat, als ich die Dateien verschoben habe, und dann nicht feststellen konnte, dass die Dateien gleich waren.

Die Verwendung von git mv hat das Problem behoben, es funktioniert jedoch nur für einzelne Dateien/Verzeichnisse, und ich hatte viele Dateien im Stammverzeichnis des Repositorys, die zu erledigen waren.

Eine Möglichkeit, dies zu korrigieren, wäre etwas Bash/Batch-Magie.

Ein anderer Weg ist der folgende

  • Verschieben Sie die Dateien und git commit. Dies aktualisiert die Zeilenenden.
  • Verschieben Sie die Dateien zurück an ihren ursprünglichen Speicherort, nachdem sie die neuen Zeilenenden haben. git commit --amend
  • Verschieben Sie die Dateien erneut und git commit --amend. Dieses Mal gibt es keine Änderung an den Zeilenenden, daher ist Git glücklich
2
cedd

Für mich funktionierte es, alle Änderungen vor dem Commit zu speichern und sie wieder herauszuholen. Dies hat dazu geführt, dass git die hinzugefügten/gelöschten Dateien erneut analysiert und sie korrekt als verschoben markiert hat.

1
Alex Ilie

Es gibt wahrscheinlich einen besseren "Kommandozeilen-Weg", um dies zu tun, und ich weiß, dass dies ein Hack ist, aber ich habe nie eine gute Lösung finden können.

TortoiseGIT verwenden: Wenn Sie ein GIT-Commit ausführen, bei dem einige Dateiverschiebevorgänge als Last zum Hinzufügen/Löschen angezeigt werden und nicht umbenannt werden, obwohl die Dateien nur kleine Änderungen enthalten, führen Sie folgende Schritte aus:

  1. Überprüfen Sie, was Sie vor Ort gemacht haben
  2. Überprüfen Sie in einem zweiten Commit eine kleine einzeilige Änderung
  3. Gehe zu GIT log in tortoise git
  4. Wählen Sie die beiden Commits aus, klicken Sie mit der rechten Maustaste und wählen Sie "Zusammenführen in ein Commit".

Das neue Festschreiben zeigt nun die Umbenennungen der Dateien korrekt an, was dazu beiträgt, den korrekten Dateiverlauf aufrechtzuerhalten.

0
Jon Rea

Ich verstehe diese Frage so: "Wie git das Löschen einer alten Datei und das Erstellen einer neuen Datei als Dateizug erkennen lässt".

Ja im Arbeitsverzeichnis Wenn Sie eine alte Datei löschen und eine alte Datei einfügen, sagt git status "deleted: old_file" und "Untracked files: ... new_file".

Sobald Sie jedoch eine Datei mit git hinzugefügt und entfernt haben, wird sie im Staging-Index/Level als Verschiebung der Datei erkannt. Geben Sie dazu die folgenden Befehle an, vorausgesetzt, Sie haben das Löschen und Erstellen mit Ihrem Betriebssystem durchgeführt.

git add new_file
git rm old_file

Wenn der Inhalt der Datei 50% oder mehr ähnlich ist, sollten Sie beim Ausführen des Befehls git status Folgendes erhalten:

renamed: old_file -> new_file
0
harshainfo

Wenn ich eine Datei gleichzeitig bearbeite, umbenenne und verschiebe, funktioniert keine dieser Lösungen. Die Lösung besteht darin, es in zwei Commits (Bearbeiten und Umbenennen/Verschieben) und dann fixup des zweiten Commits über git rebase -i auszuführen, um es in einem Commit zu haben.

0
Hativ