2012-06-12 10 views
30

Gibt es eine Möglichkeit, eine Zusammenführung anzuzeigen, die bereits in einem 3-Wege-Vergleich festgeschrieben wurde?Bereits festgeschriebene Git-Zusammenführung in externem 3-Wege-Diff-Tool anzeigen

Wenn eine große merge zwischen den Zweigen vor 3 Wochen begangen wurde, ist es eine Möglichkeit, einen 3-Wege-diff davon in einem externen diff-Tool wie BeyondCompare3 sehen kann? Ich bin auf der Suche nach nur die Dateien in der Zusammenführung Commit geändert. Bonus, wenn ich es bekommen könnte, um mir nur die Konflikte und irgendetwas manuell geändert anzuzeigen, im Gegensatz zu den ganzen Unterschied einer Datei zwischen den zwei Zweigen zu sehen.

würde ich nicht für einen 2-Wege-diff Einschwingzeit dagegen, wenn die linke Seite den < < < < ===== >>>>> Konfliktmarken < hatte und die rechte Seite war das engagierte Ergebnis.

habe ich versucht, bei diff-Baum suchen, diff-Dateien, diff, difftool, zeigen und andere und konnte es nicht herausgefunden. Ich weiß, dass gitk die Änderungen nur im Merge-Commit zeigt, aber ich mag die Over-under-Diff-Ansicht nicht und es ist sehr schwer zu verstehen, wenn es viele Änderungen gibt.

Wenn ich nur etwas tun könnte, wie git difftool --cc firstparent..secondparent..result

Antwort

2

Ich weiß nicht, wie ohne einige Hacks einen Drei-Wege-diff in git zu tun, aber für einen Zwei-Wege-diff ich meld verwenden würde. meld ist in der Lage, einen Drei-Wege-Vergleich durchzuführen, wenn Sie die drei verschiedenen Versionen Ihres Projekts auschecken, einen neuen Vergleich nach Verzeichnis vornehmen und die Option "Drei-Wege-Vergleich" auswählen.

Zuerst installieren meld

sudo apt-get install meld

Dann setzen meld als difftool

git config --global diff.tool meld

finden die Commits

git log | more

Öffnen Sie die Commits

git difftool <old-version>..HEAD

6

Aktualisiert Antwort: Meine ursprüngliche Version des Skripts unten wurde im Sinne fehlerhaft, dass $conflicting_files in der Tat nicht nur die Dateien enthalten haben, die wirklich Konflikte hatte, aber alle Dateien, die geändert wurden in beiden Elternteilen (hatte aber nicht unbedingt Konflikte). Außerdem verwendete es nicht das "konfigurierte Zusammenführungswerkzeug", wie in der Begründung angegeben, sondern diffuse. Ich habe beide Probleme in der current version of the script angesprochen.

Ursprüngliche Antwort: Angenommen, wir haben einen „Master“ Zweig mit die wichtigste Entwicklung im Gange, und ein „Thema“ Zweig, der an der Spitze von einigen (älteren) Zustand der Master eine Funktion hinzufügt.Wenn Sie sagen, dass Sie nur nach den Dateien suchen, die im Merge-Commit geändert wurden, nehme ich an, dass Sie nur an den Änderungen interessiert sind, die in "Master" im Zusammenführungs-Commit (einschließlich einer Konfliktlösung) eingeführt wurden. widersprüchliche Änderungen, die in "Master" vorgenommen wurden, da "Thema" verzweigt war. Die Weitere davon aus, dass „Master“ ist die erste Mutter Ihrer merge begehen und „Thema“ ist die zweite, kann dies mit

git difftool <merge commit>^1 <merge commit> 

Hinweis erreicht wird, dass es nicht sinnvoll, einen 3-Wege-diff hier zu verwenden, macht als Wir betrachten den Zustand, der enthält keine Konfliktlösung. Dies zeigt auch, was GitHub für Merge-Commits zeigt, siehe z. this merge commit die ich zum Testen benutzt habe.

Um nur die widerstreitenden Dateien und die Lösungen in einem 3-Wege-diff Werkzeug, das ich mit diesem Skript

#!/bin/sh 

if [ $# -ne 1 ]; then 
    echo "Rationale : Show the conflict resolution of a given merge commit in the configured merge tool." 
    echo "Usage : $(basename $0) <merge commit>" 
    exit -1 
fi 

# Test e.g. with https://github.com/git/git/commit/8cde60210dd01f23d89d9eb8b6f08fb9ef3a11b8 
our=$1^1 
their=$1^2 
base=$(git merge-base $our $their) 

conflicting_files=$(git merge-tree $base $our $their | grep -A 3 "changed in both" | grep "base" | grep -Po "[^\s]+$") 
for f in $conflicting_files; do 
    diffuse -r $our -r $base -r $their $f 
done 

kam zu sehen, ich bin Diffuse statt Beyond Compare verwenden, da die ersten direkt arbeiten kann auf Git verpflichtet im Gegensatz zu lokalen Dateien; Ändern Sie die Reihenfolge der Argumente nach Ihren Wünschen. Um BC zu verwenden, müssen Sie wahrscheinlich temporäre Auscheckvorgänge durchführen. Ich habe auch darüber nachgedacht, die Zusammenführung zu wiederholen, die bekannte Auflösung anzuwenden und auszuführen, was auch immer git mergetool konfiguriert ist, aber beide dieser Ideen würden mehr Arbeit erfordern, um Ihren Arbeitsbaum nicht zu verwirren und die Aufräumarbeiten richtig zu machen.

+0

+1 für diffuse, könnte es sogar eine 4-Wege-Diff mit verschiedenen Commits tun – Johan

0

Wie sschuberth, schrieb ich ein Skript, das mir half, eine Änderung in einem Merge-Commit zu finden. Es funktioniert mit einer einzigen Datei gleichzeitig mit vimdiff, um die Unterschiede zwischen Eltern und Zusammenführung zu zeigen.

#! /usr/bin/env ruby 

require 'pp' 
require 'tmpdir' 

merge = ARGV[0] || abort("I need a merge commit as the first argument") 
file = ARGV[1] || abort("I need a path as the second argument") 
cmd = "vimdiff" 

commits = `git log -n 1 #{merge} --format="%H %P"`.split(' ') 
abort "expected three commits" unless commits.size == 3 
commits[0], commits[1] = commits[1], commits[0] 
tmpdir = Dir.mktmpdir 
commits.each do |commit| 
    tfile = "#{tmpdir}/#{commit[0..10]}" 

    puts "git show #{commit}:./#{file} > #{tfile}" 
    `git show #{commit}:./#{file} > #{tfile}` 
    cmd += " #{tfile}" 
end 
puts cmd 
exec(cmd) 

Es ist ein bisschen hacky, aber ich postete es in der Off-Chance, es hilft jemandem.