Ich verschmelze in einem Remote-Zweig, der möglicherweise viele Konflikte aufweist. Wie kann ich feststellen, ob es Konflikte geben wird oder nicht?
Ich sehe so etwas wie ein --dry-run
On nicht git-merge
.
Ich verschmelze in einem Remote-Zweig, der möglicherweise viele Konflikte aufweist. Wie kann ich feststellen, ob es Konflikte geben wird oder nicht?
Ich sehe so etwas wie ein --dry-run
On nicht git-merge
.
Antworten:
Übergeben Sie, wie bereits erwähnt, das --no-commit
Flag, aber um ein schnelles Vorwärts-Commit zu vermeiden, übergeben Sie es auch --no-ff
wie folgt:
$ git merge --no-commit --no-ff $BRANCH
So untersuchen Sie die inszenierten Änderungen:
$ git diff --cached
Und Sie können die Zusammenführung rückgängig machen, auch wenn es sich um eine Schnellvorlaufzusammenführung handelt:
$ git merge --abort
git merge --only-if-there-wont-be-any-conflicts
oder git diff --show-conflicts <commit>
wäre wirklich praktisch. Schade, dass es noch nicht möglich ist oder fehlt mir etwas?
git pull --ff-only
!
Ich musste nur eine Methode implementieren, die automatisch Konflikte zwischen einem Repository und seiner Fernbedienung findet. Diese Lösung führt die Zusammenführung im Speicher durch, sodass weder der Index noch der Arbeitsbaum berührt werden. Ich denke, dies ist der sicherste Weg, um dieses Problem zu lösen. So funktioniert das:
git fetch origin master
git merge-base FETCH_HEAD master
git merge-tree mergebase master FETCH_HEAD
( Mergebase ist die hexadezimale ID, die die Merge-Basis im vorherigen Schritt gedruckt hat.)Angenommen, Sie möchten den Remote-Master mit Ihrem lokalen Master zusammenführen, können jedoch beliebige Zweige verwenden. git merge-tree
führt die Zusammenführung im Speicher aus und druckt das Ergebnis in die Standardausgabe. Grep für das Muster <<
oder >>
. Oder Sie können die Ausgabe in eine Datei drucken und dies überprüfen. Wenn Sie eine Zeile finden, die mit "in beiden geändert" beginnt, liegt höchstwahrscheinlich ein Konflikt vor.
git merge-tree `git merge-base FETCH_HEAD master` FETCH_HEAD master
git merge-tree `git merge-base clieop master` clieop master | grep -A3 "changed in both"
Einfach großartig! +100
+<<<<<<< .our
Also verwende ich einen Grep-Ausdruck wiegrep -q '^+<* \.our$'
Meine einfache Brute-Force-Lösung hierfür lautet:
Erstellen Sie einen "Pre-Master" -Zweig (vom Master natürlich)
Füge alle Dinge, die du willst, in diesen Pre-Master ein.
Dann können Sie sehen, wie die Zusammenführung stattgefunden hat, ohne den Master zu berühren.
Wie auch immer, ich würde dem Rat von @ orange80 folgen.
git merge --abort
wenn es Konflikte gibt, git reset --hard HEAD~1
wenn es eine Zusammenführung gab oder git reset --hard origin/master
. Das Erstellen eines weiteren Zweigs gibt Ihnen ein Gefühl der Sicherheit, aber wenn Sie lernen, wie Git funktioniert, werden Sie verstehen, dass es sich um fehlgeleitete Angst handelt. Wenn Bedenken bestehen, die Arbeitskopie nicht zu ändern, bietet dies keine Lösung.
git merge --no-commit
Eine Zusammenführung wird nicht abgebrochen, wenn sie schnell weitergeleitet werden kann. git merge --abort
funktioniert nicht, wenn es zusammengeführt wurde. Wenn Sie dies als Skript schreiben möchten, ist dies umständlich, da Sie git merge
nicht mit ausreichend guten Fehlercodes antworten, um die verschiedenen Arten von Konflikten zu erklären. Das Arbeiten mit einem neuen Zweig verhindert, dass ein defektes Skript Ihr Repo in einem Zustand belässt, in dem manuelle Eingriffe erforderlich sind. Sicher kannst du nichts verlieren. Aber es ist einfacher, anders zu bauen.
Das Rückgängigmachen einer Zusammenführung mit git ist so einfach, dass Sie sich nicht einmal Gedanken über den Trockenlauf machen sollten:
$ git pull $REMOTE $BRANCH
# uh oh, that wasn't right
$ git reset --hard ORIG_HEAD
# all is right with the world
BEARBEITEN: Wie in den Kommentaren unten angegeben, möchten Sie Änderungen in Ihrem Arbeitsverzeichnis oder Staging-Bereich wahrscheinlich vor dem oben beschriebenen Vorgang aufbewahren (andernfalls verschwinden sie nach den git reset
obigen Anweisungen).
git branch --contains HEAD
oder noch direkter überprüfen. Verwenden Sie einfachgit merge --ff-only
--dry-run
würde nicht "einfach prüfen, ob eine Zusammenführung schnell vorwärts geht". Es würde die genaue Ausgabe zurückgeben, die eine Zusammenführung ergeben würde: Dateien, Konflikte usw. Ob es ff ist, ist nicht wirklich interessant, oder?
git stash; git reset --hard
? @ BrianPhillips
Ich habe einen Alias dafür gemacht und arbeite wie ein Zauber, ich mache das:
git config --global alias.mergetest '!f(){ git merge --no-commit --no-ff "$1"; git merge --abort; echo "Merge aborted"; };f '
Jetzt rufe ich einfach an
git mergetest <branchname>
Um herauszufinden, ob es Konflikte gibt.
Vergleichen Sie einfach Ihren aktuellen Zweig mit dem Remote-Zweig. Hier erfahren Sie, was sich beim Ziehen / Zusammenführen ändern wird.
#see diff between current master and remote branch
git diff master origin/master
Ich benutze dazu den Befehl request-pull git. Sie können jede Änderung sehen, die beim Zusammenführen auftreten würde, ohne jedoch etwas in Ihren lokalen oder Remote-Repositorys zu tun .
Stellen Sie sich zum Beispiel vor, Sie möchten einen Zweig mit dem Namen "feature-x" in Ihren Hauptzweig einbinden
git request-pull master origin feature-x
zeigt Ihnen eine Zusammenfassung dessen, was passieren würde (ohne etwas zu tun):
The following changes since commit fc01dde318:
Layout updates (2015-06-25 11:00:47 +0200)
are available in the git repository at:
http://fakeurl.com/myrepo.git/ feature-x
for you to fetch changes up to 841d3b41ad:
----------------------------------------------------------------
john (2):
Adding some layout
Refactoring
ioserver.js | 8 +++---
package.json | 7 +++++-
server.js | 4 +--
layout/ldkdsd.js | 277 +++++++++++++++++++++++++++++++++++++
4 files changed, 289 insertions(+), 7 deletions(-)
create mode 100644 layout/ldkdsd.js
Wenn Sie den -p
Parameter hinzufügen , erhalten Sie auch den vollständigen Patch-Text, genau wie wenn Sie für jede geänderte Datei einen Git-Diff ausführen würden.
master
und origin
was in den Befehlszeilenoptionen zu tun ist, und was ist, wenn ich mich beispielsweise in einem lokalen Zweig befinde branch1
und request-pull
einen Zweig in einem lokalen Feature ausführen möchte branch2
? Muss ich noch brauchen origin
? Natürlich kann man die Dokumentation immer lesen.
Ich bin überrascht, dass noch niemand vorgeschlagen hat, Patches zu verwenden.
Angenommen, Sie möchten eine Zusammenführung von your_branch
in testen master
(ich gehe davon aus, dass Sie master
ausgecheckt haben):
$ git diff master your_branch > your_branch.patch
$ git apply --check your_branch.patch
$ rm your_branch.patch
Das sollte den Trick machen.
Wenn Sie Fehler wie erhalten
error: patch failed: test.txt:1
error: test.txt: patch does not apply
Das bedeutet, dass der Patch nicht erfolgreich war und eine Zusammenführung zu Konflikten führen würde. Keine Ausgabe bedeutet, dass der Patch sauber ist und Sie den Zweig problemlos zusammenführen können
Beachten Sie, dass dies Ihren Arbeitsbaum nicht wirklich ändert (abgesehen von der Erstellung der Patch-Datei natürlich, aber Sie können diese anschließend sicher löschen). Aus der git-apply-Dokumentation:
--check
Instead of applying the patch, see if the patch is applicable to the
current working tree and/or the index file and detects errors. Turns
off "apply".
Hinweis für alle, die klüger / erfahrener mit Git sind als ich: Bitte lassen Sie mich wissen, wenn ich hier falsch liege und diese Methode ein anderes Verhalten zeigt als eine reguläre Zusammenführung. Es scheint seltsam, dass in den mehr als 8 Jahren, in denen diese Frage existiert hat, niemand diese scheinbar offensichtliche Lösung vorschlagen würde.
git diff master your_branch | git apply --check
.
Dies könnte interessant sein: Aus der Dokumentation:
Wenn Sie eine Zusammenführung versucht haben, die zu komplexen Konflikten geführt hat, und von vorne beginnen möchten, können Sie mit git merge --abort wiederherstellen .
Sie können es aber auch naiv (aber langsam) machen:
rm -Rf /tmp/repository
cp -r repository /tmp/
cd /tmp/repository
git merge ...
...if successful, do the real merge. :)
(Hinweis: Es funktioniert nicht nur beim Klonen nach / tmp. Sie benötigen eine Kopie, um sicherzustellen, dass nicht festgeschriebene Änderungen nicht in Konflikt geraten.)
cp -r repository/.git /tmp/repository/.git
, cd /tmp/repository
, git reset --hard
, git add --all
, git reset --hard
(für eine gute Maßnahme), git status
(um zu überprüfen , dass es sauber).
Mir ist bewusst, dass dies eine alte Frage ist, aber es ist die erste, die in einer Google-Suche angezeigt wird.
Git hat beim Zusammenführen die Option --ff-only eingeführt.
Von: http://git-scm.com/docs/git-merge
--ff-only
Verweigern Sie das Zusammenführen und Beenden mit einem Status ungleich Null, es sei denn, der aktuelle HEAD ist bereits auf dem neuesten Stand oder die Zusammenführung kann als schneller Vorlauf aufgelöst werden.
Wenn Sie dies tun, wird versucht, zusammenzuführen und vorzuspulen. Wenn dies nicht möglich ist, werden Sie abgebrochen und aufgefordert, den schnellen Vorlauf nicht durchzuführen, aber Ihr Arbeitszweig bleibt unberührt. Wenn es schnell vorspulen kann, führt es die Zusammenführung in Ihrem Arbeitszweig durch. Diese Option ist auch am verfügbar git pull
. Sie können also Folgendes tun:
git pull --ff-only origin branchA #See if you can pull down and merge branchA
git merge --ff-only branchA branchB #See if you can merge branchA into branchB
Ich verwende das Git-Protokoll, um zu sehen, was sich an einem Feature-Zweig vom Master-Zweig geändert hat
git log does_this_branch..contain_this_branch_changes
zB - um zu sehen, welche Commits sich in einem Feature-Zweig befinden, der zum Master zusammengeführt wurde / nicht:
git log master..feature_branch
Wenn Sie von B nach A vorspulen möchten, müssen Sie sicherstellen, dass das Git-Protokoll B..A Ihnen nichts anzeigt, dh A hat nichts, was B nicht hat. Aber selbst wenn B..A etwas hat, können Sie möglicherweise immer noch ohne Konflikte zusammengeführt werden. Das Obige zeigt also zwei Dinge: dass es einen schnellen Vorlauf geben wird und Sie somit keinen Konflikt bekommen.
Meine Lösung besteht darin, rückwärts zu verschmelzen.
Anstatt Ihren Zweig mit dem entfernten "Ziel" -Zweig zusammenzuführen, führen Sie diesen Zweig mit Ihrem Zweig zusammen.
git checkout my-branch
git merge origin/target-branch
Sie werden sehen, ob es Konflikte gibt, und können planen, wie diese gelöst werden können.
Danach können Sie entweder die Zusammenführung über Git abbrechen merge --abort
oder (wenn keine Konflikte aufgetreten sind und eine Zusammenführung stattgefunden hat) zum vorherigen Festschreiben über zurücksetzengit reset --hard HEAD~1