774 Stimmen

Wie kann man Git dazu bringen, eine gelöschte und eine neue Datei als eine Dateiverschiebung zu markieren?

Ich habe eine Datei manuell verschoben und sie dann geändert. Laut Git ist es eine neue Datei und eine entfernte Datei. Gibt es eine Möglichkeit, Git zu zwingen, es als Dateiverschiebung zu behandeln?

3 Stimmen

Für eine bestimmte Datei old_file.txt entonces git mv old_file.txt new_file.txt ist gleichbedeutend mit git rm --cached old_file.txt , mv old_file.txt new_file.txt , git add new_file.txt .

6 Stimmen

Jarl: Nein, ist es nicht. Wenn es auch Änderungen innerhalb der Datei gibt, git mv werden sie nicht in den Cache aufgenommen, sondern git add wird. Ich ziehe es vor, die Datei zurück zu verschieben, damit ich die git mv entonces git add -p um meinen Änderungssatz zu überprüfen.

0 Stimmen

617voto

Bombe Punkte 77831

Git erkennt die Verschiebung/Umbenennung 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 es die Umbenennung erkannt hat.

Zusätzlich müssen Sie bei der Verschiebung von Verzeichnissen unter Umständen:

  1. cd an den Anfang dieser Verzeichnisstruktur.
  2. Ejecutar git add -A .
  3. Ejecutar git status um zu überprüfen, ob die "neue Datei" nun eine "umbenannte" Datei ist

Wenn der Git-Status immer noch "neue Datei" und nicht "umbenannt" anzeigt, müssen Sie Folgendes tun Hank Gay's und führen Sie das Verschieben und Ändern in zwei separaten Commits durch.

194voto

Hank Gay Punkte 67607

Führen Sie die Verschiebung und die Änderung in separaten Commits durch.

55voto

git diff -M ou git log -M sollte solche Änderungen automatisch als Umbenennung mit geringfügigen Änderungen so lange sie es tatsächlich sind. Wenn Ihr geringfügige Änderungen nicht geringfügig sind, können Sie den Ähnlichkeitsschwellenwert verringern, z. B.

$ git log -M20 -p --stat

um sie von den standardmäßigen 50 % auf 20 % zu reduzieren.

46voto

Kent Fredric Punkte 55042

Es ist alles eine Sache der Wahrnehmung. Git ist im Allgemeinen recht gut darin, Züge zu erkennen, weil GIT es un Content-Tracker

Alles, was wirklich davon abhängt, ist, wie Ihr "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-Hilfe-Protokoll

   -M
       Detect renames.

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

46voto

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

Nehmen wir an, die Datei hieße foo und jetzt heißt es bar :

  1. Umbenennen bar auf einen vorläufigen Namen:

    mv bar side
  2. Kasse foo :

    git checkout HEAD foo
  3. Umbenennen foo まで bar mit Git:

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

    mv side bar

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

Dies kann zwar funktionieren, aber wenn sich die verschobene Datei inhaltlich zu sehr vom Original unterscheidet, wird Git es für effizienter halten, sie als neues Objekt zu betrachten. Lassen Sie mich das 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/stash@{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.

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