¿Por qué usar diff / patch cuando es más fácil usar cp?


19
diff -u file1.txt file2.txt > patchfile

crea un archivo de parche que consiste en instrucciones para patchconvertir file1.txt para que sea exactamente como file2.txt

¿No se puede hacer esto usando el cpcomando? Me imagino que esto será útil cuando el archivo es demasiado grande y tiene que transferirse a una red donde este enfoque podría ahorrar ancho de banda. ¿Hay alguna otra forma de usar diff / patch que sería ventajoso en otros escenarios?

Respuestas:


31

Las diferencias pueden ser más complicadas que solo comparar un archivo versus otro. El puede comparar jerarquías de directorios completas. Considere el ejemplo que quiero arreglar un error en GCC. Mi cambio agrega una o dos líneas en 4 o 5 archivos y elimina un puñado de líneas en esos y otros archivos. Si quiero comunicar estos cambios a alguien, potencialmente para su inclusión en GCC, mis opciones son

  • Copie todo el árbol fuente
  • Copie solo los archivos que fueron cambiados
  • Suministra solo los cambios que he hecho

Copiar todo el árbol de origen no tiene sentido, pero ¿qué pasa con las otras dos opciones, que se encuentran en el centro de su pregunta? Ahora considere que alguien más también trabajó en el mismo archivo que yo y ambos le damos nuestros cambios a alguien. ¿Cómo sabrá esta persona lo que hemos hecho y si los cambios son compatibles (diferentes partes del archivo) o están en conflicto (las mismas líneas del archivo)? ¡Los diferirá! El diff puede decirle en qué se diferencian los archivos entre sí y del archivo fuente no modificado. Si la diferencia es lo que se necesita, tiene más sentido enviar la diferencia en primer lugar. Un archivo diff también puede contener cambios de más de un archivo, por lo que si bien edité 9 archivos en total, puedo proporcionar un solo archivo diff para describir esos cambios.

Las diferencias también se pueden utilizar para proporcionar historia. ¿Qué pasa si un cambio hace tres meses causó un error que solo descubrí hoy? Si puedo reducir cuando se introdujo el error y puedo aislarlo a un cambio específico, puedo usar el diff para "deshacer" o revertir el cambio. Esto no es algo que podría hacer tan fácilmente si solo estuviera copiando archivos.

Todo esto se relaciona con el control de la versión de origen donde los programas pueden grabar el historial de archivos como una serie de diferencias desde el momento en que se creó hasta hoy. Los diffs proporcionan el historial (puedo recrear el archivo tal como estaba en un día en particular), puedo ver a quién culpar por romper algo (el diff tiene un propietario) y puedo enviar fácilmente cambios a proyectos ascendentes dándoles diferencias específicas ( tal vez solo estén interesados ​​en un cambio cuando he hecho muchos).

En resumen, sí, cpes más fácil que diffy patch, pero la utilidad de diffy patches mayor que cppara situaciones en las que es importante realizar un seguimiento de cómo cambian los archivos.


De hecho, git realmente no almacena el historial del archivo como diferencias de confirmaciones posteriores. Para cada confirmación se almacena el contenido de cada archivo (consulte "git show -s --pretty = raw" y "git ls-tree HEAD"). Luego, además de esta capa, ya que muchos archivos serán similares en diferentes confirmaciones, utiliza la compresión delta para compartir datos entre archivos (pero esto no está vinculado al historial).
ysdx

Sin embargo, las diferencias son una herramienta de visualización conveniente para esta historia.
ysdx

20

Cuando obtiene un parche, a menudo (es decir, a menos que haya realizado cambios en las mismas líneas) puede aplicar el parche a un conjunto de archivos que usted también ha cambiado.

El parche contiene información sobre el estado antiguo y nuevo de los archivos. Si obtiene un archivo copiado, no sabe cuál era el original (el estado anterior) y no puede aplicar las diferencias a un archivo (o conjunto de archivos) que también ha cambiado sin gran dificultad. Entonces, para los conjuntos de archivos fuente, no es la preservación del espacio lo que preocupa más, es la información del antes y el después.

Antes de las diferencias (contexto / unificado), esto a menudo se hacía con instrucciones para los editores (inserte una línea después de X, elimine la línea Y), pero eso solo funcionaría si supiera el estado desde el que comenzaron estas instrucciones. Por lo tanto, tiene el mismo problema que su "solución" con solo copiar.


2
un archivo de parche también le permite deshacerlo y aplicarlo a varios archivos a la vez
Gilsham

En realidad, los diffs unificados ( diff -u) son una mejora diseñada para los humanos, no ayudan a la robustez contra los conflictos sobre el contexto regular diff ( diff -c), creo. Incluso los diffs simples ( diff) a menudo funcionan sin saber exactamente el "estado desde el que comenzaron estas instrucciones". Sin embargo, esto es mejor que la respuesta aceptada porque hablar sobre cómo los archivos de parche pueden parchear múltiples archivos fuente al mismo tiempo es realmente una pista falsa.
Celada

@celeda tienes razón sobre las diferencias de contexto, entre eso y las diferencias normales es donde radica la distinción principal. Sin el contexto, los parches son mucho más difíciles de aplicar a la inversa, si es que lo hacen.
Anthon

12

Si está usando diff, puede ver qué ha cambiado exactamente, por lo que usar diff / patch es una forma de evitar que alguien deslice los cambios no deseados en el archivo.


11

Los cambios realizados en los archivos suelen ser mucho más pequeños que los archivos que se están cambiando.

Esto significa que almacenar un diff puede ahorrarle mucho espacio. Cuando diffse creó, el espacio en disco era costoso.

Pero también significa que puede volver a aplicar un diff a un archivo incluso cuando ese archivo haya cambiado de otras maneras. La utilidad de parche lo hará por usted y le dirá cuando haya problemas.

De hecho, esta es la razón más importante para trabajar con diferencias en el desarrollo de software. Cuando se ha realizado un cambio (generalmente en más de un archivo), se puede guardar como una diferencia: el resultado se denomina parche o conjunto de cambios . Si todo está bien, el parche no es solo un cambio arbitrario, sino que implementa algún tipo de cambio funcional, por ejemplo, una corrección de errores o una nueva característica.

Mientras tanto, se puede hacer un cambio diferente, posiblemente por un desarrollador diferente, incluso en una ubicación diferente. Si los cambios no se realizaron en las mismas partes de los mismos archivos, se pueden aplicar de forma independiente. Por lo tanto, los desarrolladores pueden enviarse entre sí sus parches para realizar pruebas. Se puede construir un conjunto completo de parches que representan posibles cambios; algunos de estos pueden finalmente ser rechazados, el resto se integrará en el sistema.

Por lo tanto, trabajar con diffs permite el desarrollo concurrente. Ya no tiene que trabajar en un cambio a la vez.

Los sistemas de control de versiones distribuidos modernos son una continuación de esta forma de trabajo.


1

En resumen, puede. Si mira algunos videos de Thinkg Big Larry Wall en YouTube, habla sobre cómo se inició diff / patch y qué problemas resolvieron, y en esencia, se trataba de reducir el tamaño de la comunicación a través de Internet mientras se mantienen los parches flexibles y legibles para los humanos .

Si está en un sistema local y no le importa ninguna de estas cosas, entonces cpo rsyncestá bien.


Gracias PSKocik ¿Podría por favor compartir el enlace a ese video?
toddlermenot

No estoy de acuerdo con la última declaración. No se trata de tamaño en estos días, se trata de rastrear su proceso de desarrollo para que sea más fácil de administrar.
reinierpost

@reinierpost usa git para seguir mi proceso de desarrollo. No hago un parche directo directamente.
PSkocik
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.