185 votes

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

git-rebase La page man mentionne -X<option> peut être transmis à git-merge . Quand/comment exactement ?

Je voudrais rebaser en appliquant des correctifs avec récursif stratégie et les leurs (appliquer ce qui colle, plutôt que de sauter des commits entiers en conflit). Je ne veux pas de fusion, je veux que l'histoire soit linéaire.

J'ai essayé :

git rebase -Xtheirs

y

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ées) après avoir résolu ces conflits.

0 votes

Remarque : cela fonctionne maintenant avec git rebase --interactive aussi. Voir ma réponse [mise à jour] ci-dessous ( stackoverflow.com/a/2945367/6309 ).

304voto

iCrazy Points 326

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

git rebase --strategy-option theirs ${branch} # Long option
git rebase -X theirs ${branch} # Short option

(qui est une abréviation de git rebase --strategy recursive --strategy-option theirs ${branch} comme indiqué par le documentation )

Extrait des notes de mise à jour de Git v1.7.3 :

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

NB : "Nos" et "leurs" signifient le contraire de ce qu'ils font lors d'une fusion directe. En d'autres termes, "leurs" favorise les commits sur le actuel branche.

7 votes

Pour clarifier : $ git rebase --strategie recursive -X leurs

0 votes

@iCrazy : alors, c'est -X theirs o -Xtheirs ? Habituellement, les arguments des options à 1 lettre sont concaténés à l'option elle-même. git est-il différent à cet égard ?

0 votes

De plus, pour les malheureux utilisateurs de git 1.7.1, consultez ma réponse pour trouver une solution.

24voto

VonC Points 414372

Il s'agit de stratégies de fusion qui s'accompagnent de leur propre série d'options.

git rebase <branch> -s recursive -X theirs

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

La page de manuel dit que git-rebase supporte les stratégies de fusion, mais le rebasement n'est pas au courant de -X et en donne l'usage lorsqu'on le lui présente.

Alors si ça ne marche toujours pas, c'est en ce moment même qu'on en débat !
(supporté dans les git récents)


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

Ne pas ignorer les options de fusion dans le rebasement interactif

La stratégie de fusion et ses options peuvent être spécifiées dans l'onglet git rebase mais avec -- interactive ils ont été complètement ignorés.

Signé par : Arnaud Fontaine

Cela signifie que -X et la stratégie fonctionnent maintenant avec le rebasement interactif, ainsi que le rebasement simple.

1 votes

@porneL : C'est ce que je pensais. D'où mon lien vers la proposition de patch.

0 votes

@porneL : Oui, j'ai remarqué ce bug aussi - je pense qu'il sera corrigé avant longtemps, que ce soit avec ce patch ou autrement, puisque toutes les facilités de base sont là ; ils doivent juste décider exactement comment ils vont communiquer de la rebase à la fusion.

0 votes

@porneL : il a été inclus dans git 1.7.3. Si vous êtes encore un utilisateur de la version 1.7.1 comme moi, il y a une solution facile, consultez ma réponse ci-dessous

7voto

MestreLion Points 1789

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

git-rebase-theirs

Il s'agit d'un script très bien conçu (et donc long), destiné à une utilisation en production : options de l'interface utilisateur, gestion de fichiers multiples, vérification si le fichier a effectivement 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) <linux@rodrigosilva.com>
#
#    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) <linux@rodrigosilva.com>
    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

0 votes

Merci @VonC ! Je ne sais juste pas pourquoi SO n'a pas donné un code couleur au script de bash. Un gros script comme celui-ci est toujours laid en soi... mais être une énorme masse de texte noir le rend encore plus laid :P

0 votes

Il est expliqué dans stackoverflow.com/editing-help#syntax-highlighting . J'ai ajouté le code approprié de la langue prettify avant votre bloc de code. Cela devrait être mieux maintenant.

0 votes

Merci @VonC ! La coloration syntaxique de SO est vraiment médiocre, mais c'est beaucoup mieux que rien. Et vous êtes extrêmement réfléchi ! Et, étant LE git authorithy dans SO, vous serez peut-être intéressé par une autre aide script : stackoverflow.com/a/10220276/624066 . Ce site et mon compte Github contiennent des outils que vous pourriez apprécier.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X