Pregunta

Estoy usando CVS y después de una fusión, tengo cientos de conflictos. Ninguno de los conflictos son un problema (que son poco importantes cambios como resultado de las diferencias de expansión de palabras clave en el tronco y ramas).

Sé que se han realizado cambios en los archivos ya que esto es simplemente una combinación de una rama de proveedor en el maletero. Unas pocas decenas de archivos han sido inspeccionadas al azar para validar esto.

¿Hay una forma rápida de resolver todos los conflictos sin hacer cada uno de forma manual? (Tengo TortoiseCVS, WinCVS y la línea de comandos a mi disposición).

¿Fue útil?

Solución 3

Voy a responder a mi propia pregunta como la solución sugerida por EMACS @jesup era poco práctico para alguien que no ha utilizado EMACS en 15 años!

En mi caso, porque sabía que el conflicto era la única en la expansión de los $ Log $ palabras clave y no le importaba sobre el contenido de los comentarios. Vi dos soluciones posibles:

  1. volver a la importación de la fuente de proveedor y asegurarse de que la expansión de palabras clave se desactiva y rehacer la fusión.

  2. ser valiente y copiar todos los archivos de los proveedores a través de los ficheros del conflicto (resolviendo así el conflicto). En mi caso, yo sabía que no había habido cambios realizados por nosotros esto era una opción sin riesgo.

Fui con 2. Comparación basada en reglas A confirmada mediante BeyondCompare todos los archivos tenía sólo cambios sin importancia ''.

Otros consejos

se puede hacer la fusión de nuevo?

hacer

  

cvs update -kk

antes de la fusión no se expandirá las palabras clave.
La única palabra clave que va a ser un problema es el registro de un solo $

Se puede programar una macro para hacerlo en Emacs sin demasiados problemas - si estás acostumbrado a emacs / elisp, o si usted probablemente podría hacerlo sin elisp utilizando una macro de teclado en emacs, a continuación, utilizando ^ u ^ u ^ u ^ u ^ u ^ x ^ e (repetición macro de teclado (^ x ^ e) 1024 veces; cada ^ u aumenta el recuento por 4x). La macro sería una simple repetición de los comandos necesarios para resolver un conflicto en el archivo. También puede cargar todos los archivos con conflictos en tampones, a continuación, utilizar elisp o tal vez una macro de teclado para resolver los conflictos a continuación, pasar a la siguiente memoria intermedia, y repetir eso.

No me sorprendería si hay una manera más fácil, pero esto funcionaría. E incluso si tiene que cargar todos los archivos en memorias intermedias y luego ejecutar la macro teclado, que Cando y ser hecho en un tiempo relativamente corto.

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)

Ahora usted tiene todos los cientos de archivos en Emacs tampones, y se puede configurar una macro para agarrar el siguiente búfer, resolver conflictos, y guardarlo -. Y luego repetir que macro N veces

Aquí es un programa en C ++ que escribí para hacer esto. Se compila en Visual Studio 2008 Express, y probablemente cualquier otro compilador.

Esta salida de entrada es a través de redireccionamiento, que tal vez no es tan conveniente, pero se puede escribir un archivo cmd llamarlo, como

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

El código es

// 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;
}

exención de responsabilidad:. Es posible que desee verificar su salida

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top