2010-05-31 8 views
105

git-rebase la pagina man menziona -X<option> può essere passato a git-merge. Quando/come esattamente?Come si seleziona una strategia di unione per un rebase git?

mi piacerebbe rebase per l'applicazione delle patch con ricorsivo strategia e loro opzione (a qualunque attacca, invece di saltare tutto il conflitto si impegna). Non voglio unirmi, voglio rendere lineare la storia.

ho provato:

git rebase -Xtheirs 

e

git rebase -s 'recursive -Xtheirs' 

ma git respinge -X in entrambi i casi.


git rebase -Xtheirs opere nelle versioni più recenti, ad eccezione di conflitti d'albero devono essere risolti manualmente. È necessario eseguire git rebase -Xtheirs --continue (con -X ripetuto) dopo aver risolto tali conflitti.

+0

Nota: ora funziona anche con 'git rebase --interactive'. Vedi la mia [risposta aggiornata di seguito (http://stackoverflow.com/a/2945367/6309). – VonC

risposta

154

È possibile utilizzare questo con Git v1.7.3 o versioni successive.

git rebase -s recursive -X theirs ${branch} 

Da Git v1.7.3 Note di rilascio:

git rebase --strategy <s> imparato l'opzione -X di passare opzioni aggiuntive che sono capiti dalla strategia prescelta merge.

NB: "I nostri" e "loro" significano il contrario di ciò che fanno durante una fusione diretta. In altre parole, "loro" favorisce il commit sul ramo corrente corrente.

Aggiornamento: Modificato per essere più chiaro.

+3

per chiarire: $ git rebase --strategy recursive -X loro –

+0

@iCrazy: quindi, è '-X loro ' o '-Xtheirs'? Di solito gli argomenti delle opzioni a 1 lettera sono concatenati all'opzione stessa .. è diverso in questo senso? – MestreLion

+0

Inoltre, per gli sfortunati utenti di 1.7.1 git, controlla la mia risposta per una soluzione – MestreLion

13

Questo è per le strategie di unione che vengono con il proprio set di opzioni

git rebase <branch> -s recursive -X theirs 

dovrebbe funzionare, anche se this patch mentions (febbraio 2010):

La pagina del manuale dice che git-rebase supporti fondono strategie, ma il comando rebase non sa di -X e fornisce l'utilizzo quando viene presentato.

Quindi se ancora non funziona, è stato discusso in questo momento!
(supportato in recente git)


Aggiornamento da commit db2b3b820e2b28da268cc88adff076b396392dfe (luglio 2013, git 1.8.4+),

Non ignorare fondono opzioni in rebase interattivo strategia

Merge e le sue opzioni possono essere specificate in git rebase, ma con -- interactive, sono state completamente ignorate.

Firmato-fuori-da: Arnaud Fontaine

Ciò significa -X e la strategia ora lavorare con rebase interattivo, così come rebase pianura.

+0

'-X theirs' (con spazio) non ha funzionato in git 1.7.1. – Kornel

+1

@porneL: l'ho pensato. Da qui il mio link alla proposta di patch. – VonC

+0

@porneL: Sì, ho notato anche questo errore - mi aspetto che possa essere affrontato a lungo, anche se con quella patch o in altro modo, dal momento che tutte le strutture di base sono lì; devono solo decidere esattamente come comunicheranno da rebase a unirsi. – Cascabel

4

Come detto iCrazy, questa funzione è disponibile solo per git 1.7.3 in poi. Così, per le povere anime (come me) ancora utilizzando 1.7.1, vi presento una soluzione che ho fatto io:

git-rebase-theirs

E 'molto ben lucidato (e quindi a lungo) di script, pensato per la produzione uso: le opzioni di interfaccia utente, gestisce più file, controllare se il file in realtà ha marcatori di conflitto, ecc, ma il "cuore" potrebbe essere riassunto in 2 linee:

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

E qui è lo script completo:

#!/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+=("[email protected]") 

(("${#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

Grazie a @VonC! Non sono sicuro del perché SO non abbia codificato a colori lo script di bash. Un copione di questo tipo è sempre brutto da solo ... ma essere una massa enorme di testo nero lo rende ancora più brutto: P – MestreLion

+0

È spiegato in http://stackoverflow.com/editing-help#syntax-highlighting. Ho aggiunto il codice della lingua di prefazione appropriato prima del blocco del codice. Dovrebbe sembrare migliore ora. – VonC

+0

Grazie a @VonC! L'evidenziazione della sintassi di SO è davvero scadente, ma è molto meglio di niente. E tu sei estremamente premuroso! E, essendo * THE * git authorithy in SO, potresti essere interessato a un altro script helper: http://stackoverflow.com/a/10220276/624066. Quello e il mio account github hanno strumenti che potrebbero piacerti. – MestreLion