4.7 Ejercicio 7

De el git repo, hagen checkout de la revisión 4284497396 and hagan merge de cdb5330a9b4 . Resuelvan todos los conflictos.

CB en diff.h

Hay un conflicto de API en diff.h

Listing 4.21:Ejercicio 7 - CB en diff.h
443<<<<<<< HEAD 
444void diff_no_index(struct rev_info *, int, const char **); 
445||||||| 125dcea963 
446void diff_no_index(struct repository *, struct rev_info *, int, const char **); 
447======= 
448int diff_no_index(struct repository *, struct rev_info *, 
449                  int implicit_no_index, int, const char **); 
450>>>>>>> cdb5330a9b

Parece bastante sencillo

dMU

Se removió el parámetro struct repository * como argumento a la función diff_no_index.

dML

Se agregó (o mejor dicho, se insertó) int implicit_no_index como argumento a la función diff_no_index.

Resolución

Dado que es más sencillo borrar que estar moviendo cosas de un bloque al otro, trabajaremos desde el LB.

Listing 4.22:Ejercicio 7 - Paso 1 LB en diff.h
447======= 
448int diff_no_index(struct repository *, struct rev_info *, 
449                  int implicit_no_index, int, const char **); 
450>>>>>>> cdb5330a9b

Entonces borramos struct repository * como argumento.

Listing 4.23:Ejercicio 7 - Paso 2 LB en diff.h
447======= 
448int diff_no_index(struct rev_info *, 
449                  int implicit_no_index, int, const char **); 
450>>>>>>> cdb5330a9b

Listing 4.24:Ejercicio 7 - Resolución de CB en diff.h
441int diff_result_code(struct diff_options *, int); 
442 
443int diff_no_index(struct rev_info *, int implicit_no_index, int, 
444                  const char **); 
445 
446int index_differs_from(struct repository *r, const char *def, 
447                       const struct diff_flags *flags, 
448                       int ita_invisible_in_index);

Noten como reorganicé los parámetros de la llamada para que tuviera un formato más acorde a los standares del proyecto git.

Esto, claro está, significa que todas las llamadas existentes a diff_no_index estarán rotas. Es bastante probable que haya algunas que presenten conflictos, pero ya sabemos que podría haber otras que escapan a conflictos y que tendremos que cazar 5.

CB en builtin/diff.c

Esto nos hará sudar un poco.

Listing 4.25:Ejercicio 7 - CB en builtin/diff.c
324<<<<<<< HEAD 
325        if (no_index && argc != i + 2) { 
326                if (no_index == DIFF_NO_INDEX_IMPLICIT) { 
327                        /* 
328                         * There was no --no-index and there were not two 
329                         * paths. It is possible that the user intended 
330                         * to do an inside-repository operation. 
331                         */ 
332                        fprintf(stderr, "Not a git repository\n"); 
333                        fprintf(stderr, 
334                                "To compare two paths outside a working tree:\n"); 
335                } 
336                /* Give the usage message for non-repository usage and exit. */ 
337                usagef("git diff %s <path> <path>", 
338                       no_index == DIFF_NO_INDEX_EXPLICIT ? 
339                       "--no-index" : "[--no-index]"); 
340 
341        } 
342||||||| 125dcea963 
343        if (no_index && argc != i + 2) { 
344                if (no_index == DIFF_NO_INDEX_IMPLICIT) { 
345                        /* 
346                         * There was no --no-index and there were not two 
347                         * paths. It is possible that the user intended 
348                         * to do an inside-repository operation. 
349                         */ 
350                        fprintf(stderr, "Not a git repository\n"); 
351                        fprintf(stderr, 
352                                "To compare two paths outside a working tree:\n"); 
353                } 
354                /* Give the usage message for non-repository usage and exit. */ 
355                usagef("git diff %s <path> <path>", 
356                       no_index == DIFF_NO_INDEX_EXPLICIT ? 
357                       "--no-index" : "[--no-index]"); 
358 
359        } 
360        if (no_index) 
361                /* If this is a no-index diff, just run it and exit there. */ 
362                diff_no_index(the_repository, &rev, argc, argv); 
363 
364        /* Otherwise, we are doing the usual "git" diff */ 
365        rev.diffopt.skip_stat_unmatch = !!diff_auto_refresh_index; 
366======= 
367        if (no_index) 
368                /* If this is a no-index diff, just run it and exit there. */ 
369                exit(diff_no_index(the_repository, &rev, 
370                                   no_index == DIFF_NO_INDEX_IMPLICIT, 
371                                   argc, argv)); 
372 
373        /* Otherwise, we are doing the usual "git" diff */ 
374        rev.diffopt.skip_stat_unmatch = !!diff_auto_refresh_index; 
375>>>>>>> cdb5330a9b

En este, parece que cada una de las ramas se encargó de borrar una de las partes del MB. Hagamos el análisis completo de todos modos.

dMU

Se borró el segundo condicional del MB (líneas 360-362) junto con todo lo que le seguía.

dML

El primer condicional del MB (líneas 343-359) fue borrado. La llamada a diff_no_index ahra tiene un nuevo parámetro (a partir de la expresión no_index == DIFF_NO_INDEX_IMPLICIT ) y la llamada está incluída dentro de una llamada a exit (líneas 360-362). En este punto quiero que estén bien atentos acerca de la resolución del conflicto porque esta esla llamada sobre la que hubo un conflicto de API en el CB anterior.

Resolución

Siempre queriendo cuidar los detalles, verifiquemos cuando/como se borró el código en cada rama.

Código borrado hacia HEAD Primero hagamos el blame reverso para ver cuando fue la última vez que esas líneas estuvieron presentes:

Listing 4.26:Ejercicio 7 - git blame reverse
$ git blame -s --reverse MERGE_HEAD..HEAD builtin/diff.c 



^cdb5330a9b 321)        repo_init_revisions(the_repository, &rev, prefix); 
^cdb5330a9b 322) 
^cdb5330a9b 323)        if (no_index) 
^cdb5330a9b 324)                /* If this is a no-index diff, just run it and exit there. */ 
^cdb5330a9b 325)                exit(diff_no_index(the_repository, &rev, 
^cdb5330a9b 326)                                   no_index == DIFF_NO_INDEX_IMPLICIT, 
^cdb5330a9b 327)                                   argc, argv)); 
^cdb5330a9b 328) 
^cdb5330a9b 329)        /* Otherwise, we are doing the usual "git" diff */ 
^cdb5330a9b 330)        rev.diffopt.skip_stat_unmatch = !!diff_auto_refresh_index; 
^cdb5330a9b 331) 
^cdb5330a9b 332)        /* Scale to real terminal size and respect statGraphWidth config */

La útima vez que esas líneas estuvieron presentes hacia HEAD fue en la revisión cdb5330a9b y al verificar la historia del achivo veremos que solo hay un puñado de versiones posteriores a ella:

Listing 4.27:Ejercicio 7 - revisiones que verificar
$ git log --oneline cdb5330a9b..HEAD -- builtin/diff.c 
12e5bdd9c4 Merge branch ’jk/diff-no-index-initialize’ 
287ab28bfa diff: reuse diff setup for --no-index case 
3a14fdec88 Merge branch ’sl/const’ 
33de80b1d5 various: tighten constness of some local variables 
f8adbec9fe cache.h: flip NO_THE_INDEX_COMPATIBILITY_MACROS switch 
1b0d968b34 read-cache.c: replace update_index_if_able with repo_&

y al verificarlas una a una encontramos que el culpable es la revisión 287ab28bfae14:

Listing 4.28:Ejercicio 7 - revisión donde se movió el código
$ git show --pretty= 287ab28bfae14 -- builtin/diff.c 
diff --git a/builtin/diff.c b/builtin/diff.c 
index f0393bba23..777ca87156 100644 
--- a/builtin/diff.c 
+++ b/builtin/diff.c 
@@ -337,21 +337,23 @@ int cmd_diff(int argc, const char **argv, const char *prefix) 
                       "--no-index" : "[--no-index]"); 
 
        } 
-       if (no_index) 
-               /* If this is a no-index diff, just run it and exit there. */ 
-               diff_no_index(the_repository, &rev, argc, argv); 

-       /* Otherwise, we are doing the usual "git" diff */ 
-       rev.diffopt.skip_stat_unmatch = !!diff_auto_refresh_index; 
 
-       /* Scale to real terminal size and respect statGraphWidth config */ 
+       /* Set up defaults that will apply to both no-index and regular diffs. */ 
        rev.diffopt.stat_width = -1; 
        rev.diffopt.stat_graph_width = -1; 

-       /* Default to let external and textconv be used */ 
        rev.diffopt.flags.allow_external = 1; 
        rev.diffopt.flags.allow_textconv = 1; 
 
+       /* If this is a no-index diff, just run it and exit there. */ 
+       if (no_index) 
+               diff_no_index(&rev, argc, argv); 

+       /* 
+        * Otherwise, we are doing the usual "git" diff; set up any 
+        * further defaults that apply to regular diffs. 
+        */ 
+       rev.diffopt.skip_stat_unmatch = !!diff_auto_refresh_index; 

        /* 
         * Default to intent-to-add entries invisible in the 
         * index. This makes them show up as new files in diff-files

Podemos ver que el código fue colocado un poco más abajo en el achivo. Y las líneas están presentes aún en el archivo, luego del CB que estamos analizando::

Listing 4.29:Ejercicio 7 - sección de builtin/diff.c
383        /* If this is a no-index diff, just run it and exit there. */ 
384        if (no_index) 
385                diff_no_index(&rev, argc, argv); 
386 
387        /* 
388         * Otherwise, we are doing the usual "git" diff; set up any 
389         * further defaults that apply to regular diffs. 
390         */ 
391        rev.diffopt.skip_stat_unmatch = !!diff_auto_refresh_index;

Y, solo para asegurarnos, podemos hacer un blame de las líneas para ver si se corresponden con la revisión que estamos hablando:

Listing 4.30:Ejercicio 7 - git blame
$ git blame -s -L 383,391 -- builtin/diff.c 
287ab28bfae 383)        /* If this is a no-index diff, just run it and exit there. */ 
287ab28bfae 384)        if (no_index) 
287ab28bfae 385)                diff_no_index(&rev, argc, argv); 
287ab28bfae 386) 
287ab28bfae 387)        /* 
287ab28bfae 388)         * Otherwise, we are doing the usual "git" diff; set up any 
287ab28bfae 389)         * further defaults that apply to regular diffs. 
287ab28bfae 390)         */ 
287ab28bfae 391)        rev.diffopt.skip_stat_unmatch = !!diff_auto_refresh_index;

Y este es precisamente uno de los sitios donde debemos considerar el cambio de API. Recuerdan la función que debimos ajustar? diff_no_index. Exactamente lo que tenemos en la línea 385. Podemos ver que en el parche donde se mueve la llamada, originalmente tenía el parámetro the_repository pero en la posición final el parámetro ha sido removido, así que esa parte de nuestro conflicto de API ya fue resuelto.

Veamos el código borrado de la otra rama.

Código borrado hacia la otra rama

Listing 4.31:Ejercicio 7 - git blame reverse
$ git blame -s --reverse HEAD..MERGE_HEAD builtin/diff.c 



^4284497396 322)        repo_init_revisions(the_repository, &rev, prefix); 
^4284497396 323) 
^4284497396 324)        if (no_index && argc != i + 2) { 
^4284497396 325)                if (no_index == DIFF_NO_INDEX_IMPLICIT) { 
^4284497396 326)                        /* 
^4284497396 327)                         * There was no --no-index and there were not two 
^4284497396 328)                         * paths. It is possible that the user intended 
^4284497396 329)                         * to do an inside-repository operation. 
^4284497396 330)                         */ 
^4284497396 331)                        fprintf(stderr, "Not a git repository\n"); 
^4284497396 332)                        fprintf(stderr, 
^4284497396 333)                                "To compare two paths outside a working tree:\n"); 
^4284497396 334)                } 
^4284497396 335)                /* Give the usage message for non-repository usage and exit. */ 
^4284497396 336)                usagef("git diff %s <path> <path>", 
^4284497396 337)                       no_index == DIFF_NO_INDEX_EXPLICIT ? 
^4284497396 338)                       "--no-index" : "[--no-index]"); 
^4284497396 339) 
^4284497396 340)        }

A partir de la revisión 4284497396, veamos qué le sigue:

Listing 4.32:Ejercicio 7 - revisiones que verificar
$ git log 4284497396..MERGE_HEAD --oneline -- builtin/diff.c 
16bb3d714d diff --no-index: use parse_options() instead of diff_opt_parse()

No hay muchas revisiones, no? Veamos:

Listing 4.33:Ejercicio 7 - revisión donde el código fue borrado y la llamada ajustada
$ git show 16bb3d714d --pretty= -- builtin/diff.c 
diff --git a/builtin/diff.c b/builtin/diff.c 
index f0393bba23..52dc3e136f 100644 
--- a/builtin/diff.c 
+++ b/builtin/diff.c 
@@ -320,26 +320,11 @@ int cmd_diff(int argc, const char **argv, const char *prefix) 
 
        repo_init_revisions(the_repository, &rev, prefix); 
 
-       if (no_index && argc != i + 2) { 
-               if (no_index == DIFF_NO_INDEX_IMPLICIT) { 
-                       /* 
-                        * There was no --no-index and there were not two 
-                        * paths. It is possible that the user intended 
-                        * to do an inside-repository operation. 
-                        */ 
-                       fprintf(stderr, "Not a git repository\n"); 
-                       fprintf(stderr, 
-                               "To compare two paths outside a working tree:\n"); 
-               } 
-               /* Give the usage message for non-repository usage and exit. */ 
-               usagef("git diff %s <path> <path>", 
-                      no_index == DIFF_NO_INDEX_EXPLICIT ? 
-                      "--no-index" : "[--no-index]"); 

-       } 
        if (no_index) 
                /* If this is a no-index diff, just run it and exit there. */ 
-               diff_no_index(the_repository, &rev, argc, argv); 
+               exit(diff_no_index(the_repository, &rev, 
+                                  no_index == DIFF_NO_INDEX_IMPLICIT, 
+                                  argc, argv)); 
 
        /* Otherwise, we are doing the usual "git" diff */ 
        rev.diffopt.skip_stat_unmatch = !!diff_auto_refresh_index;

Y aquí podemos ver que el código fue borrado, y tenemos un ajuste a la llamada a diff_no_index. Si hacemos los ajustes a la llamada que vimos que existe aún e la línea 385, estará todo muy bien. Y dado que el MB fue borrado por completo por los cambios que cada rama hizo, eso apunta a que esta sea la solución definitiva:

Listing 4.34:Ejercicio 7 - CB en builtin/diff.c
318        init_diff_ui_defaults(); 
319        git_config(git_diff_ui_config, NULL); 
320        precompose_argv(argc, argv); 
321 
322        repo_init_revisions(the_repository, &rev, prefix); 
323 
324        /* Set up defaults that will apply to both no-index and regular diffs. */ 
325        rev.diffopt.stat_width = -1; 
326        rev.diffopt.stat_graph_width = -1; 
327        rev.diffopt.flags.allow_external = 1; 
328        rev.diffopt.flags.allow_textconv = 1; 
329 
330        /* If this is a no-index diff, just run it and exit there. */ 
331        if (no_index) 
332                exit(diff_no_index(&rev, no_index == DIFF_NO_INDEX_IMPLICIT, 
333                                   argc, argv)); 
334 
335        /* 
336         * Otherwise, we are doing the usual "git" diff; set up any 
337         * further defaults that apply to regular diffs. 
338         */ 
339        rev.diffopt.skip_stat_unmatch = !!diff_auto_refresh_index;

Vean como la llamada a diff_no_index está dentro de la llamada a exit y cómo se insertó el nuevo parámetro como estaba definido en la otra rama.

CB#1 en diff-no-index.c

Hay 2 CBs en diff-no-index.c. El primero se relaciona directamente con la firma de la función sobre la que trabajamos en diff.h. Ahora estamos trabajando sobre la firma en la implementación de la función.

Listing 4.35:Ejercicio 7 - CB#1 en diff-no-index.c
237<<<<<<< HEAD 
238void diff_no_index(struct rev_info *revs, 
239                   int argc, const char **argv) 
240||||||| 125dcea963 
241void diff_no_index(struct repository *r, 
242                   struct rev_info *revs, 
243                   int argc, const char **argv) 
244======= 
245static const char * const diff_no_index_usage[] = { 
246        N_("git diff --no-index [<options>] <path> <path>"), 
247        NULL 
248}; 
249 
250int diff_no_index(struct repository *r, 
251                  struct rev_info *revs, 
252                  int implicit_no_index, 
253                  int argc, const char **argv) 
254>>>>>>> cdb5330a9b

dMU

Se quitó el parámetro struct repository *r de la función diff_no_index.

dML

Se agregó el parámetro diff_no_index_usage y también se insertó implicit_no_index como argumento a la función diff_no_index.

Resolución

Es más que obvio que hay que trabajar desde el LB, cierto?

Listing 4.36:Ejercicio 7 - Paso 1 - LB#1 en diff-no-index.c
244======= 
245static const char * const diff_no_index_usage[] = { 
246        N_("git diff --no-index [<options>] <path> <path>"), 
247        NULL 
248}; 
249 
250int diff_no_index(struct repository *r, 
251                  struct rev_info *revs, 
252                  int implicit_no_index, 
253                  int argc, const char **argv) 
254>>>>>>> cdb5330a9b

Removemos struct the repository *r como argumento, siguiente el dMU.

Listing 4.37:Ejercicio 7 - Paso 2 - LB#1 en diff-no-index.c
244======= 
245static const char * const diff_no_index_usage[] = { 
246        N_("git diff --no-index [<options>] <path> <path>"), 
247        NULL 
248}; 
249 
250int diff_no_index(struct rev_info *revs, 
251                  int implicit_no_index, 
252                  int argc, const char **argv) 
253>>>>>>> cdb5330a9b

Listo con el CB#1:

Listing 4.38:Ejercicio 7 - Resolución del CB#1 en diff-no-index.c
234        } 
235
236 
237static const char * const diff_no_index_usage[] = { 
238        N_("git diff --no-index [<options>] <path> <path>"), 
239        NULL 
240}; 
241 
242int diff_no_index(struct rev_info *revs, 
243                  int implicit_no_index, 
244                  int argc, const char **argv) 
245
246        int i, no_index; 
247        const char *paths[2];

Podrían encargarse de resolver los otros conflictos en el proyecto? Esto es lo que hay que hacer, una vez que los terminen, para verificar:

CB#2 en diff-no-index.c

Listing 4.39:Ejercicio 7 - Resolución del CB#2 en diff-no-index.c
255        struct option *options; 
256 
257        options = parse_options_concat(no_index_options, 
258                                       revs->diffopt.parseopts); 
259        argc = parse_options(argc, argv, revs->prefix, options, 
260                             diff_no_index_usage, 0); 
261        if (argc != 2) { 
262                if (implicit_no_index) 
263                        warning(_("Not a git repository. Use --no-index to " 
264                                  "compare two paths outside a working tree")); 
265                usage_with_options(diff_no_index_usage, options); 
266        } 
267        FREE_AND_NULL(options); 
268        for (i = 0; i < 2; i++) {

No se necesita la llamada a repo_diff_setup porque fue borrada en una de las ramas y, por si acaso, r (el repositotio) ya no es parte de los parámetros de la función sobre la que estamos trabajando.

CB en diff.c

Listing 4.40:Ejercicio 7 - Resolucion del CB en diff.c
5530        ac = parse_options(ac, av, prefix, options->parseopts, NULL, 
5531                           PARSE_OPT_KEEP_DASHDASH | 
5532                           PARSE_OPT_KEEP_UNKNOWN | 
5533                           PARSE_OPT_NO_INTERNAL_HELP | 
5534                           PARSE_OPT_ONE_SHOT | 
5535                           PARSE_OPT_STOP_AT_NON_OPTION); 
5536 
5537        return ac; 
5538}

Nos quedamos con el LB tal cual porque la nueva definición para manejar color-moved-ws según la revisión 8ce2020ff07995 se hará cargo de la opción –no-color-moved-ws.

Qué falta?

El último paso sería verificar otras llamas a la función con el conflicto:

Listing 4.41:Ejercicio 7 - llamadas a diff_no_index
$ git grep -n "diff_no_index(" 
builtin/diff.c:332:             diff_no_index(&rev, no_index == DIFF_NO_INDEX_IMPLICIT, 
diff-no-index.c:242:int diff_no_index(struct rev_info *revs, 
diff.h:443:int diff_no_index(struct rev_info *, int implicit_no_index, int,

Y todas se relacionan con código que ya trabajamos resolviendo los conflictos así que todo esta bien.

Finalmente, si comparan con dcd6a8c09a, no deberían obtener ninguna diferencia significativa.