ฉันจะเลือกกลยุทธ์การรวมเพื่อรีบูต git ได้อย่างไร


147

git-rebaseหน้าคนกล่าวสามารถส่งผ่านไป-X<option> git-mergeเมื่อไหร่ / อย่างไร

ฉันต้องการรีบูตด้วยการใช้แพตช์กับกลยุทธ์แบบเรียกซ้ำและตัวเลือกของพวกเขา (ใช้สิ่งใดก็ได้แทนที่จะใช้การคอมมิชชันที่ขัดแย้งกันทั้งหมด) ฉันไม่ต้องการรวมฉันต้องการสร้างประวัติศาสตร์เชิงเส้น

ฉันพยายามแล้ว:

git rebase -Xtheirs

และ

git rebase -s 'recursive -Xtheirs'

แต่คอมไพล์ปฏิเสธ-Xทั้งสองกรณี


git rebase -Xtheirsทำงานในรุ่นล่าสุดยกเว้นความขัดแย้งของต้นไม้จะต้องได้รับการแก้ไขด้วยตนเอง คุณต้องเรียกใช้git rebase -Xtheirs --continue( -Xซ้ำ) หลังจากแก้ไขข้อขัดแย้งเหล่านั้นแล้ว


หมายเหตุ: ตอนนี้ใช้ได้กับgit rebase --interactiveด้วย ดู [คำตอบอัพเดทด้านล่างของฉัน ( stackoverflow.com/a/2945367/6309 )
VonC

คำตอบ:


230

คุณสามารถใช้สิ่งนี้กับ Git v1.7.3 หรือรุ่นที่ใหม่กว่า

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

(ซึ่งย่อมาgit rebase --strategy recursive --strategy-option theirs ${branch}จากเอกสารที่ระบุไว้)

จากบันทึกประจำรุ่น Git v1.7.3:

git rebase --strategy <s>เรียนรู้--strategy-option/ -Xตัวเลือกในการส่งตัวเลือกเพิ่มเติมที่เข้าใจโดยกลยุทธ์การผสานที่เลือก

หมายเหตุ: "ของเรา" และ "ของพวกเขา" หมายถึงสิ่งที่ตรงกันข้ามกับสิ่งที่พวกเขาทำในระหว่างการรวมกัน กล่าวอีกนัยหนึ่ง "พวกเขา" สนับสนุนการกระทำในสาขาปัจจุบัน


6
การชี้แจง: $ git rebase - กลยุทธ์ recursive -X พวกเขา
Gregg Lind

28
เมื่อฉันลองทำสิ่งนี้ความหมายoursและtheirsดูเหมือนจะตรงกันข้ามกับที่ฉันคาดไว้ ฉันต้องใช้theirsเพื่อสนับสนุนสาขาปัจจุบันของฉัน
Craig McQueen

19
@CraigMcQueen เมื่อใช้ rebase คอมมิชชันที่ไม่ได้เผยแพร่ (ไม่ได้กด) ของคุณจะถูกวางไว้สาขาจะจัดตำแหน่งด้วยรีโมต (ส่งต่ออย่างรวดเร็ว) และคอมมิชชันของคุณจะถูกเล่นซ้ำที่ด้านบนสุดของสาขาของคุณ . ความมุ่งมั่นของคุณคือ "พวกเขา" ตามการดำเนินการผสานและสถานะปัจจุบันของสาขาท้องถิ่นคือ "ของเรา" อาจดูขัดกับความเป็นจริง แต่เมื่อคุณตระหนักถึงสิ่งที่เกิดขึ้นจริงแล้วมันก็สมเหตุสมผล
patrikbeno

6
@patrikbeno: พูดถึงโอบิวันเคโนบี "ดังนั้นสิ่งที่ฉันบอกคุณก็คือความจริง ... จากมุมมองที่กำหนด"
Craig McQueen

5
ฉันไม่แน่ใจว่ามันคุ้มค่าที่จะเพิ่ม แต่อย่างน้อยก็ในเวอร์ชั่นปัจจุบันการมีอยู่ของ-Xนัย-s recursiveซึ่งตอนนี้คุณสามารถใช้งานgit rebase ${branch} -X theirsได้แล้ว (source git-scm.com/docs/git-rebase#git-rebase--Xltstrategy-optiongt )
Matt Passell

20

นี่เป็นกลยุทธ์การรวมที่มาพร้อมกับตัวเลือกชุดของตัวเอง

git rebase <branch> -s recursive -X theirs

ควรทำงานได้แม้ว่าโปรแกรมแก้ไขนี้จะกล่าวถึง (กุมภาพันธ์ 2010):

manpage บอกว่าgit-rebaseสนับสนุนกลยุทธ์การรวม แต่คำสั่ง rebase ไม่ทราบ-Xและให้การใช้งานเมื่อนำเสนอด้วย

ดังนั้นหากยังใช้งานไม่ได้แสดงว่ามีการโต้วาทีแล้ว!
(รองรับในคอมไพล์ล่าสุด)


อัปเดตจากการกระทำ db2b3b820e2b28da268cc88adff076b396392dfe (กรกฎาคม 2013, คอมไพล์ 1.8.4+),

อย่าเพิกเฉยตัวเลือกการผสานในการรีบูตแบบโต้ตอบ

กลยุทธ์การผสานและตัวเลือกที่สามารถจะระบุไว้ในgit rebaseแต่มี-- interactiveพวกเขาถูกละเว้นสมบูรณ์

ลงชื่อออกโดย: Arnaud Fontaine

นั่นหมายถึง-Xและกลยุทธ์ตอนนี้ทำงานร่วมกับ rebase แบบโต้ตอบเช่นเดียวกับ rebase ธรรมดา


1
@porneL: ฉันคิดอย่างนั้น ดังนั้นลิงก์ของฉันไปยังข้อเสนอแพทช์
VonC

@ PorneL: ใช่ฉันได้สังเกตเห็นข้อผิดพลาดนี้ด้วย - ฉันคาดหวังว่ามันจะได้รับการแก้ไขก่อนหน้านี้ไม่ว่าจะมีการแก้ไขหรืออย่างอื่นเนื่องจากสิ่งอำนวยความสะดวกขั้นพื้นฐานทั้งหมดอยู่ที่นั่น; พวกเขาเพียงแค่ต้องตัดสินใจอย่างชัดเจนว่าพวกเขาจะสื่อสารกันอย่างไรตั้งแต่การรีบูตจนถึงการรวม
Cascabel

@porneL: มันรวมอยู่ในคอมไพล์ 1.7.3 หากคุณยังคงเป็นผู้ใช้ 1.7.1 อย่างฉันมีวิธีแก้ปัญหาง่ายๆให้ตรวจสอบคำตอบของฉันด้านล่าง
MestreLion

7

ตามที่iCrazyกล่าวว่าคุณลักษณะนี้มีให้สำหรับ git 1.7.3 เป็นต้นไปเท่านั้น ดังนั้นสำหรับคนจน (อย่างฉัน) ที่ยังใช้ 1.7.1 อยู่ฉันขอเสนอวิธีแก้ปัญหาด้วยตัวเอง:

-git rebase-พวกเขา

มันเป็นสคริปที่ดี (และยาวมาก) ซึ่งมีความหมายสำหรับการใช้งานจริง: ตัวเลือก ui จัดการหลายไฟล์ตรวจสอบว่าไฟล์มีตัวทำเครื่องหมายขัดแย้งกันหรือไม่ แต่สามารถสรุป "คอร์" ได้ใน 2 บรรทัด:

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

และนี่คือสคริปต์แบบเต็ม:

#!/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

ขอบคุณ @VonC! ฉันแค่ไม่แน่ใจว่าทำไมจึงไม่ได้รหัสสีทุบตี สคริปต์ขนาดใหญ่แบบนี้มักจะน่าเกลียดอยู่เสมอ ... แต่การที่ตัวอักษรสีดำจำนวนมากทำให้มันน่าเกลียดยิ่งขึ้น: P
MestreLion

มันจะมีการอธิบายในstackoverflow.com/editing-help#syntax-highlighting ฉันได้เพิ่มรหัสภาษาที่เหมาะสมไว้ก่อนหน้าบล็อกรหัสของคุณ มันควรจะดูดีขึ้นในขณะนี้
VonC

ขอบคุณ @VonC! การเน้นไวยากรณ์ของ SO นั้น subpar จริง ๆ แต่มัน waaaay ดีกว่าไม่มีอะไร และคุณมีน้ำใจอย่างมาก! และเป็นauthorithy คอมไพล์ในดังนั้นคุณอาจจะสนใจในบทผู้ช่วยอีก: stackoverflow.com/a/10220276/624066 นั่นและบัญชี GitHub ของฉันมีเครื่องมือที่คุณสามารถเพลิดเพลินได้
MestreLion

สำหรับ 1.7.1 นี่ดูเหมือนจะใช้ได้สำหรับฉัน ไม่จำเป็นสำหรับสคริปต์ด้านบน git rebase --strategy="recursive --theirs" master
Papadeltasierra

ขออภัยที่เป็น git สามเณร แต่มีวิธีการใช้สคริปต์ git-rebase-พวกเขาได้รับด้านบน เป็นตัวเลือกหรือไม่ที่ถูกส่งผ่านไปยัง git-rebase หรือลดเวลาที่ต้องใช้ในการแก้ไขข้อขัดแย้งด้วยตนเอง
Papadeltasierra
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.