2010-05-31 105 views
105

git-rebase手冊頁提到-X<option>可以傳遞給git-merge。何時/如何?如何爲git rebase選擇合併策略?

我想通過應用修補程序與遞歸戰略和他們選項(適用任何棒,而不是跳過整個衝突的承諾)衍合。我不想合併,我想讓歷史線性化。

我已經試過:

git rebase -Xtheirs 

git rebase -s 'recursive -Xtheirs' 

但混帳拒絕在這兩種情況下-X


git rebase -Xtheirs在最近的版本中工作,除了樹衝突需要手動解決。解決這些衝突後,您需要運行git rebase -Xtheirs --continue(重複執行-X)。

+0

注意:這現在也適用於'git rebase --interactive'。請參閱我的[更新的答案(http://stackoverflow.com/a/2945367/6309)。 – VonC 2013-07-12 05:53:22

回答

154

你可以在Git v1.7.3或更高版本中使用它。

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

從Git的v1.7.3版本說明:

git rebase --strategy <s>學到的-X選項傳遞由所選擇的合併策略理解額外的選項。

注:「我們」和「他們的」意味着他們在直接合並期間所做的相反。換句話說,「他們」傾向於當前分支的承諾。

更新:編輯得更清楚。

+3

澄清:$ git rebase --strategy recursive -X他們的 – 2011-04-24 19:06:57

+0

@iCrazy:那麼,它是'-X他們'或'他們的'?通常1個字母選項的參數連接到選項本身。在這方面,git是不同的? – MestreLion 2012-04-17 22:59:04

+0

此外,對於不幸的git 1.7.1用戶,請檢查我的答案以獲得解決方案 – MestreLion 2012-04-17 22:59:44

13

這對於帶着自己的一組選項

git rebase <branch> -s recursive -X theirs 

應該工作的合併策略,儘管this patch mentions(2010年2月):

的手冊頁說,git-rebase支持融合的策略,但基金會 命令不知道約-X,並給出了它的使用情況。

所以,如果它仍然無法正常工作,現在正在辯論!
(在最近的Git支持)


更新從commit db2b3b820e2b28da268cc88adff076b396392dfe(2013年7月的git 1.8.4+),

不要忽視互動變基

合併戰略合併選項其選項可在git rebase中指定,但-- interactive則完全忽略。

參團的off-by:阿爾諾方丹

這意味着-X和現在的戰略互動變基,以及純重訂工作。

+0

'-X他們'(帶空格)在git 1.7.1中都不起作用。 – Kornel 2010-05-31 20:07:48

+1

@porneL:我這麼認爲。因此我鏈接到修補程序提案。 – VonC 2010-05-31 20:27:33

+0

@porneL:是的,我也注意到了這個錯誤 - 我希望它能夠在不久之後得到解決,不管是在那個補丁還是其他方面,因爲所有的基礎設施都在那裏;他們只需要確定他們將如何從rebase到merge進行通信。 – Cascabel 2010-06-24 16:06:39

4

由於iCrazy表示,此功能僅適用於git 1.7.3以上版本。因此,對於可憐的靈魂(像我)仍然使用1.7.1,我提出一個解決方案,我做了自己:

git-rebase-theirs

這是一個很好的拋光(因此長)腳本,這意味着生產使用:用戶界面選項,處理多個文件,檢查文件是否確實有衝突標誌等,但「核心」可在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) <[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

謝謝@VonC!我只是不確定爲什麼沒有對bash腳本進行顏色編碼。像這樣的大腳本本身總是很醜陋......但是由於大量的黑色文本使得它更加醜陋:P – MestreLion 2012-04-18 08:20:16

+0

它在http://stackoverflow.com/editing-help#syntax-highlighting中進行了解釋。我在代碼塊之前添加了適當的美化語言代碼。它應該現在看起來更好。 – VonC 2012-04-18 09:19:25

+0

謝謝@VonC! SO的語法高亮實在太差,但它總比沒有好。你非常體貼!並且,作爲SO *中的* git authorithy,您可能會對另一個助手腳本感興趣:http://stackoverflow.com/a/10220276/624066。這和我的github賬戶有你可能喜歡的工具。 – MestreLion 2012-04-19 01:54:05