872 Stimmen

Wie kann man mit git-cherry-pick nur Änderungen an bestimmten Dateien vornehmen?

Wenn ich in einem Git-Zweig die Änderungen zusammenführen möchte, die nur an einigen der Dateien vorgenommen wurden, die in einem bestimmten Commit geändert wurden, der Änderungen an mehreren Dateien enthält, wie kann dies erreicht werden?

Angenommen, der Git-Commit namens stuff hat Änderungen an Dateien A , B , C y D aber ich möchte nur zusammenführen stuff Änderungen an Dateien A y B . Das klingt wie ein Job für git cherry-pick sondern cherry-pick weiß nur, wie man ganze Commits zusammenführt, nicht eine Teilmenge der Dateien.

7voto

Alexey Punkte 71

Ich habe einen anderen Weg gefunden, der eine widersprüchliche Zusammenführung bei der Rosinenpickerei verhindert und der IMO recht einfach zu merken und zu verstehen ist. Da Sie eigentlich nicht einen Commit, sondern einen Teil davon Cherry-Picking betreiben, müssen Sie ihn zuerst aufteilen und dann einen Commit erstellen, der Ihren Bedürfnissen entspricht, und diesen Cherry-Picking betreiben.

Erstellen Sie zunächst einen Zweig von dem Commit, den Sie teilen möchten, und checken Sie ihn aus:

$ git checkout COMMIT-TO-SPLIT-SHA -b temp

Machen Sie dann die vorherige Übertragung rückgängig:

$ git reset HEAD~1

Fügen Sie dann die Dateien/Änderungen hinzu, die Sie herauspicken möchten:

$ git add FILE

und übertragen sie:

$ git commit -m "pick me"

Merken Sie sich den Commit-Hash, nennen wir ihn PICK-SHA, und gehen Sie zurück zu Ihrem Hauptzweig, z.B. master, um das Auschecken zu erzwingen:

$ git checkout -f master

und wählen Sie den Commit aus:

$ git cherry-pick PICK-SHA

Jetzt können Sie den temporären Zweig löschen:

$ git branch -d temp -f

5voto

Garogolun Punkte 303

Sie können verwenden:

git diff <commit>^ <commit> -- <path> | git apply

Die Notation <commit>^ spezifiziert das (erste) Elternteil von <commit> . Dieser diff-Befehl wählt also die Änderungen aus, die an <path> bei der Übergabe <commit> .

Beachten Sie, dass dadurch noch nichts übertragen wird (da git cherry-pick tut). Also, wenn Sie das wollen, müssen Sie tun:

git add <path>
git commit

0 Stimmen

Auf diese Weise können Sie einen beliebigen gültigen Bereich angeben, wenn das Ergebnis nicht zutrifft, können Sie sich für die 3-Wege-Zusammenführung mit -3 o --3way Schalter: ... | git apply --3way

2voto

nvd Punkte 2538

Einen Zweig mit einem neuen Zweig zusammenführen (Squash) und die nicht benötigten Dateien entfernen:

git checkout master
git checkout -b <branch>
git merge --squash <source-branch-with-many-commits>
git reset HEAD <not-needed-file-1>
git checkout -- <not-needed-file-1>
git reset HEAD <not-needed-file-2>
git checkout -- <not-needed-file-2>
git commit

2voto

davidvandebunte Punkte 1046

Ein bisschen mehr automatisieren:

#!/usr/bin/env bash

filter_commit_to_files() {
    FILES="$1"
    SHA="$2"
    git show "$SHA" -- $FILES | git apply --index -
    git commit -c "$SHA"
}

Beispiel für die Verwendung:

filter_commit_to_files "file1.txt file2.txt" 07271c5e

Ich definiere sie durch Kopieren und Einfügen von hier direkt in meine Shell. Sie brauchen keine hier dokumentieren .

0voto

Chris Maggiulli Punkte 2842

Kasse mit Patch-Flag

Eine einfache Möglichkeit, das zu erreichen, was Sie beschreiben, ist ein checkout --patch. Ändern Sie die vier Variablen, die ich am Anfang angegeben habe. Das Skript macht das Folgende:

  1. Klont den Zweig, der Ihren Commit enthält (Quellzweig)
  2. Markieren Sie den Zweig, in den Sie die Datei verschieben möchten (Zielzweig)
  3. Checken Sie den Quellzweig mit der gewünschten Commit-Revision aus, geben Sie das Patch-Flag und den relativen Speicherort der Datei als Parameter an.
  4. Hinzufügen, übertragen, pushen

Das war für mich immer die einfachste Methode. Schritt #3 erstellt zwar eine interaktive Shell, aber Sie können die gesamte Option standardmäßig deaktivieren, wenn Sie das Ziel verschlucken wollen.

source_branch=branch_with_file_you_want
destination_branch=file_go_here
rev=757c47d4
relative_file_path=structures/serializers/node.py
message="Patching a file from $source_branch to $destination_branch"

git clone https://github.com/yourepo/app.git -b $source_branch $source_branch
cd $source_branch
git checkout $destination_branch
git checkout $rev --patch $source_branch $relative_file_path
git add $relative_file_path
git commit -m "$message"
git push

Wenn Sie mit GitLab arbeiten, können Sie git push -o merge_request.create wenn Sie einen MR benötigen

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