मैं एक गिट रीबेस के लिए मर्ज की रणनीति का चयन कैसे करूं?


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

जवाबों:


229

आप 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 --strategy पुनरावर्ती -X उनका
Gregg Lind

28
जब मैं यह कोशिश करता हूं, तो इसका अर्थ oursऔर theirsलगता है कि मैं जो अपेक्षा करता हूं उसके विपरीत है। मुझे theirsअपनी वर्तमान शाखा का पक्ष लेने के लिए उपयोग करने की आवश्यकता है ।
क्रेग मैकक्यून

19
@CraigMcQueen, जब रिबास का उपयोग करते हैं, तो आपके अप्रकाशित (अप्रकाशित) को एक तरफ रख दिया जाता है, शाखा को रिमोट (तेजी से अग्रेषित) के साथ संरेखित किया जाता है, और आपकी शाखा के शीर्ष पर आपके कमेंट्स को फिर से देखा जा सकता है। । मर्ज ऑपरेशन के अनुसार आपके कमिट "उनके" हैं, और स्थानीय शाखा की वर्तमान (तेजी से अग्रेषित) स्थिति "हमारी" है। शायद लगता है, लेकिन एक बार जब आप महसूस करते हैं कि वास्तव में क्या हो रहा है, तो यह समझ में आता है।
पेट्रिकबैनो

6
@patrikbeno: ओबी-वान केनबी को उद्धृत करने के लिए, "तो मैंने जो आपको बताया था वह एक निश्चित दृष्टिकोण से ... सच था।"
क्रेग मैकक्वीन

5
मुझे यकीन है कि यह की कीमत जोड़ने नहीं कर रहा हूँ, लेकिन कम से कम अपेक्षाकृत वर्तमान संस्करण में, की उपस्थिति -Xका अर्थ है -s recursive, इसलिए अब आप बस का उपयोग कर सकते git rebase ${branch} -X theirs। (स्रोत git-scm.com/docs/git-rebase#git-rebase--Xltstrategy-optiongt )
मैट Passell

20

यह मर्ज रणनीतियों के लिए है जो विकल्पों के अपने सेट के साथ आते हैं

git rebase <branch> -s recursive -X theirs

काम करना चाहिए, हालांकि इस पैच का उल्लेख है (फरवरी 2010):

मैनपेज का कहना है कि git-rebaseमर्ज की रणनीतियों का समर्थन करता है, लेकिन रिबेस कमांड इसके बारे में नहीं जानता है -X, और इसके साथ प्रस्तुत किए जाने पर उपयोग देता है।

तो अगर यह अभी भी काम नहीं करता है, यह अभी बहस हो रही है!
(हालिया गिट में समर्थित)


Db2b3b820e2b28da268cc88adff076b396392dfe (जुलाई 2013, git 1.8.4+) से अपडेट करें ,

इंटरैक्टिव रिबेस में मर्ज के विकल्पों को अनदेखा न करें

मर्ज की रणनीति और इसके विकल्पों को निर्दिष्ट किया जा सकता है git rebase, लेकिन इसके साथ -- interactive, उन्हें पूरी तरह से नजरअंदाज कर दिया गया।

साइन-ऑफ-बाय: अरनॉड फोंटेन

इसका मतलब है कि -Xरणनीति और रणनीति अब इंटरएक्टिव रिबेस के साथ-साथ सादे रिबास के साथ काम करते हैं।


1
@ चोंच: मुझे ऐसा लगा। इसलिए पैच प्रस्ताव के लिए मेरा लिंक।
वॉन

@ चोंच: हाँ, मैंने इस बग पर भी ध्यान दिया है - मुझे उम्मीद है कि इसे बहुत पहले से संबोधित किया जाएगा, चाहे वह पैच के साथ हो या अन्यथा, क्योंकि सभी बुनियादी सुविधाएं हैं; उन्हें बस यह तय करना होगा कि वे रिबेज से मर्ज करने के लिए कैसे संवाद करेंगे।
कास्कैब

@ चोंच: इसे 1.7.3 git में शामिल किया गया था। यदि आप अभी भी मेरे जैसे एक 1.7.1 उपयोगकर्ता हैं, तो एक आसान समाधान है, नीचे मेरे उत्तर की जांच करें
MestreLion

7

जैसा कि iCrazy ने कहा, यह सुविधा केवल 1.7.3 git के लिए उपलब्ध है। इसलिए, गरीब आत्माओं के लिए (मेरे जैसे) अभी भी 1.7.1 का उपयोग करते हुए, मैं एक समाधान प्रस्तुत करता हूं जो मैंने खुद किया था:

Git-रिबेस-उनकी

यह एक बहुत अच्छी तरह से पॉलिश की गई (और इस तरह लंबी) स्क्रिप्ट है, जिसका उपयोग उत्पादन उपयोग के लिए होता है: 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 का सिंटैक्स हाइलाइटिंग वास्तव में सबपर है, लेकिन यह वाया कुछ भी नहीं से बेहतर है। और आप बेहद विचारशील हैं! और, किया जा रहा है अतः में Git authorithy, आप अभी तक एक और सहायक लिपि में दिलचस्पी हो सकती है: stackoverflow.com/a/10220276/624066 । उस और मेरे गितुब खाते में ऐसे उपकरण हैं जिनका आप आनंद ले सकते हैं।
MestreLion

1.7.1 के लिए, यह मेरे लिए काम करता है; उपरोक्त स्क्रिप्ट की कोई आवश्यकता नहीं है। git rebase --strategy="recursive --theirs" master
पापाडेल्टासिएरा

एक नौसिखिया होने के लिए खेद है, लेकिन ऊपर दिए गए git-rebase-उनकी स्क्रिप्ट का उपयोग कोई कैसे करता है? क्या यह एक विकल्प है जो किसी तरह गिट-रिबेस के लिए पास किया जाता है या क्या यह केवल संघर्षों को मैन्युअल रूप से हल करने के लिए आवश्यक समय को कम करता है?
पापदेलतासिरा 10
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.