2009-05-20 8 views
0

J'utilise CVS et après une fusion, j'ai des centaines de conflits. Aucun des conflits n'est un problème (ils sont des changements sans importance en raison des différences d'expansion de mot-clé sur le tronc et la branche).résolution de conflit de masse

Je ne sais pas que des modifications ont été apportées aux fichiers car il s'agit simplement d'une fusion d'une branche fournisseur dans le tronc. Quelques dizaines de fichiers ont été inspectés au hasard pour valider cela.

Existe-t-il un moyen rapide de résoudre tous les conflits sans faire chacun manuellement? (J'ai TortoiseCVS, WinCVS et la ligne de commande à ma disposition).

Répondre

0

Je vais répondre à ma propre question car la solution EMACS proposée par @jesup était impraticable pour quelqu'un qui n'a pas utilisé EMACS depuis 15 ans!

Dans mon cas, parce que je savais que le seul conflit était dans l'expansion des mots-clés $ LOG $ et je ne me souciais pas vraiment du contenu des commentaires. J'ai vu deux solutions possibles:

  1. Retour à l'importation de la source des fournisseurs et veiller à ce que l'expansion de mot-clé est désactivé et Refaire la fusion. Soyez courageux et copiez tous les fichiers du fournisseur sur les fichiers de conflit (résolvant ainsi le conflit). Dans mon cas, je savais que nous n'avions pas apporté de changements, c'était une option sans risque.

Je suis allé avec 2. Une comparaison basée sur les règles en utilisant BeyondCompare confirmé tous les dossiers avaient seulement des changements « sans importance ».

0

Vous pouvez programmer une macro pour le faire dans Emacs sans trop de problèmes - si vous êtes habitué à emacs/elisp, ou si vous pourriez probablement le faire sans elisp en utilisant une macro clavier dans emacs, puis en utilisant^u^(Répétez 1024 fois la macro du clavier (^ x^e), chaque^u augmente le compte de 4x). La macro serait une simple répétition des commandes nécessaires pour résoudre un conflit dans le fichier. Vous pouvez également charger tous les fichiers avec des conflits dans des tampons, puis utiliser elisp ou peut-être une macro de clavier pour résoudre les conflits, puis passer au tampon suivant, et le répéter.

Je ne serais pas surpris s'il y a un moyen plus simple, mais cela fonctionnerait. Et même si vous devez charger tous les fichiers dans des tampons, puis exécuter la macro du clavier, vous le faites en un temps relativement court.

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) 

Maintenant vous avez tous les centaines de fichiers dans les tampons emacs, et vous pouvez mettre en place une macro pour saisir le tampon suivant, résoudre les conflits, et l'enregistrer - puis répétez que macro N fois.

1

pouvez-vous faire la fusion à nouveau?

faire un

cvs update -kk

avant la fusion, ce ne sera pas élargir les mots-clés.
Le seul mot-clé qui sera un problème est le $ Log un

0

Voici un programme C++ que j'ai écrit pour le faire. Il compile dans Visual Studio 2008 Express, et probablement tout autre compilateur.

Cette sortie d'entrée se fait par redirection, ce qui est peut-être pas pratique, mais vous pouvez écrire un fichier cmd pour appeler, comme

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

Le code est

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

Avertissement: Vous voudrez peut-être vérifier votre sortie.