A ver, algo de información...
Por ahora le puse SAFA, no se si vaya a quedar así, pero me sonó bien y viene a "Simple-And-Fast-Alternative", y da juego a "Simple and fast alternative VCS", etc... el resto, por lo pronto pensé varios conceptos, varias ideas, todos a discutir y flexibilizar para que sea lo mejor según todos y para todos (o la gran mayoría):
Que haga lo que debe:
Mi idea principal es enfocarme en lo que queremos que haga bien. La filosofía UNIX es lo primero (simplicidad y modularización), lo segundo es "¿es sensato aplicarlas a este caso?", y la regla para elegir entre 1 y 2 es la de la menor sorpresa. Lo mismo para las features y elecciónes. Si una funcionalidad no primaria en cuanto a nuestros objetivos interfiere con una primaria, no se hará, o se pondrá como opcional, a menos que eso determine la utilización más intuitiva.
En distributed VCS, el historial es un concepto LOCAL:
Simplemente eso. A cualquiera le cansa la necesidad de estar horas descargando el kernel de LINUX via GIT ¿Porque querría yo tener el desarrollo de LINUX desde que debutó en el repo de GIT? Es realmente tedioso saber que gran cantidad del tiempo y espacio en disco perdido es para cosas que no vas a utilizar... NUNCA. Mi idea es un historial donde podamos adjuntar o desprender partes antiguas, quizá almacenarlas, quizá no.
Las buenas operaciones no se ponen en un programa, se ponen en una API:
La idea es tener una buena API en C, un wrapper en C++, y de ahi a Ruby, Python, etc... para que programar sobre la base del core del versionador sea sencillo sin importar en que programes. Uno no tiene porqué hacer una horrenda cañeria con PIPES para trabajar con el versionador. El concepto de plomería debería ser un poco más refinado que eso.
La sincronizacion es una buena idea, pero es mejor la actualización asíncrona:
Me ha pasado, en GIT, que no puedo hacer una sincronización via "clone", "push", "fetch", etc... por temas de red. Cuando esto pasa, nos sentimos tentados a enviar un patchset. El problema es que de esta forma los commits ya no conservaran el SHA-1, porque al aplicarse un parche se hace un nuevo commit. Poder empaquetar una sincronización es ilusorio, porque sincronizar requiere trabajo de ambas partes, pero la actualización asíncrona es algo factible. Podemos empaquetar una actualización desde el commit A al B, y dejarla guardada, enviarla por e-mail, etc, sin destruir el contenido exacto, y por lo tanto las huellas criptográficas del historial.
Los commits no son los cambios reales:
Los commits son piezas de información referentes a un árbol, que nos ayudan a comprender lo que ha cambiado respecto al anterior, son partes del log. Entonces podría anidar commits para sumarizar información en niveles. Hablando del modelo ITIL, un release puede incluir varios cambios, algunos grandes y otros chicos. Si el log fuera como nuestro "changelog", podríamos mejorarlo haciendo que se puedan anidar los cambios grandes como muchos commits dentro de un commit, entonces los 2 niveles pueden expandirse, hasta que llegamos a los commits que apuntan a los árboles. Esto me indica que puedo ver la información en perspectiva, "granulada" o no.
La decisión de cómo almacenar es un concepto local:
Un usuario puede preferir hacer un blob nuevo cada vez que cambia un archivo, o puede decidir grabar diffs entre release y release. Estas decisiónes influiran en la velocidad de checkout, el consumo de disco, etcetera. Al armar un paquete de sincronización, siempre se elegirá hacer deltas para disminuir la cantidad de información enviada, así que el almacenamiento queda como una elección para el usuario.
A demás, un sistema distribuido con un un repo central puede configurarse para ser (pseudo)centralizado, donde se agregan acciones de bloqueo y desbloqueo, con varias metodologías posibles, desde privilegios hasta autobranching (esa palabra la acabo de inventar, pero creo que se entiende).
Aunque hay muchos más, la rigidez en conceptos no es compatible 100% con el desarrollo en grupo.
Por ahora estoy usando GoogleGroups y Trello, que me parece práctico, pero estoy prácticamente solo. Hice algunos scripts de shell (bash) aunque planeo que todo el core termine siendo traducido a C inicialmente para la API y luego llevada esta hacia el programa.
Deje el ultimo fuente en trello, pero se puede usar GIT hasta que SAFA sea capaz de auto-hospedarse.
Como para que se copen, les dejo algunos pedazos de código que pueden ver, uno es la biblioteca de funciones del shell, que es sencilla y les permitirá ver algunas de las premisas que tengo para programar:
# DEBUG FLAG: 0/1
test -z $DEBUG_ && DEBUG_=0
DEBUG() {
test $DEBUG_ -eq 1 && $*;
}
ERROR_print() {
echo "[error] $*"
}
DEBUG_print() {
DEBUG echo "[debug] $*"
}
DIE() {
DEBUG_print "DIE ($*)"
ERROR_print $*
exit 1
}
El otro, un pequeño comando en PERL para obtener los permisos octales de un determinado archivo. Usaría la salida de este comando para armar los objetos 'index' y 'tree':
#!/usr/bin/perl
# Created by Rodriguez Dario A. on Thu Nov 10 07:57:12 AST 2011
# not using -w in shabang due to warnings about things we don't care
# unless we are really debugging, such as Fcntl.pm mistakes
use strict;
use Fcntl ':mode';
my $stat_mode;
my $octal_perm;
my $user_rwx;
my $group_read;
my $other_execute;
unless (@ARGV) {
print "Usage: ls.pl <file 1> ... <file n>\n"; };
foreach (@ARGV) {
die "file $_ doesnt exist" unless -f
$_; };
foreach (@ARGV) {
$stat_mode=stat($_)->mode or die "cannot stat file $_"; $octal_perm=S_IMODE($stat_mode);
printf "%04o\t%s\n", $octal_perm, $_; };
Y finalmente, el script que agrega archivos al index para el proximo commit, para que vean que conociendo el modelo, algunas operaciónes son realmente simples (sujeto a cambios, pero no se va a complicar mucho):
#!/bin/bash
. safa-shelllib
if test $# -lt 1; then
echo "incorrect usage"
echo "usage: safa-addfiles <file 1> ... <file n>"
else
for myFile in $@; do
if test -f "$myFile"; then
# verify if the file changed from the last tree
DEBUG_print "safa-diff-from-tree --quiet HEAD \"$myFile\""
safa-diff-from-tree --quiet --perm -- HEAD "$myFile"
if test $? -ne 0; then
echo " o $myFile"
DEBUG_print "nothing changed"
else
echo " + $myFile"
echo "$myFile" >> .safa/addindex
fi
fi
done
fi
Obvio que, por dar un ejemplo, safa-diff-from-tree es un script algo más complejo. Espero que se copen.
Saludos