Pergunta

Eu estou usando CVS e depois de uma fusão, eu tenho centenas de conflitos. Nenhum dos conflitos são um problema (eles são mudanças sem importância, como resultado de diferenças de expansão de palavra-chave no tronco e ramo).

Eu sei que há alterações foram feitas para os arquivos como este é simplesmente um merge de um ramo de fornecedor para o tronco. Algumas dezenas de arquivos foram inspeccionados de forma aleatória para validar esta.

Existe uma maneira rápida de resolver todos os conflitos sem fazer cada um manualmente? (Eu tenho TortoiseCVS, WinCVS e da linha de comando à minha disposição).

Foi útil?

Solução 3

Eu vou responder a minha própria pergunta como a solução EMACS sugerido por @jesup foi impraticável para alguém que não tenha usado EMACS em 15 anos!

No meu caso, porque eu sabia que o único conflito foi na expansão dos $ Log $ palavras-chave e eu realmente não se preocupam com o conteúdo dos comentários. Eu vi duas soluções possíveis:

  1. voltar para a importação da fonte fornecedor e garantir que a palavra-chave de expansão está desativado e refazer a mesclagem.

  2. ser corajoso e copiar todos os arquivos do fornecedor sobre os arquivos de conflito (resolvendo assim o conflito). No meu caso, eu sabia que não houve alterações feitas por nós foi uma opção sem risco.

Eu fui com a comparação baseado em regras 2. A utilização BeyondCompare confirmou todos os arquivos teve apenas mudanças 'sem importância'.

Outras dicas

Você pode fazer a fusão de novo?

Faça um

cvs update -kk

antes da fusão isso não vai expandir as palavras-chave.
A única palavra-chave que será um problema é o $ Log um

Você pode programar uma macro para fazê-lo em Emacs sem muita dificuldade - se você está acostumado a emacs / elisp, ou se você provavelmente poderia fazê-lo sem elisp usando uma macro de teclado no emacs, em seguida, usando ^ u ^ u ^ u ^ u ^ u ^ x ^ e (repetição do teclado macro (^ x ^ e) 1024 vezes, cada ^ u aumenta a contagem por 4x). A macro seria uma simples repetição dos comandos necessários para resolver um conflito no arquivo. Você também pode carregar todos os arquivos com os conflitos em tampões, em seguida, usar elisp ou talvez um macro teclado para resolver conflitos, em seguida, mudar para o próximo buffer, e repetir isso.

Eu não ficaria surpreso se há uma maneira mais fácil, mas isso iria funcionar. E mesmo se você tiver que carregar todos os arquivos em buffers e, em seguida, executar a macro teclado, você cando isso e ser feito em um tempo relativamente curto.

Pseudo-emacs:

cvs status | grep conflict >/tmp/foo;
load /tmp/foo into an emacs buffer
edit buffer to remove all but the file/pathnames (use keyboard macros!)
load them all into buffers:
^x^(        (start-macro)
^@^e        (mark (or control-space), then end-of-line)
ESC-w       (copy)
^n^a        (next-line, beginning of line (set up for next iteration))
^x^f        (load-file)
^y          (yank saved)
<RETURN>    (load it - you could resolve conflicts right here and save)
^xb         (switch to buffer)
foo<RETURN> (go back to foo)
^x^)        (end macro)
^x^e        (repeat macro once) or
^u^u^u^u^u^x^e (repeat macro 1024 times or until BEEP)

Agora você tem todas as centenas de arquivos no Emacs buffers, e você pode criar uma macro para pegar o próximo buffer, resolver conflitos, e guardá-lo -. Repita então que macro N vezes

Aqui está um programa C ++ que eu escrevi para fazer isso. Ele compila em Visual Studio 2008 Express, e, provavelmente, qualquer outro compilador.

Esta saída de entrada é através de redirecionamento, que talvez não seja tão conveniente, mas você pode escrever um arquivo cmd para chamá-lo, como

@echo off
copy /y %1 \temp\t
resolve %2 %3 < \temp\t > %1
del \temp\t

O código é

// resolve.cpp
#include "stdafx.h"
#include "string.h"

int main(int argc, char* argv[])
{
    const int MAXWIDTH = 10000;
    char line[MAXWIDTH];

    enum { ECHO, OLD, NEW, ERROR };

    int state = ECHO;
    int num = 0;
    int quiet = 0;
    int pick = OLD;

    for (int i = 1; i < argc; ++i)
    {
        if (!strcmp(argv[i],"-h") || !strcmp(argv[i],"--help") || !strcmp(argv[i],"?"))
        {
            printf("Automatically fix CVS merge conflicts.\n"
                "Options:\n"
                " -n use the bottom code, the new code (default uses top, old code).\n"
                " -q quiet\n"
                " -h help\n"
                "use stdin and stdout for input/output and stderr for status.");
            return 0;
        }
        else if (!strcmp(argv[i],"-n"))
        {
            pick = NEW;
        }
        else if (!strcmp(argv[i],"-q"))
        {
            quiet = 1;
        }
        else
            fprintf(stderr,"unknown option %s\n",argv[i]);
    }

    while (fgets(line, MAXWIDTH, stdin))
    {
        // trim trailing whitespace
        for (int i = strlen(line); i >= 0 && line[i] < ' '; --i) 
            line[i] = 0;

        ++num;
        if (!strncmp(line,"<<<<<<< ",8))
        {
            state = (state==ECHO) ? OLD : ERROR;
            if (!quiet)
                fprintf(stderr,"At line: %d\n", num);
        }
        else if (!strcmp(line,"======="))
        {
            state = (state==OLD) ? NEW : ERROR;
        }
        else if (!strncmp(line,">>>>>>> ",8))
        {
            state = (state==NEW) ? ECHO : ERROR;
        }
        else
        {
            if (state == ECHO || state == pick)
                printf("%s\n",line);
            if (!quiet && state != ECHO)
                fprintf(stderr,"%c%s\n", (state==pick) ? '+' : '-', line);
            continue;
        }
        if (!quiet)
            fprintf(stderr,"%s\n",line);
    }
    return 0;
}

Disclaimer:. Você pode querer verificar a sua saída

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top