web-dev-qa-db-fra.com

Comment sélectionner une stratégie de fusion pour un rebase git?

git-rebase la page de manuel mentionne -X<option> peut être passé à git-merge. Quand/comment exactement?

Je voudrais rebaser en appliquant des correctifs avec stratégie récursive et la leur option (appliquez ce que vous voulez, plutôt que de sauter des commits contradictoires). Je ne veux pas fusionner, je veux rendre l'histoire linéaire.

J'ai essayé:

git rebase -Xtheirs

et

git rebase -s 'recursive -Xtheirs'

mais git rejette -X dans les deux cas.


git rebase -Xtheirs fonctionne dans les versions récentes, sauf que les conflits d’arbres doivent être résolus manuellement. Vous devez exécuter git rebase -Xtheirs --continue (avec -X répété) après la résolution de ces conflits.

129
Kornel

Vous pouvez l'utiliser avec Git v1.7.3 ou des versions ultérieures.

git rebase -X theirs ${branch}

(qui est un raccourci pour git rebase -s recursive -X theirs ${branch} comme indiqué par le documentation )

Depuis Git v1.7.3 Notes de publication:

git rebase --strategy <s> a appris le -X option pour passer des options supplémentaires comprises par la stratégie de fusion choisie.

NB: "Le nôtre" et "le leur" signifient l’opposé de ce qu’ils font lors d’une fusion simple. En d’autres termes, "le leur" favorise les commets sur la actuelle branche.

207
iCrazy

Ceci est pour les stratégies de fusion qui viennent avec leur propre ensemble d'options

git rebase <branch> -s recursive -X theirs

devrait fonctionner, bien que ce correctif mentionne (février 2010):

La page de manuel indique que git-rebase Prend en charge les stratégies de fusion, mais la commande rebase ne connaît pas -X, Et donne l’utilisation qui s’y accompagne.

Donc, si cela ne fonctionne toujours pas, il fait actuellement l'objet d'un débat!
(supporté par git récent)


Mise à jour de commit db2b3b820e2b28da268cc88adff076b396392dfe (juillet 2013, git 1.8.4+),

Ne pas ignorer les options de fusion dans une base interactive

La stratégie de fusion et ses options peuvent être spécifiées dans git rebase, Mais avec -- interactive, Elles ont été complètement ignorées.

Signé par: Arnaud Fontaine

Cela signifie que -X Et que la stratégie fonctionnent maintenant avec une base interactive, ainsi que une base simple.

19
VonC

Comme iCrazy , cette fonctionnalité n’est disponible qu’à partir de git 1.7.3. Donc, pour les pauvres âmes (comme moi) qui utilisent encore la version 1.7.1, je présente une solution que je me suis faite:

git-rebase-eux

C'est un script très soigné (et donc long), destiné à une utilisation en production: options ui, gère plusieurs fichiers, vérifie si le fichier a réellement des marqueurs de conflit, etc., mais le "noyau" pourrait être résumé en 2 lignes:

cp file file.bak
awk '/^<+ HEAD$/,/^=+$/{next} /^>+ /{next} 1' file.bak > file

Et voici le script complet:

#!/bin/bash
#
# git-rebase-theirs - Resolve rebase conflicts by favoring 'theirs' version
#
#    Copyright (C) 2012 Rodrigo Silva (MestreLion) <[email protected]>
#
#    This program is free software: you can redistribute it and/or modify
#    it under the terms of the GNU General Public License as published by
#    the Free Software Foundation, either version 3 of the License, or
#    (at your option) any later version.
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU General Public License for more details.
#
#    You should have received a copy of the GNU General Public License
#    along with this program. If not see <http://www.gnu.org/licenses/gpl.html>

#Defaults:
verbose=0
backup=1
inplace=0
ext=".bak"

message() { printf "%s\n" "$1" >&2 ; }
skip()    { message "skipping ${2:-$file}${1:+: $1}"; continue ; }
argerr()  { printf "%s: %s\n" "$myname" "${1:-error}" >&2 ; usage 1 ; }
invalid() { argerr "invalid option: $1" ; }
missing() { argerr "missing${1:+ $1} operand." ; }

usage() {
    cat <<- USAGE
    Usage: $myname [options] [--] FILE...
    USAGE
    if [[ "$1" ]] ; then
        cat >&2 <<- USAGE
        Try '$myname --help' for more information.
        USAGE
        exit 1
    fi
    cat <<-USAGE

    Resolve git rebase conflicts in FILE(s) by favoring 'theirs' version

    When using git rebase, conflicts are usually wanted to be resolved
    by favoring the <working branch> version (the branch being rebased,
    'theirs' side in a rebase), instead of the <upstream> version (the
    base branch, 'ours' side)

    But git rebase --strategy -X theirs is only available from git 1.7.3
    For older versions, $myname is the solution.

    It works by discarding all lines between '<<<<<<< HEAD' and '========'
    inclusive, and also the the '>>>>>> commit' marker.

    By default it outputs to stdout, but files can be edited in-place
    using --in-place, which, unlike sed, creates a backup by default.

    Options:
      -h|--help            show this page.
      -v|--verbose         print more details in stderr.

      --in-place[=SUFFIX]  edit files in place, creating a backup with
                           SUFFIX extension. Default if blank is ""$ext"

       --no-backup         disables backup

    Copyright (C) 2012 Rodrigo Silva (MestreLion) <[email protected]>
    License: GPLv3 or later. See <http://www.gnu.org/licenses/gpl.html>
    USAGE
    exit 0
}
myname="${0##*/}"

# Option handling
files=()
while (( $# )); do
    case "$1" in
    -h|--help     ) usage            ;;
    -v|--verbose  ) verbose=1        ;;
    --no-backup   ) backup=0         ;;
    --in-place    ) inplace=1        ;;
    --in-place=*  ) inplace=1
                    suffix="${1#*=}" ;;
    -*            ) invalid "$1"     ;;
    --            ) shift ; break    ;;
    *             ) files+=( "$1" )  ;;
    esac
    shift
done
files+=( "$@" )

(( "${#files[@]}" )) || missing "FILE"

ext=${suffix:-$ext}

for file in "${files[@]}"; do

    [[ -f "$file" ]] || skip "not a valid file"

    if ((inplace)); then
        outfile=$(tempfile) || skip "could not create temporary file"
        trap 'rm -f -- "$outfile"' EXIT
        cp "$file" "$outfile" || skip
        exec 3>"$outfile"
    else
        exec 3>&1
    fi

    # Do the magic :)
    awk '/^<+ HEAD$/,/^=+$/{next} /^>+ /{next} 1' "$file" >&3

    exec 3>&-

    ((inplace)) || continue

    diff "$file" "$outfile" >/dev/null && skip "no conflict markers found"

    ((backup)) && { cp "$file" "$file$ext" || skip "could not backup" ; }

    cp "$outfile" "$file" || skip "could not edit in-place"

    ((verbose)) && message "resolved ${file}"
done
6
MestreLion