¿Hay alguna manera en RCS o SCCS, etc. para 're-originar' los cambios?

Actualmente uso SCCS para control de fuente, pero esta pregunta se aplica a los sistemas de control de versiones en general.

Para determinar cuándo se originó un fragment de código, a veces abro SCCS s. files para desplazarse y hacer coincidir los commands de inserción alnetworkingedor del código con los encabezados de la versión. Por supuesto, después de un time, estos files se vuelven bastante difíciles de leer de esa manera.

¿Hay alguna manera de 're-originar' un file SCCS para que la primera versión almacenada sea lo que haya, digamos, hace 5 años, y solo se conservan esos deltas desde entonces? Supongo que podría hacerse revisando cada versión que desee y volver a delinearlas en un nuevo repository, pero alguien debe haber automatizado ese process, ¿no?

O, mejor aún (?), ¿Existe alguna utilidad que muestre la versión actual de un file anotado con la versión # asociada a cada línea? Acabo de encontrar documentation para un command 'anotar' en bitkeeper. Ese es el tipo de cosas sobre las que estoy preguntando. Oops. Veo que el command "sccs get -m" hace eso (y de hecho tengo una opción en mi script de contenedor de sccs para hacerlo). Lo siento, qué droga.

La primera pregunta de 're-origen' sigue en pie, aunque …

Estás mezclando algunos conceptos separados (como descubriste con el command secundario anotar). La anotación ( git annotate , svn annotate , etc.) o a veces llamada "culpa" le pide al VCS que le muestre información sobre la fuente misma y la primera revisión que tuvo ese fragment de fuente particular, generalmente una línea, ya que principalmente tratamos con "líneas de código", de la misma forma que lo hace en una revisión en particular.

Pero eso no es lo que todavía está buscando, así que vamos a sumergirnos. Todos los sistemas de control de versiones tienen un problema: si va a almacenar cada versión de cada file, podría requerir grandes cantidades de espacio de almacenamiento.

Por lo tanto, la mayoría de los VCS utilizan algún tipo de compression, y la mayoría se conecta directamente con la encoding delta , también llamada compression delta: almacene una versión completamente intacta, y en lugar de almacenar una segunda versión intacta, almacene solo un set de instrucciones que puedan usarse para modifique la versión intacta almacenada para get la segunda versión.

Repite esto para muchas versiones y obtienes deltas encadenados , donde comienzas con una versión inicial y la modificas repetidamente para get una versión final. Inicialmente, SCCS usó esto en una dirección "hacia adelante": almacena la versión inicial, luego almacena el primer cambio como la segunda versión, luego almacena el cambio en la segunda versión como la tercera versión, y así sucesivamente. Esto, claramente, es algo lento. Por lo tanto, RCS usa deltas invertidos : almacena la última versión intacta mientras almacena deltas para computar versiones anteriores de sus sucesores. Esto hace que la recuperación de la versión más reciente sea más rápida y la versión más antigua lenta, generalmente lo que se desea, pero tiene un inconveniente diferente: no funciona correctamente con las twigs. Por lo tanto, RCS realmente usa deltas inversos en su troncal y deltas hacia adelante en sus twigs .

Dado que CVS está (o fue) construido sobre el formatting de file RCS, también utiliza este formatting de almacenamiento delta inverso pero también adelantado.

Para el performance, el SCCS moderno usa un concepto conocido como deltas intercalados , donde el repository almacena lo que equivale a una especie de unión de todas las versiones. Un pase lineal a través de un file almacenado es suficiente para extraer cualquier versión en particular. (La página de Wikipedia vinculada dice que Bitkeeper también usa deltas intercalados).

Personalmente, no sé qué usa Subversion internamente, pero ¿cómo exactamente subversion almacena los files en el repository? sugiere que use deltas inversos más instantáneas. Hornear en una instantánea, otra versión "intacta", de vez en cuando proporciona una forma de establecer un límite en la cantidad de deltas que se deben aplicar.

Git hace algo bastante diferente. En lugar de almacenar cada file por separado y de comprimir delta contra versiones anteriores de ese file, Git almacena lo que llama objects . Cada object es, al less lógicamente, independiente (una instantánea), de modo que ninguna versión de ningún file está comprimida alguna vez delta, aunque cada instantánea está comprimida zlib. Para ahorrar espacio adicional, Git ocasionalmente comprime varios objects en un solo "file pack", y aquí los objects internos del file pack se comprimen delta … pero contra cualquier otro object , no solo los que representan el mismo file fuente. (En particular, esto permite a Git comprimir objects de tree usando otros objects de tree).

Al final, lo que esto significa para Git es que usa delta-compression, potencialmente en cualquier dirección, esto podría mezclarse hacia delante y hacia atrás, con snapshots para mantener las longitudes de cadena limitadas ( --depth o pack.depth ), pero de objects contra objects, no necesariamente solo un file contra otra versión del mismo file. A efectos prácticos, Git no elige estos objects de forma totalmente arbitraria (es muy difícil saber qué objects se comprimirán bien con otros por adelantado) sino que lo hace por tipo de object, tamaño de object, nombre de file como se encuentra en un object de tree, y edad (no estoy seguro de dónde provienen estas edades), por lo que Git a menudo termina con el equivalente de deltas inversos, pero no está garantizado. (Git también reutiliza las cadenas delta precalculadas de los packages anteriores a less que le diga que no lo haga; vea --no-reuse-delta aka -f ).

Como regla general, no hay forma de decirle a un sistema de revisión que actualice por completo su formatting de almacenamiento interno. Algunos VCS pueden tener excepciones. Por ejemplo, Git es un poco inusual ya que git repack hace exactamente eso, ¡pero no de una manera que sea útil para tu caso de uso particular!

(Tengo que preguntarme por qué en la Tierra estás usando SCCS.)

Dichos commands varían según los diferentes sistemas de control de fuente. SCCS es positivamente antiguo, y es poco probable que tenga tal command.

En RCS (que también es antiguo, pero un poco más moderno que SCCS), puede usar la opción "-o" para eliminar ("pasar") las versiones anteriores de los files. Por ejemplo, si tiene un file con revisiones almacenadas 1.1, 1.2, 1.3, …, entonces puede usar

 rcs -o1.1 filename 

para eliminar la versión 1.1 del historial, o

 rcs -o1.1:1.3 

para eliminar las revisiones 1.1, 1.2 y 1.3.

¿Existe alguna utilidad que muestre la versión actual de un file anotado con la versión # asociada a cada línea?

Para la mayoría de los sistemas modernos, sí:

  • CVS: cvs annotate filename
  • SVN: svn blame filename (también praise , annotate , ann )
  • Git: git blame filename
  • Mercurial: hg annotate o hg blame

No creo que SCCS o RCS tengan ese command. Es fácil importar files RCS a CVS (simplemente copie el filename,v en el repository de CVS), y probablemente haya herramientas automatizadas para convertir un repository de SCCS en un repository de RCS.

Estos commands muestran una anotación línea por línea de la versión actual del file, lo que significa que no le darán ninguna información sobre las líneas eliminadas. Para eso, puede usar algún command de tipo diff para comparar versiones especificadas ( rcsdiff , cvs diff , svn diff , git diff , hg diff ).