So wählen Sie nur Änderungen für nur eine Datei aus, nicht das gesamte Commit

108

Ich muss Änderungen, die in einem Zweig eingeführt wurden, auf einen anderen Zweig anwenden. Ich kann Cherry Pick verwenden, um das zu tun. In meinem Fall möchte ich jedoch Änderungen anwenden, die nur für eine Datei relevant sind. Ich muss nicht das gesamte Commit auswählen. Wie geht das?

wie er
quelle

Antworten:

136

Sie haben verschiedene Möglichkeiten, je nachdem, was Sie erreichen möchten:

Wenn Sie möchten, dass der Inhalt der Datei mit dem des Zielzweigs übereinstimmt, können Sie ihn verwenden git checkout <branch> -- <filename>. Dies wird jedoch nicht die Änderungen "auswählen", die in einem einzelnen Commit vorgenommen wurden, sondern nur den resultierenden Status dieser Datei annehmen. Wenn Sie also eine Zeile in einem Commit hinzugefügt haben, die vorherigen Commits jedoch mehr geändert wurden und Sie diese Zeile nur ohne diese anderen Änderungen hinzufügen möchten, ist eine Kaufabwicklung nicht das, was Sie möchten.

Andernfalls haben Sie mehrere Optionen, wenn Sie den in einem Commit eingeführten Patch nur auf eine einzelne Datei anwenden möchten. Sie können git cherry-pick -ndas Commit ausführen , dh ohne es festzuschreiben, bearbeiten (z. B. alle Dateien mit zurücksetzen git reset -- .und nur die Datei hinzufügen, die Sie tatsächlich mit ändern möchten git add <filename>). Oder Sie können das Diff für die Datei erstellen und das Diff dann anwenden:

git diff <branch>^..<branch> -- <filename> | git apply
Sack
quelle
22

Erstellen Sie ein patch fileund wenden Sie es an.

git diff branchname -- filename > patchfile
git apply patchfile

BEARBEITEN:

Da Sie die Änderungen aus einem Commit übernehmen müssen, erstellen Sie den Patch wie folgt:

git show sha1 -- filename > patchfile
Sailesh
quelle
1
git diff sha1(oder git diff branch- es ist dasselbe, wenn der Zweig auf denselben Hash verweist) erzeugt nur einen Unterschied des aktuellen Arbeitsverzeichnisses in Bezug auf diesen Hash, nicht jedoch, was ein selbst eingeführtes Commit ändert.
stupsen
Richtig. Antwort bearbeitet. Vielen Dank.
Sailesh
1
-1 git checkoutmit einem Dateinamen ist der richtige Hammer für diesen Nagel. Beide Optionen sind unnötig komplex.
Rein Henrichs
7
Für diesen speziellen Fall ja. Wenn Sie jedoch Änderungen aus einem Commit für eine bestimmte Datei auswählen möchten, checkoutfunktioniert dies im Allgemeinen nicht, da dies möglicherweise andere unerwünschte vorherige Änderungen beinhaltet und möglicherweise keine Änderungen enthält, die im aktuellen Zweig vorgenommen wurden.
Sailesh
11

Eine weitere praktische Möglichkeit besteht darin, den Patch lokal abzurufen und dann zu verwenden:

git checkout {<name_of_branch>, commit's SHA} <path to the file> 

Das ist aber keine Kirschernte.

0x90
quelle
2
Warnung: Wie @poke in seiner Antwort sagt, werden die Änderungen dadurch nicht kopiert. Es kopiert den gesamten Status der Datei. Wenn Sie also die Änderungen eines Commits zur Datei hinzufügen möchten, überschreiben Sie beim Auschecken alle neueren Änderungen, was nicht gut ist.
Alexander Bird
7

Git hat alles fertig :)

Benutz einfach git checkout <sha> <path-to-file>

Raghotham S.
quelle
4
Das ist kein Kirschbaum - das checkt die Datei vollständig aus. Ziel ist es, eine bestimmte Änderung gegenüber einem Commit vorzunehmen. Oft sind das die gleichen, aber manchmal nicht.
AndrewF
6
git checkout the_branch_with_the_change the/path/to/the/file/you/want.extension

Dies funktioniert, wenn eine einzelne Datei aus einem anderen Zweig in den aktuellen Arbeitszweig kopiert werden soll

Ismail Iqbal
quelle
1
Seien Sie vorsichtig, Änderungen an der Datei, die nicht in der Version des anderen Zweigs enthalten sind, gehen verloren.
Patrick Schlüter
Dem zustimmte. Dies ist nützlich, wenn Sie nur eine Kopie der Datei benötigen und diese im aktuellen Zweig ändern möchten
Ismail Iqbal
1
Man kann Globs (Pfad / *) verwenden und mehr als einen Pfad / eine Datei angeben
Todd
1

Das suchen Sie:

git checkout target-branch sha1 path/to/file

sha1 ist optional

Ruslan Osipov
quelle
11
Nein, " Änderungen im Commit auswählen " ist nicht "Ganze Datei auswählen"
Abyx
1

Was ich dazu neige, ist zu benutzen git ls-tree

mach einfach:

git ls-tree -r <commit-id> |grep 'your filename'
# there will be output that shows a SHA1 of your file
git show ${SHA1 of your file} > 'your filename'

Dadurch werden alle Dateinamen gedruckt, die Ihrem grep entsprechen, und es werden SHA1-Schlüssel der Dateien im Commit angegeben.

Git Show kann auch für Dateien außerhalb Ihres Zweigs verwendet werden. Wenn >Sie die Ausgabe von Ihrer Shell aus in eine Datei leiten, erhalten Sie das gewünschte Ergebnis.

Alex
quelle
0

Sie können dies versuchen:

git show COMMIT_ID -- path/to/specific-file | git apply

Beispielsweise:

git show 3feaf20 -- app/views/home/index.html | git apply
arashb31
quelle
-9
git reset HEAD~1

Verschiebt die Dateien in die Pre-Commit-Phase

git stash

wird aus dem Speicher entfernt

Jetzt ist Ihre Filiale ziemlich sauber (zurück zum vorherigen Commit)

Venkata
quelle