it-swarm.com.de

Warum gibt es zwei Möglichkeiten, eine Datei in Git zu dekonfigurieren?

Manchmal schlägt git git rm --cached vor, eine Datei zu dekonfigurieren, manchmal git reset HEAD file. Wann soll ich welche verwenden?

BEARBEITEN:

D:\code\gt2>git init
Initialized empty Git repository in D:/code/gt2/.git/
D:\code\gt2>touch a

D:\code\gt2>git status
# On branch master
#
# Initial commit
#
# Untracked files:
#   (use "git add <file>..." to include in what will be committed)
#
#       a
nothing added to commit but untracked files present (use "git add" to track)

D:\code\gt2>git add a

D:\code\gt2>git status
# On branch master
#
# Initial commit
#
# Changes to be committed:
#   (use "git rm --cached <file>..." to unstage)
#
#       new file:   a
#
D:\code\gt2>git commit -m a
[master (root-commit) c271e05] a
 0 files changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 a

D:\code\gt2>touch b

D:\code\gt2>git status
# On branch master
# Untracked files:
#   (use "git add <file>..." to include in what will be committed)
#
#       b
nothing added to commit but untracked files present (use "git add" to track)

D:\code\gt2>git add b

D:\code\gt2>git status
# On branch master
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#       new file:   b
#
1048
Senthess

git rm --cached <filePath>macht kein Unstage eine Datei, es tatsächlich macht das Entfernen der Datei (en) aus dem Repo (vorausgesetzt, es wurde bereits vorher festgeschrieben), verlässt aber das Repo Datei in Ihrem Arbeitsbaum (so dass Sie eine nicht verfolgte Datei haben).

git reset -- <filePath> wird nstage alle inszenierten Änderungen für die angegebene (n) Datei (en).

Das heißt, wenn Sie git rm --cached für eine neue Datei verwenden, die bereitgestellt wird, sieht es im Grunde so aus, als hätten Sie sie nur aufgehoben, da sie noch nie festgeschrieben wurde.

1729
Ryan Stewart

git rm --cached wird verwendet, um eine Datei aus dem Index zu entfernen. Befindet sich die Datei bereits im Repo, entfernt git rm --cached die Datei aus dem Index und verbleibt im Arbeitsverzeichnis. Ein Commit entfernt sie nun auch aus dem Repo. Grundsätzlich hätten Sie nach dem Festschreiben die Datei dekomprimiert und eine lokale Kopie aufbewahrt.

git reset HEAD file (das standardmäßig das --mixed -Flag verwendet) unterscheidet sich darin, dass in dem Fall, in dem sich die Datei bereits im Repo befindet, die Indexversion der Datei durch die von Repo (HEAD) ersetzt wird ), wodurch das Modifikationen effektiv deaktiviert wird.

Im Fall einer nicht versionierten Datei wird die gesamte Datei dekonfiguriert, da sich die Datei nicht im HEAD befand. In diesem Aspekt sind git reset HEAD file und git rm --cached gleich, aber sie sind nicht gleich (wie im Fall von Dateien, die sich bereits im Repo befinden).

Auf die Frage von Why are there 2 ways to unstage a file in git? - es gibt nie wirklich nur einen Weg, etwas in git zu machen. das ist das Schöne daran :)

324
manojlds

Recht einfach:

  • git rm --cached <file> lässt git die Datei nicht mehr vollständig verfolgen (im Gegensatz zu normalem git rm *)
  • git reset HEAD <file> macht alle Änderungen rückgängig, die seit dem letzten Festschreiben an der Datei vorgenommen wurden (setzt sie jedoch entgegen dem Befehl nicht im Dateisystem zurück Name könnte darauf hindeuten **). Die Datei bleibt unter Versionskontrolle.

Wenn sich die Datei zuvor nicht in der Versionskontrolle befand (dh, Sie heben die Bereitstellung einer Datei auf, die Sie gerade zum ersten Mal git added hatten), haben die beiden Befehle den gleichen Effekt, weshalb sie "zwei" sind Wege, etwas zu tun ".

* Beachten Sie, dass @DrewT in seiner Antwort die Einschränkung erwähnt, dass git rm --cached eine Datei ist, die zuvor an das Repository übergeben wurde . Im Zusammenhang mit dieser Frage besteht für eine Datei, die gerade hinzugefügt und noch nicht festgeschrieben wurde, kein Grund zur Sorge.

** Ich hatte peinlich lange Angst, den Befehl git reset wegen seines Namens zu verwenden - und noch heute schaue ich oft in der Syntax nach, um sicherzugehen, dass ich nichts falsch mache. ( update : Ich habe mir endlich die Zeit genommen, um die Verwendung von git reset in einer tldr-Seite zusammenzufassen , also jetzt Ich habe ein besseres mentales Modell, wie es funktioniert, und eine kurze Referenz, wenn ich einige Details vergesse.)

115
waldyrious

Dieser Thread ist ein bisschen alt, aber ich möchte noch eine kleine Demonstration hinzufügen, da es immer noch kein intuitives Problem ist:

me$ git status
# On branch master
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#   new file:   to-be-added
#   modified:   to-be-modified
#   deleted:    to-be-removed
#

me$ git reset -q HEAD to-be-added

    # ok

me$ git reset -q HEAD to-be-modified

    # ok

me$ git reset -q HEAD to-be-removed

    # ok

# or alternatively:

me$ git reset -q HEAD to-be-added to-be-removed to-be-modified

    # ok

me$ git status
# On branch master
# 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)
#
#   modified:   to-be-modified
#   deleted:    to-be-removed
#
# Untracked files:
#   (use "git add <file>..." to include in what will be committed)
#
#   to-be-added
no changes added to commit (use "git add" and/or "git commit -a")

git reset HEAD (ohne -q) gibt eine Warnung über die geänderte Datei aus und ihr Beendigungscode ist 1, was als Fehler in einem Skript angesehen wird.

Bearbeiten: git checkout HEAD to-be-modified to-be-removed funktioniert auch zum Aufheben der Bereitstellung, entfernt die Änderung jedoch vollständig aus dem Arbeitsbereich

44
Daniel Alder

wenn Sie versehentlich Dateien bereitgestellt haben, die Sie nicht festschreiben möchten, und sicher sein möchten, dass Sie die Änderungen beibehalten, können Sie auch Folgendes verwenden:

git stash
git stash pop

dies führt einen Reset auf HEAD durch und wendet Ihre Änderungen erneut an, sodass Sie einzelne Dateien erneut für das Festschreiben bereitstellen können. Dies ist auch hilfreich, wenn Sie vergessen haben, einen Feature-Zweig für Pull-Anforderungen (git stash ; git checkout -b <feature> ; git stash pop) zu erstellen.

35
ives

Diese beiden Befehle unterscheiden sich geringfügig, wenn sich die betreffende Datei bereits im Repository befindet und der Versionskontrolle unterliegt (zuvor festgeschrieben usw.):

  • git reset HEAD <file> Hebt die Speicherung der Datei im aktuellen Commit auf.
  • git rm --cached <file> dekonfiguriert die Datei auch für zukünftige Commits. Es ist unstaged, bis es mit git add <file> erneut hinzugefügt wird.

Und es gibt noch einen wichtigen Unterschied:

  • Nachdem Sie git rm --cached <file> und Push your branch to the remote ausgeführt haben, wird die Datei ACTUALLY aus Ihrem Ordner gelöscht, auch wenn Sie in Ihrem lokalen Arbeitsverzeichnis die Datei festgelegt haben wird nur untracked (dh nicht physisch aus dem Ordner gelöscht).

Dieser letzte Unterschied ist wichtig für Projekte, die eine Konfigurationsdatei enthalten, in der jeder Entwickler im Team eine andere Konfiguration hat (dh eine andere Basis-URL, IP oder Port-Einstellung). Wenn Sie also git rm --cached <file> verwenden, wird jeder, der Ihren Zweig zieht, dies tun Sie müssen die Konfiguration manuell neu erstellen, oder Sie können sie Ihnen senden und sie können sie wieder auf ihre IP-Einstellungen (usw.) zurückbearbeiten, da das Löschen nur Leute betrifft, die Ihren Zweig von der Fernbedienung ziehen.

15
DrewT

1.

D:\code\gt2>git status
# On branch master
#
# Initial commit
#
# Changes to be committed:
#   (use "git rm --cached <file>..." to unstage)
#
#       new file:   a

(benutze "git rm --cached ..." um die Bühne zu verlassen

  • git ist ein System von Zeigern

  • sie haben noch kein Commit, um Ihren Zeiger auf zu ändern

  • die einzige Möglichkeit, Dateien aus dem Eimer zu entfernen, auf die verwiesen wird, besteht darin, Dateien zu entfernen, bei denen Sie git angewiesen haben, auf Änderungen zu achten

2.

D:\code\gt2>git commit -m a
[master (root-commit) c271e05] a
0 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 a

git commit -m a

  • sie haben sich verpflichtet, 'gespeichert'

3.

D:\code\gt2>git status
# On branch master
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#       new file:   b
#

(benutze "git reset HEAD ..." um die Bühne zu verlassen)

  • sie haben zu diesem Zeitpunkt ein Commit in Ihrem Code ausgeführt
  • jetzt können Sie Ihren Zeiger auf Ihr Commit 'Zurück zum letzten Speichern' zurücksetzen.

Angenommen, Sie stage ein ganzes Verzeichnis über git add <folder>, möchten jedoch eine Datei aus der bereitgestellten Liste ausschließen (dh die Liste, die beim Ausführen von git status generiert wird) und behalten die Änderungen in der ausgeschlossenen Datei (Sie haben an etwas gearbeitet und es ist nicht bereit zum Festschreiben, aber Sie möchten Ihre Arbeit nicht verlieren ...). Sie könnten einfach verwenden:

git reset <file>

Wenn Sie git status ausführen, werden Sie sehen, dass alle Dateien, die Sie reset sind, unstaged und die restlichen Dateien, die Sie added sind, noch in staged Liste.

8
jiminikiz

Ich bin überrascht, dass niemand das Git-Reflog erwähnt hat ( http://git-scm.com/docs/git-reflog ):

# git reflog
<find the place before your staged anything>
# git reset [email protected]{1}

Das Reflog ist ein Git-Verlauf, der nicht nur die Änderungen am Repo, sondern auch die Benutzeraktionen (z. B. Ziehen, Auschecken in einen anderen Zweig usw.) verfolgt und das Rückgängigmachen dieser Aktionen ermöglicht. Anstatt also die versehentlich bereitgestellte Datei zu deaktivieren, können Sie zu dem Punkt zurückkehren, an dem Sie die Dateien nicht bereitgestellt haben.

Dies ähnelt git reset HEAD <file>, ist jedoch in bestimmten Fällen möglicherweise genauer.

Entschuldigung - beantworte deine Frage nicht wirklich, sondern zeige nur einen weiteren Weg, um Dateien zu entfernen, die ich ziemlich oft benutze (ich mag Antworten von Ryan Stewart und waldyrious sehr.);) Ich hoffe, es hilft.

5
Alex

Es scheint mir, dass git rm --cached <file> die Datei aus dem Index entfernt, ohne sie aus dem Verzeichnis zu entfernen, in dem ein einfaches git rm <file> beides tun würde, genau wie ein Betriebssystem rm <file> die Datei aus dem Index entfernen würde Verzeichnis, ohne seine Versionierung zu entfernen.

3
ernie.cordell