File: secrets.txt

package info (click to toggle)
gitmagic 20160304-1
  • links: PTS, VCS
  • area: main
  • in suites: buster, sid, stretch
  • size: 2,280 kB
  • ctags: 20
  • sloc: makefile: 98; sh: 38
file content (214 lines) | stat: -rw-r--r-- 13,440 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
== Secretos Revelados ==

Tomemos un vistazo bajo la mesa y expliquemos cómo realiza sus milagros. No escatimare sobre los detalles. Para descripciones detalladas referirse a http://schacon.github.com/git/user-manual.html[el manual de usuario].

=== Invisibilidad ===

¿Cómo puede ser Git tan discreto? Aparte de los "commit" y "merge" ocasionales, usted puede trabajar inconscientemente de que un control de versiones existe. Esto sucede hasta que usted lo necesita, y esto es cuando esta agradecido de que Git este viendo por usted todo el tiempo.

Otros sistemas de control de versiones te fuerzan a luchar constantemente con cinta roja y burocracia. Los permisos de archivos podría ser de solo lectura a menos que usted explícitamente le diga a un servidor central cuales archivos intenta editar. Los comandos más básicos podrían retardarse al punto de arrastrarse cuando el número de usuarios se incrementa. El trabajo se paraliza cuando la red o el servidor central deja de funcionar.

En contraste, Git simplemente mantiene la historia de su proyecto en el directorio '.git' ubicado en su directorio de trabajo. Ésta es su propia copia de la historia, de esta manera usted puede trabajar desconectado hasta que desee comunicarse con otros. Usted tiene control total del destino de sus archivos ya que Git puede fácilmente recrear un estado guardado de '.git' en cualquier momento.

=== Integridad ===

Muchas personas asocian criptografía con manterner la información secreta, pero otro objetivo importante es mantener la información segura. El uso apropiado de las funciones "hash" en criptografía puede prevenir corrupción de datos accidental o intencional.

Un hash SHA1 puede pensarse como un identificador numérico único de 160-bit para cualquier linea de caracteres que usted pueda encontrar en su vida. Pero mas que eso: cualquier linea de caracteres que cualquier ser humano vaya a usar en muchas vidas.

Como un "hash" SHA1 es una linea de "bytes", podemos dividir lineas de "bytes" que contienen otros "hash". Esta simple observación es sorpresivamente útil: buscar 'cadenas de "hash"'. Mas adelante veremos como Git lo utiliza para garantizar eficientemente la integridad de datos.

Brevemente, Git mantiene sus datos en el subdirectorio '.git/objects', donde en lugar de archivos normales, usted encontrara solo identificadores. Al usar identificadores como nombres de archivos, asi como algunos trucos de bloqueo de archivos y sellos de tiempo, Git transforma cualquier humilde sistema de archivos en una eficiente y robusta base de datos.

=== Inteligencia ===

¿Cómo sabe Git que usted renombró un archivo, incluso pensando que usted nunca menciono el hecho explícitamente? Seguramente, usted podria haber ejecutado *git mv*, pero eso es exactamente lo mismo a *git rm* seguido de *git add*.

Git heuristicamente averigua los cambios de nombre y copias entre versiones sucesivas. ¡De hecho, puede detectar pedazos de codigo que estan siendo movidos o copiados entre archivos! Al pensar que no puede cubrir todos los casos, realiza un trabajo decente, y esta caracteristica esta siendo mejorada constantemente. Si falla al trabajar por usted, intente habilitar deteccion de copias mas caras y considere actualizar.

=== Indexacion ===

Para cada archivo rastreado, Git guarda informacion como su tamano, fecha de creacion y ultima fecha de modificacion en un archivo conocido como 'index'. Para determinar cuando un archivo ha cambiado, Git compara su estado actual con lo que estan acumulados en el indice. Si son iguales, entonces Git omite leer el archivo nuevamente.

Partiendo del hecho de que las llamadas de estado son considerablemente mas rapidas que leer archivos, si usted edita unicamente
algunos archivos, Git puede actualizar su estado en casi nada de tiempo.

Hemos insistido anteriormente que el indice es un area de escenificacion. ¿Porque un monton de estados
de archivo es un area de escenificacion? Porque el comando "add" pone archivos en la based de datos de Git
y actualiza los estados, mientras que el comando "commit", sin opciones, crea una
actualizacion basada unicamente en estos estados y los archivos que ya estan en la base de datos.

=== Los origenes de Git ===

Esto http://lkml.org/lkml/2005/4/6/121[ anuncio: Lista de Correos de "Linux Kernel"] Describe la cadena de eventos que llevaron a Git. El hilo entero es un fascinante sitio para los historiadores de Git.

=== La Base de Datos de Objetos ===

Toda version de sus datos is mantenida en la "Base de Datos de Objetos", la cual vive en el
subdirectorio 'git./objects'; los otros residentes de '.git' mantienen menos datos:
el indice, nombres de ramas, etiquetas, opciones de configuracion, logs, la localizacion
actual del primer "commit", y asi sucesivamente. La Base de Datos de Objetos is elemental pero
elegante, y la fuente del poder de Git.

Cada archivo que se encuentre en '.git/objects' es un 'objeto'. Existen 3 tipos de objetos
que nos concierne: objetos 'blob', objetos 'tree', y objetos 'commit'.

=== Blobs ===

Primero, un truco magico. Elija un archivo, cualquier archivo. En un directorio vacio:

$ echo sweet > NOMBRE_DE_ARCHIVO
$ git init
$ git add .
$ find .git/objects -type f

Usted podra ver +.git/objects/aa/823728ea7d592acc69b36875a482cdf3fd5c8d+.

¿Cómo se esto sin saber el nombre del archivo? Es porque el
"hash" SHA1 de:

"blob" SP "6" NUL "sweet" LF

es aa823728ea7d592acc69b36875a482cdf3fd5c8d,
donde SP es un espacio, NUL es un "byte" zero y LF es un avance de linea. Usted puede verificar
esto escribiendo:

$ printf "blob 6\000sweet\n" | sha1sum

Git es 'contenido-direccionable': los archivos no son almacenados de acuerdo con su nombre,
sino mas por el "hash" de la informacion que contiene, dentro de un archivo llamamos al 'objeto
"blob"'. Podemos pensar de un "hash" como el identificador del contenido de un archivo, asi
que en un sentido estamos buscando archivos por su contenido. El "blob" inicial es
meramente un encabezado que consiste en el typo del objeto y su tamaño en "bytes"; lo que
simplifica la contabilidad interna.

De esta manera yo puedo predecir fácilmente lo que usted vera. El nombre del archivo es irrelevante:
solo la información interna es usada para construir el 'objeto "blob"'.

Usted podría estarse preguntando qué sucede con archivos idénticos. Intente agregar copias de
su archivo, con cualquier cosa de nombre. El contenido de +.git/objects+ se queda
de la misma manera sin importar cuantos agregue. Git guarda la información solo una vez.

Por cierto, los archivos ubicados en +.git/objects+ estan comprimidos con zlib asi que usted
no debería poder verlos directamente. Filtrelos a través de
http://www.zlib.net/zpipe.c[zpipe -d], o digite:

$ git cat-file -p aa823728ea7d592acc69b36875a482cdf3fd5c8d

lo que bellamente imprime el objeto dado.

=== Árboles ===

¿Pero dónde están los nombres de archivo? Ellos deberían estar almacenados en algún lugar en algún organizador.
Git toma su turno para poner los nombres de archivo durante un "commit":

$ git commit # Escribe algún mensaje.
$ find .git/objects -type f

Ahora debería poder ver 3 objetos. Esta vez no puedo decirte qué son esos 2 nuevos archivos, esto debende parcialmente del nombre de archivo que escogió. Procederemos asumiendo que eligió 'rose'. Si usted no lo hizo, podría reescribir la historia para hacer parecer que usted lo hizo:

$ git filter-branch --tree-filter 'mv YOUR_FILENAME rose'
$ find .git/objects -type f

Ahora debería poder ver el archivo
+.git/objects/05/b217bb859794d08bb9e4f7f04cbda4b207fbe9+, porque este es el
SHA1 "hash" de su contenido:

"tree" SP "32" NUL "100644 rose" NUL 0xaa823728ea7d592acc69b36875a482cdf3fd5c8d

Verifique que este archivo contiene verdaderamente lo anterior escribiendo:

$ echo 05b217bb859794d08bb9e4f7f04cbda4b207fbe9 | git cat-file --batch

Con zpipe, es fácil verificar el hash:

$ zpipe -d < .git/objects/05/b217bb859794d08bb9e4f7f04cbda4b207fbe9 | sha1sum

Las verficaciones de "hash" son mas difíciles utilizando cat-file porque su salida contiene más
que la fuente del objeto del archivo descomprimido.

Este archivo es un objeto "tree": una lista de tuplas de un tipo de
archivo, un nombre de archivo, y un "hash". En nuestro ejemplo, el tipo de archivo es 100644, lo cual
significa que 'rose' es un archivo normal, y el "hash" es el objeto "blob" que contiene
los contenidos de 'rose'. Otro posible tipo de archivo son los ejecutables, enlaces simbólicos o
los directorios. En el último caso, los punteros "hash" a un objeto 'tree'.

Si usted ejecuta "filter-branch", obtendrá objetos viejos que ya no necesita. Aunque
serán desechados automáticamente una vez que su periodo de gracia expire, nosotros
los borraremos ahora para hacer nuestro ejemplo de prueba más fácil de seguir:

$ rm -r .git/refs/original
$ git reflog expire --expire=now --all
$ git prune

Para proyectos reales típicamente usted debería evitar comandos como este, ya que está
destruyendo respaldos. Si usted quiere un repositorio limpio, usualmente es mejor crear
un clon nuevo. También, tenga cuidado cuando está manipulando directamente +.git+: ¿qué pasaría si un proceso
Git está corriendo al mismo tiempo, ó un corte eléctrico ocurre?
En general, las referencias deberían ser eliminadas con *git update-ref -d*,
pensando que usualmente es más seguro remover +refs/original+ a mano.

=== "Commits" ===

Hemos explicado 2 de 3 objetos. El tercero es un objeto '"commit"'. Sus
contenidos dependen del mensaje del "commit" así como de la fecha en el que fué
creado. Para contrastar lo que tenemos aquí, deberemos torcerlo un poco:

$ git commit --amend -m Shakespeare  # Change the commit message.
$ git filter-branch --env-filter 'export
     GIT_AUTHOR_DATE="Fri 13 Feb 2009 15:31:30 -0800"
     GIT_AUTHOR_NAME="Alice"
     GIT_AUTHOR_EMAIL="alice@example.com"
     GIT_COMMITTER_DATE="Fri, 13 Feb 2009 15:31:30 -0800"
     GIT_COMMITTER_NAME="Bob"
     GIT_COMMITTER_EMAIL="bob@example.com"'  # Rig timestamps and authors.
$ find .git/objects -type f


+.git/objects/49/993fe130c4b3bf24857a15d7969c396b7bc187+


 "commit 158" NUL
 "tree 05b217bb859794d08bb9e4f7f04cbda4b207fbe9" LF
 "author Alice <alice@example.com> 1234567890 -0800" LF
 "committer Bob <bob@example.com> 1234567890 -0800" LF
 LF
 "Shakespeare" LF

Como antes, usted puede correr zpipe ó cat-file para que vea por usted mismo.

Este es el primer "commit", así que no existe un "commit" padre, pero "commit" sucesivos}
siempre van a contener al menos una línea identificando el "commit" padre.

=== Sin Distinción de la Magia ===

Los secretos de Git parecen muy simples. Parece ser que usted podría unir algunos comandos y agregar una parte de código C para cocinar algo en cuestión de horas: una mezcla de operaciones básicas con archivos de sistema y SHA1 "hashing", adornado con archivos "lock" y "fsyncs" para robustez. De hecho, esto describe con exactitud las versiones anteriores de Git. Sin embargo, fuera de ingeniosos trucos de empaque para salvar espacio, e ingeniosos trucos de indexación para salvar tiempo, nosotros ahora sabemos definitivamente cómo Git cambia los sistemas de archivo en una base de datos perfecta para el control de versiones.

Por ejemplo, si cualquier archivo dentro de la base de datos es corrompido por un error
de disco, entonces su "hash" nunca más podrá ser emparejado, alertándonos del problema. Al
crear un "hash" de otros "hash" de otros objetos, mantenemos la integridad a todos los niveles. Los "commit"
son atómicos, eso es, un "commit" nunca puede guardar solamente partes de cambios: nosotros podemos
únicamente calcular el "hash" de un "commit" y guardarlo en la base de datos después de que ya
hemos guardado todos los árboles relevantes, los "blob" y los "commit" padres. La base de datos
de objetos es inmune a interrupciones inesperadas como cortes de electricidad.

Hemos derrotado inclusive al más tortuoso adversario. Suponga que alguien intenta
modificar furtivamente los contenidos de un archivo en una versión anterior de un proyecto. Para
mantener la base de datos de objetos sana, ellos deben cambiar también el "hash" del
objeto "blob" correspondiente porque ahora es una cadena de bytes distinta. Esto
significa que además tendrán que cambiar el "hash" de cualquier árbol de objetos referenciando el archivo,
y por defecto cambiar todos los "hash" de todos los descendientes del árbol de ese "commit". Además
de todos los "hash" de todos los descendientes de ese "commit".Esto implica que
el "hash" de la cabeza oficial difiere a la del repositorio erróneo. Para
seguir el curso de los "hash" que difieren podemos localizar el archivo mutilado,
así como el "commit" en donde fue corrompido inicialmente.

En corto tiempo, mientras que los 20 "byte" representando el último "commit" seguro,
es imposible de manosear en un repositorio de Git.

¿Qué sucede con las famosas características de Git? ¿Las ramas? ¿Las mezclas? ¿Los tags?
Simples detalles. La cabeza actual es mantenida en el archivo +.git/HEAD+,
la cual contiene un "hash" de un objeto "commit". El "hash" es actualizado durante un "commit"
así como cualquier otro comando. Las ramas son casi lo mismo: son archivos en
+.git/refs/heads+. Las etiquetas también: se encuentran en +.git/refs/tags+ pero
son actualizadas por un juego de comandos distintos.