2016-06-06 9 views
3

Ich möchte wissen, ob eine bestimmte Zusammenführung wird über "Fast-Forward" oder nicht vor dem Zusammenführen Befehl lösen.Ermitteln, ob eine Zusammenführung durch Schnellvorlauf aufgelöst wird

Ich weiß, dass ich speziell verlangen kann, dass die Zusammenführung nicht über "Schnellvorlauf" aufgelöst wird (mit der --no-ff Option). Oder dass ich versuchen kann, die Zusammenführung nur durch Schnellvorlauf zu lösen (mit der Option --ff).

Aber manchmal möchte ich wissen, ob eine bestimmte Zusammenführung über Fast-Forward auflösen wird, bevor ich es ausführe. Ich realisiere, dass ich es theoretisch durcharbeiten kann, indem ich den Geschichtsbaum durchforste. Und ich merke auch, dass ich die Zusammenführung ausführen und sehen könnte, was passiert, aber das wird problematisch, wenn ich dann entscheide, dass die Zusammenführung auf andere Weise aufgelöst wird, da ich die Zusammenführung rückgängig machen muss (indem ich die Verzweigungs-Tags neu verweise) im ref-log) und mach es noch einmal.

HINWEIS: Die --dry-run Frage (Is there a git-merge --dry-run option?) ist viel mehr darüber zu betrachten, welche Merge-Konflikte in einer Zusammenführung vorhanden sein können, und nicht über Zusammenführungen, die über Fast-Forward aufgelöst werden können.

+0

Mögliche Duplikate von [Gibt es einen Git -merge --dry-run Option?] (http://stackoverflow.com/questions/501407/is-there-a-git-merge-dry-run-option) – Vishwanath

Antwort

2

Zusammenfassung: git merge-base --is-ancestor testet, ob ein Commit ein Vorfahre eines anderen ist (wobei commits als eigene Vorfahren betrachtet werden, was eine besonders komische Form von Inzest ist, vielleicht :-)). Da ein Verzweigungsetikett nur von git merge weitergeleitet werden kann, wenn der aktuelle Zweig (HEAD) auf einen Commit verweist, der ein Vorgänger des anderen Commits ist, können wir damit ermitteln, ob git merge einen schnellen Vorlauf ausführen kann.

Es sieht so aus, als wolltest du dies als Antwort gepostet haben, also habe ich es in einen funktionierenden Git-Alias ​​umgewandelt, den du in deine globale Git-Konfiguration einfügen kannst.Der Alias ​​ist ein bisschen lang und kompliziert, und es wäre wahrscheinlich am besten sein, nur cut-and-paste dieses Abschnitt in Ihrem git config-Alias:

canff = "!f() { if [ $# -gt 0 ]; then b=\"$1\"; git rev-parse -q --verify \"$b^{commit}\" >/dev/null || { printf \"%s: not a valid commit specifier\n\" \"$b\"; return 1; } else b=$(git rev-parse --symbolic-full-name --abbrev-ref @{u}) || return $?; fi; if git merge-base --is-ancestor HEAD \"$b\"; then echo \"merge with $b can fast-forward\"; else echo \"merge with $b cannot fast-forward\"; fi; }; f" 

Hier ist das gleiche wie ein Shell-Skript geschrieben, in einem mehr lesbare Art und Weise, und einige Kommentare:

#! /bin/sh 
# 
# canff - test whether it is possible to fast-forward to 
# a given commit (which may be a branch name). If given 
# no arguments, find the upstream of the current (HEAD) branch. 

# First, define a small function to print the upstream name 
# of the current branch. If no upstream is set, this prints a 
# message to stderr and returns with failure (nonzero). 
upstream_name() { 
    git rev-parse --symbolic-full-name --abbrev-ref @{u} 
} 

# Now define a function to detect fast-forward-ability. 
canff() { 
    local b # branch name or commit ID 

    if [ $# -gt 0 ]; then # at least 1 argument given 
     b="$1" 
     # make sure it is or can be converted to a commit ID. 
     git rev-parse -q --verify "$b^{commit}" >/dev/null || { 
      printf "%s: not a valid commit specifier\n" "$b" 
      return 1 
     } 
    else 
     # no arguments: find upstream, or bail out 
     b=$(upstream_name) || return $? 
    fi 
    # now test whether git merge --ff-only could succeed on $b 
    if git merge-base --is-ancestor HEAD "$b"; then 
     echo "merge with $b can fast-forward" 
    else 
     echo "merge with $b cannot fast-forward" 
    fi 
} 

das Shell-Skript braucht nur einen Hauptteil, es zu fahren, die der Aufruf von f nach dem Alias ​​ist. Der Alias ​​selbst schaufelt einfach alles von canff und upstream_name in eine Zeile. Git's Konfigurationsdateiregeln erfordern dann, dass der gesamte Alias ​​mit Anführungszeichen in Anführungszeichen gesetzt wird, was wiederum erfordert, dass alle internen Anführungszeichen in Backslash-Anführungszeichenfolgen konvertiert werden.

(Ich habe auch aus der local b Aussage, da als Alias, das jedes Mal eine neue Instanz der Schale löst, also Variablenname Hygiene wird unwichtig.)

(es ist tatsächlich möglich, das schreiben Alias ​​als mehrere Zeilen.Klicken Sie einfach jeder neuen Zeile Backslash voran.Jedoch ist dieser Alias ​​so komplex, dass er auch auf diese Weise hässlich aussieht, also habe ich ihm nur eine große Zeile hinterlassen.)

0

Es gibt eine ähnliche, aber nicht ganz gleich, Frage hier gestellt: Is there a git-merge --dry-run option?

Die erste Antwort sieht aus wie es sein könnte, was Sie suchen.

Speziell eine merge mit der --no-commit Flagge und mit --abort, wenn Sie genug gesehen haben und zurückgehen wollen und die eigentliche Zusammenführung tun.

1

Sie könnten testen, ob gleich git rev-parse <branch1> ist. Wenn es gleich ist, ein ff merge oder bereits up-to-date, wenn Sie git merge <branch1> <branch2> ausführen. Wenn nicht, fusionieren Sie nicht.

function isff(){ 
a=$(git merge-base $1 $2) 
b=$(git rev-parse $1) 
c=$(git rev-parse $2) 
if [[ "$b" == "$c" ]] || [[ "$a" == "$c" ]];then 
    echo merge dry run: already up-to-date 
    return 
fi 
if [ "$a" == "$b" ];then 
    echo merge dry run: a fast forward merge 
else 
    echo merge dry run: a non fast forward merge 
fi 
} 

isff master topic

+1

Simpler (obwohl Sie nicht "schon geben" up-to-date "Fall, nur" kann schnell vorspulen "): einen Test machen, 'git merge-base - ist-Vorfahr HEAD Ziel && Echo kann schnell vorspulen. – torek

+0

Ich bin nicht wirklich besorgt über den Fall von Zusammenführungen, die bereits auf dem neuesten Stand sind: das ist mir normalerweise schon klar. @torek hat die beste Lösung für mein Problem. Wenn Sie das als vollständige Antwort verwenden, akzeptiere ich es. – uayebforever

0

bei der Frage nach @ verwiesen Suche Ashwin-Nair, fand ich, was ich glaube, eine Antwort ist.

Für

git checkout MY_BRANCH 
git merge OTHER_BRANCH 

Wenn die Ausgabe von

git branch --contains MY_BRANCH 

enthält OTHER_BRANCH, dann kann eine Fusion mit OTHER_BRANCH über vorspulen gelöst werden.

+0

Dieser Befehl deckt nicht alle Anwendungsfälle ab – yorammi