2012-04-05 2 views
23

Как мне сделать git автоматически запускать git mergetool для любого конфликта слияния? Это должно применяться для всех слияний, используя merge, rebase, pull и т.д.Как заставить git автоматически открывать mergetool, если есть конфликт слиянием?

+1

Возможно, вы можете использовать [githook] (http://www.kernel.org/pub/software/scm/git/docs/githooks.html), например. 'post-checkout' (я не знаю, действительно ли он был вызван во время слияния.' post-merge' требует успешного слияния) –

+1

@TobiasKienzler Вы могли бы что-то сказать. Если вы можете найти рабочее решение, я дам вам щедрость за этот вопрос. –

+0

@QuinnStrahl Я не думаю, что в настоящее время существует крючок, который выполняется перед каждой из различных команд, ведущих к слиянию, поэтому [обертка rospov] (http://stackoverflow.com/a/17620046/321973), вероятно, является простое решение. Это или изменение источника git для реализации функции «pre-merge' hook», и в этом случае вы, конечно, можете просто запустить git runitool на конфликтах в зависимости от настройки конфигурации в любом случае ... –

ответ

3

Вы всегда можете использовать псевдоним

alias 'git-merge'='git merge && git mergetool' 
alias 'git-rebase'='git rebase && git mergetool' 
alias 'git-pull'='git pull && git mergetool' 

и/или написать вспомогательный сценарий вдоль этих линий

#/bin/bash 
git $* 
[ "$(git ls-files –abbrev –unmerged | wc -l)" -gt 0 ] && git mergetool 

и затем

alias git='~/.git/git-script' 

Существует нет прямого способа вызвать mergetool, потому что это только один из нескольких способов слияния (см. «КАК РЕШИТЬ КОНФЛИКТЫ» в man 1 git-merge).

+3

Как я уже говорил, я хочу только назвать 'mergetool', если есть конфликт. Аргумент «только один из нескольких способов слияния» не убедителен. Да, существует несколько способов, но вполне разумно хотеть выбрать один из них по умолчанию. –

+1

git mergetool ничего не сделает, если нет конфликта. – j13r

+2

Он напечатает сообщение. –

2

Насколько я знаю, для этого нет фарфорового способа.

Вы можете иметь оболочку вокруг мерзавца, как этот (файл git_mergetool.sh, на вашем пути, +x):

#!/bin/bash 

SEARCH="CONFLICT" 
OUTPUT=$(git "[email protected]" 2>&1 | tee /dev/tty) 
if `echo ${OUTPUT} | grep -i "${SEARCH}" 1>/dev/null 2>&1` 
then 
    git mergetool 
fi 

Затем добавить псевдоним:

echo alias git=\"git_mergetool.sh\" >> ~/.bashrc 

Каждый раз, когда вы вызываете мерзавца, обертку будет проверяться, появляется ли слово «CONFLICT». Если это так - wrapper запускает mergetool.

Это может быть улучшен путем добавления более точной фразы $SEARCH (например, «Автоматическое слияние не удалось, исправить конфликты и затем зафиксировать результат.»), А также путем проверки, если первый аргумент ($1) находится в списке команд, в результате в конфликте слиянием (pull, merge и т. д.). В противном случае вы получите синтаксический анализ большого количества ненужных данных, если вывод команды git слишком велик.

+0

Возможно ли без эффективного сглаживания git? –

+0

@QuinnStrahl Вы можете назвать скрипт 'git' (без расширения файла) и ввести свой путь до фактического исполняемого файла git. Но это всего лишь еще один способ сглаживания. Так что нет, я не знаю, как это сделать, не используя aliasing git. –

+2

Должно быть несколько работоспособным, но регулярное выражение CONFLICT нуждается в улучшении. Я думаю, что в настоящее время он подбирает его где угодно, даже, например, в diff мощность. По крайней мере, вы можете фильтровать по строке (например, якорь) и, возможно, расширять текст. –

5

Вы не можете (пока) сделать git сделать это.


Это может быть или не быть приемлемым обходным путем.

Создать функцию в ~/.bashrc:

git() 
{ 
    if [[ $1 == "merge" ]] || [[ $1 == "rebase" ]] || [[ $1 == "pull" ]]; then 
    command git "[email protected]" 
    rc=$? 
    if [[ $rc == 1 ]]; then 
     echo "There are conflicts, better run git-mergetool!!!" 
     # There might be some other condition that returns a '1', 
     # if so you can add another check like this: 
     # if grep Conflicts $(git --git-dir)/MERGE_MSG; 
     command git mergetool 
    fi 
    else 
    command git "[email protected]" 
    fi 
} 

Mergetool не вызывается, когда она сливается:

$ git merge non_conflicting_branch 
Merge made by the 'recursive' strategy. 
bar | 0 
1 file changed, 0 insertions(+), 0 deletions(-) 
create mode 100644 bar 

Mergetool вызывается, когда возникают конфликты:

$ git merge conflicting_branch 
Auto-merging foo 
CONFLICT (content): Merge conflict in foo 
Automatic merge failed; fix conflicts and then commit the result. 
There are Conflicts, better run git-mergetool!!! 

Mergetool не вызывается при других ошибках:

$ git merge adasds 
fatal: adasds - not something we can merge 
+0

Это не делает git автоматически открытым mergetool, это делает оболочку делать это. –

+0

Почему downvote? Это, по сути, более чистый способ реализовать ответ Росипова. – onionjake

+0

Как он чище? Вам не хватает некоторых конфликтов (например, 'git stash pop'). Так как он не фильтрует по команде, это не проблема. Как вы сами заметили, текущий код запускает 'git mergetool' при любой ошибке с 1 статусом. –