-
1. Inicio - Sobre el Control de Versiones
-
2. Fundamentos de Git
-
3. Ramificaciones en Git
-
4. Git en el Servidor
- 4.1 Los Protocolos
- 4.2 Configurando Git en un servidor
- 4.3 Generando tu clave pública SSH
- 4.4 Configurando el servidor
- 4.5 El demonio Git
- 4.6 HTTP Inteligente
- 4.7 GitWeb
- 4.8 GitLab
- 4.9 Git en un alojamiento externo
- 4.10 Resumen
-
5. Git en entornos distribuidos
-
6. GitHub
-
7. Herramientas de Git
- 7.1 Revisión por selección
- 7.2 Organización interactiva
- 7.3 Guardado rápido y Limpieza
- 7.4 Firmando tu trabajo
- 7.5 Buscando
- 7.6 Reescribiendo la Historia
- 7.7 Reiniciar Desmitificado
- 7.8 Fusión Avanzada
- 7.9 Rerere
- 7.10 Haciendo debug con Git
- 7.11 Submódulos
- 7.12 Agrupaciones
- 7.13 Replace
- 7.14 Almacenamiento de credenciales
- 7.15 Resumen
-
8. Personalización de Git
-
9. Git y Otros Sistemas
- 9.1 Git como Cliente
- 9.2 Migración a Git
- 9.3 Resumen
-
10. Los entresijos internos de Git
-
A1. Apéndice A: Git en otros entornos
- A1.1 Interfaces gráficas
- A1.2 Git en Visual Studio
- A1.3 Git en Eclipse
- A1.4 Git con Bash
- A1.5 Git en Zsh
- A1.6 Git en Powershell
- A1.7 Resumen
-
A2. Apéndice B: Integrando Git en tus Aplicaciones
- A2.1 Git mediante Línea de Comandos
- A2.2 Libgit2
- A2.3 JGit
-
A3. Apéndice C: Comandos de Git
- A3.1 Configuración
- A3.2 Obtener y Crear Proyectos
- A3.3 Seguimiento Básico
- A3.4 Ramificar y Fusionar
- A3.5 Compartir y Actualizar Proyectos
- A3.6 Inspección y Comparación
- A3.7 Depuración
- A3.8 Parcheo
- A3.9 Correo Electrónico
- A3.10 Sistemas Externos
- A3.11 Administración
- A3.12 Comandos de Fontanería
9.2 Git y Otros Sistemas - Migración a Git
Migración a Git
Si tiene una base de código existente en otro VCS pero ha decidido comenzar a usar Git, debe migrar su proyecto de una forma u otra. Esta sección revisa algunos importadores para sistemas comunes y luego demuestra cómo desarrollar su propio importador personalizado. Aprenderá a importar datos de varios de los sistemas SCM profesionales más grandes, ya que conforman la mayoría de los usuarios que están cambiando, y porque las herramientas de alta calidad para ellos son fáciles de conseguir.
Subversión
Si lee la sección anterior sobre el uso de git svn, usted puede usar fácilmente esas instrucciones para clonar un repositorio; luego, deje de usar el servidor de Subversión, presione en un nuevo servidor de Git y comience a usarlo. Si desea ver el historial, puede lograrlo tan rápido como pueda extraer los datos del servidor de Subversión (lo que puede llevar un tiempo).
Sin embargo, la importación no es perfecta; y porque tomará tanto tiempo, también puedes hacerlo bien. El primer problema es la información del autor. En Subversión, cada persona comprometida tiene un usuario en el sistema que está registrado en la información de confirmación. Los ejemplos en la sección anterior muestran schacon en algunos lugares, como la salida de culpa y el registro de git svn. Si desea asignar esto a mejores datos de autor de Git, necesita una asignación de los usuarios de Subversión a los autores de Git. Cree un archivo llamado users.txt que tenga esta asignación en un formato como este:
schacon = Scott Chacon <schacon@geemail.com>
selse = Someo Nelse <selse@geemail.com>
Para obtener una lista de los nombres de autor que utilizan SVN, puede ejecutar esto:
$ svn log --xml | grep author | sort -u | \
perl -pe 's/.*>(.*?)<.*/$1 = /'
Eso genera la salida del registro en formato XML, luego mantiene solo las líneas con la información del autor, descarta los duplicados y elimina las etiquetas XML. (Obviamente, esto solo funciona en una máquina con grep, sort y perl instalados). Luego, redirija esa salida a su archivo users.txt para que pueda agregar los datos de usuario equivalentes de Git al lado de cada entrada.
Puede proporcionar este archivo a git svn para ayudarlo a mapear los datos del autor con mayor precisión. También puede indicarle a git svn que no incluya los metadatos que normalmente importa Subversión, pasando --no-metadata al comando clone o init. Esto hace que su comando de importación se vea así:
$ git svn clone http://my-project.googlecode.com/svn/ \
--authors-file=users.txt --no-metadata -s my_project
Ahora debería tener una importación de Subversión más agradable en su directorio my_project. En lugar de commits que se ven así
commit 37efa680e8473b615de980fa935944215428a35a
Author: schacon <schacon@4c93b258-373f-11de-be05-5f7a86268029>
Date: Sun May 3 00:12:22 2009 +0000
fixed install - go to trunk
git-svn-id: https://my-project.googlecode.com/svn/trunk@94 4c93b258-373f-11de-
be05-5f7a86268029
se ven así:
commit 03a8785f44c8ea5cdb0e8834b7c8e6c469be2ff2
Author: Scott Chacon <schacon@geemail.com>
Date: Sun May 3 00:12:22 2009 +0000
fixed install - go to trunk
No solo el campo Autor se ve mucho mejor, sino que el git-svn-id ya no está allí.
También debería hacer un poco de limpieza posterior a la importación. Por un lado, debe limpiar las referencias raras que git svn configuró. Primero moverá las etiquetas para que sean etiquetas reales en lugar de ramas remotas extrañas, y luego moverá el resto de las ramas para que sean locales.
Para mover las etiquetas para que sean etiquetas Git correctas, ejecuta
$ cp -Rf .git/refs/remotes/origin/tags/* .git/refs/tags/
$ rm -Rf .git/refs/remotes/origin/tags
Esto toma las referencias que eran ramas remotas que comenzaron con controles remotos / origen / etiquetas / y las convierte en etiquetas reales (ligeras).
A continuación, mueva el resto de las referencias en refs / remotes para que sean ramas locales:
$ cp -Rf .git/refs/remotes/* .git/refs/heads/
$ rm -Rf .git/refs/remotes
Ahora todas las ramas antiguas son ramas reales de Git y todas las etiquetas antiguas son etiquetas Git reales. Lo último que debe hacer es agregar su nuevo servidor Git como un control remoto y pulsarlo. Aquí hay un ejemplo de cómo agregar su servidor como un control remoto:
$ git remote add origin git@my-git-server:myrepository.git
Como quiere que todas sus ramas y etiquetas suban, ahora puede ejecutar esto:
$ git push origin --all
Todas sus ramas y etiquetas deben estar en su nuevo servidor Git en una importación agradable y limpia..
Mercurial
Since Mercurial and Git have fairly similar models for representing versions, and since Git is a bit more flexible, converting a repository from Mercurial to Git is fairly straightforward, using a tool called "hg-fast-export", which you’ll need a copy of:
$ git clone http://repo.or.cz/r/fast-export.git /tmp/fast-export
The first step in the conversion is to get a full clone of the Mercurial repository you want to convert:
$ hg clone <remote repo URL> /tmp/hg-repo
The next step is to create an author mapping file.
Mercurial is a bit more forgiving than Git for what it will put in the author field for changesets, so this is a good time to clean house.
Generating this is a one-line command in a bash
shell:
$ cd /tmp/hg-repo
$ hg log | grep user: | sort | uniq | sed 's/user: *//' > ../authors
This will take a few seconds, depending on how long your project’s history is, and afterwards the /tmp/authors
file will look something like this:
bob
bob@localhost
bob <bob@company.com>
bob jones <bob <AT> company <DOT> com>
Bob Jones <bob@company.com>
Joe Smith <joe@company.com>
In this example, the same person (Bob) has created changesets under four different names, one of which actually looks correct, and one of which would be completely invalid for a Git commit.
Hg-fast-export lets us fix this by adding ={new name and email address}
at the end of every line we want to change, and removing the lines for any usernames that we want to leave alone.
If all the usernames look fine, we won’t need this file at all.
In this example, we want our file to look like this:
bob=Bob Jones <bob@company.com>
bob@localhost=Bob Jones <bob@company.com>
bob jones <bob <AT> company <DOT> com>=Bob Jones <bob@company.com>
bob <bob@company.com>=Bob Jones <bob@company.com>
The next step is to create our new Git repository, and run the export script:
$ git init /tmp/converted
$ cd /tmp/converted
$ /tmp/fast-export/hg-fast-export.sh -r /tmp/hg-repo -A /tmp/authors
The -r
flag tells hg-fast-export where to find the Mercurial repository we want to convert, and the -A
flag tells it where to find the author-mapping file.
The script parses Mercurial changesets and converts them into a script for Git’s "fast-import" feature (which we’ll discuss in detail a bit later on).
This takes a bit (though it’s much faster than it would be over the network), and the output is fairly verbose:
$ /tmp/fast-export/hg-fast-export.sh -r /tmp/hg-repo -A /tmp/authors
Loaded 4 authors
master: Exporting full revision 1/22208 with 13/0/0 added/changed/removed files
master: Exporting simple delta revision 2/22208 with 1/1/0 added/changed/removed files
master: Exporting simple delta revision 3/22208 with 0/1/0 added/changed/removed files
[…]
master: Exporting simple delta revision 22206/22208 with 0/4/0 added/changed/removed files
master: Exporting simple delta revision 22207/22208 with 0/2/0 added/changed/removed files
master: Exporting thorough delta revision 22208/22208 with 3/213/0 added/changed/removed files
Exporting tag [0.4c] at [hg r9] [git :10]
Exporting tag [0.4d] at [hg r16] [git :17]
[…]
Exporting tag [3.1-rc] at [hg r21926] [git :21927]
Exporting tag [3.1] at [hg r21973] [git :21974]
Issued 22315 commands
git-fast-import statistics:
---------------------------------------------------------------------
Alloc'd objects: 120000
Total objects: 115032 ( 208171 duplicates )
blobs : 40504 ( 205320 duplicates 26117 deltas of 39602 attempts)
trees : 52320 ( 2851 duplicates 47467 deltas of 47599 attempts)
commits: 22208 ( 0 duplicates 0 deltas of 0 attempts)
tags : 0 ( 0 duplicates 0 deltas of 0 attempts)
Total branches: 109 ( 2 loads )
marks: 1048576 ( 22208 unique )
atoms: 1952
Memory total: 7860 KiB
pools: 2235 KiB
objects: 5625 KiB
---------------------------------------------------------------------
pack_report: getpagesize() = 4096
pack_report: core.packedGitWindowSize = 1073741824
pack_report: core.packedGitLimit = 8589934592
pack_report: pack_used_ctr = 90430
pack_report: pack_mmap_calls = 46771
pack_report: pack_open_windows = 1 / 1
pack_report: pack_mapped = 340852700 / 340852700
---------------------------------------------------------------------
$ git shortlog -sn
369 Bob Jones
365 Joe Smith
That’s pretty much all there is to it. All of the Mercurial tags have been converted to Git tags, and Mercurial branches and bookmarks have been converted to Git branches. Now you’re ready to push the repository up to its new server-side home:
$ git remote add origin git@my-git-server:myrepository.git
$ git push origin --all
Perforce
El siguiente sistema que verá importando es Perforce Como mencionamos anteriormente, hay dos formas de que Git y Perforce hablen entre sí: git-p4 y Perforce Git Fusion.
Perforce Git Fusion
Git Fusion hace que este proceso sea bastante sencillo. Simplemente elija la configuración de su proyecto, las asignaciones de usuario y las ramas con un archivo de configuración (como se explica en << _ p4_git_fusion >>) y clone el repositorio. Git Fusion te deja con lo que parece ser un repositorio nativo de Git, que luego está listo para enviar a un host nativo de Git si lo deseas. Incluso puede usar Perforce como su host Git si gusta.
Git-p4
Git-p4 también puede actuar como una herramienta de importación. Como ejemplo, importaremos el proyecto Jam desde Perforce Public Depot. Para configurar su cliente, debe exportar la variable de entorno P4PORT para que se dirija al depósito de Perforce:
$ export P4PORT=public.perforce.com:1666
Nota
|
Para poder seguir, necesitarás un depósito de Perforce para conectarte. Utilizaremos el depósito público en public.perforce.com para ver nuestros ejemplos, pero puede usar cualquier depósito al que tenga acceso. |
Ejecute el comando git p4 clone
para importar el proyecto Jam desde el servidor Perforce, proporcionando la ruta de depósito y proyecto y la ruta en la que desea importar el proyecto:
$ git-p4 clone //guest/perforce_software/jam@all p4import
Importación desde //guest/perforce_software/jam@all into p4import
Inicializó el repositorio vacío de Git en /private/tmp/p4import/.git/
Destino de importación: refs/remotes/p4/master
Importando revisión 9957 (100%)
Este proyecto en particular tiene solo una rama, pero esta configurado con vistas de ramificaciones (o simplemente un conjunto de directorios), y puede usar el indicador --detect-branches
en` git p4 clone` para importar todas las ramas del proyecto. Ver << _ git_p4_branches >> para un poco más de detalle sobre esto.
En este punto, casi has terminado.
Si va al directorio p4import
y ejecuta` git log`, puede ver su trabajo importado:
$ git log -2
commit e5da1c909e5db3036475419f6379f2c73710c4e6
Autor: giles <giles@giles@perforce.com>
Información: Wed Feb 8 03:13:27 2012 -0800
Corrección a línea 355; change </UL> to </OL>.
[git-p4: depot-paths = "//public/jam/src/": change = 8068]
commit aa21359a0a135dda85c50a7f7cf249e4f7b8fd98
Autor: kwirth <kwirth@perforce.com>
Información: Tue Jul 7 01:35:51 2009 -0800
Corrige el error de ortografía en la página Jam doc (cummulative -> cumulative).
[git-p4: depot-paths = "//public/jam/src/": change = 7304]
Puede ver que git-p4
ha dejado un identificador en cada mensaje de confirmación.
Está bien mantener ese identificador allí, en caso de que necesite hacer referencia al número de cambio Perforce más adelante.
Sin embargo, si desea eliminar el identificador, ahora es el momento de hacerlo, antes de comenzar a trabajar en el nuevo repositorio.
Puede usar git filter-branch
para eliminar las cadenas de identificador en masa:
$ git filter-branch --msg-filter 'sed -e "/^\[git-p4:/d"'
Rewrite e5da1c909e5db3036475419f6379f2c73710c4e6 (125/125)
Ref 'refs/heads/master' was rewritten
Si ejecuta git log
, puede ver que todas las sumas de comprobación SHA-1 para las confirmaciones han cambiado, pero las cadenas` git-p4` ya no se encuentran en los mensajes de confirmación:
$ git log -2
commit b17341801ed838d97f7800a54a6f9b95750839b7
Autor: giles <giles@giles@perforce.com>
Información: Wed Feb 8 03:13:27 2012 -0800
Corrección a linea 355; change </UL> to </OL>.
commit 3e68c2e26cd89cb983eb52c024ecdfba1d6b3fff
Autor: kwirth <kwirth@perforce.com>
Información: Tue Jul 7 01:35:51 2009 -0800
Corrige el error de ortografía en la página Jam doc (cummulative -> cumulative).
Su importación está lista para subir a su nuevo servidor Git.
TFS
Si su equipo está convirtiendo su control de código fuente de TFVC a Git, querrá la conversión de mayor fidelidad que pueda obtener. Esto significa que mientras cubrimos git-tfs y git-tf para la sección de interoperabilidad, sólo cubriremos git-tfs para esta parte, porque git-tfs soporta ramificaciones, y esto es prohibitivamente difícil usando git-tf.
Nota
|
Se trata de una conversión unidireccional. El repositorio Git resultante no podrá conectarse con el proyecto TFVC original. |
The first thing to do is map usernames.
TFVC is fairly liberal with what goes into the author field for changesets, but Git wants a human-readable name and email address.
You can get this information from the tf
command-line client, like so:
PS> tf history $/myproject -recursive > AUTHORS_TMP
Esto agarra todos los conjuntos de cambios de la historia del proyecto y lo coloca en el archivo AUTHORS_TMP que procesaremos para extraer los datos de la columna Usuario (el segundo).
Abre el archivo y busca en qué caracteres comienzan y terminan la columna y reemplazan, en la línea de comandos siguiente, los parámetros 11-20
del comando` cut` con los que se encuentran:
PS> cat AUTHORS_TMP | cut -b 11-20 | tail -n+3 | uniq | sort > AUTHORS
El comando cut
mantiene sólo los caracteres entre 11 y 20 de cada línea.
El comando tail
omite las dos primeras líneas, que son cabeceras de campo y subrayados ASCII-art.
El resultado de todo esto se canaliza a uniq
para eliminar duplicados y se guarda en un archivo llamado` AUTHORS`.
El siguiente paso es manual; Para que git-tfs haga un uso efectivo de este archivo, cada línea debe estar en este formato:
DOMAIN\username = User Name <email@address.com>
La parte de la izquierda es el campo “Usuario” de TFVC, y la porción en el lado derecho del signo de iguales es el nombre de usuario que se utilizará para los compromisos de Git.
Una vez que tengas este archivo, lo siguiente que debes hacer es hacer un clon completo del proyecto TFVC en el que estás interesado:
PS> git tfs clone --with-branches --authors=AUTHORS https://username.visualstudio.com/DefaultCollection $/project/Trunk project_git
A continuación, deseará limpiar las secciones git-tfs-id
desde la parte inferior de los mensajes de confirmación.
El siguiente comando hará lo siguiente:
PS> git filter-branch -f --msg-filter 'sed "s/^git-tfs-id:.*$//g"' -- --all
Que utiliza el comando sed
desde el entorno Git-bash para reemplazar cualquier línea que empiece por “git-tfs-id:” con vacío, que Git luego ignorará.
Una vez que todo está hecho, estás listo para añadir un nuevo mando a distancia, empujar todas sus ramas hacia arriba, y hacer que su equipo comience a trabajar desde Git.
Un proveedor individual
Si su sistema no es uno de los arriba mencionados, usted debe buscar un importador online - importadores de calidad están disponibles para muchos otros sistemas, incluido el CVS, Clear Case, Visual Source Safe, incluso un directorio de archivos. Si ninguna de estas herramientas funciona para usted, tiene una herramienta más obsoleta o necesita un método de importación más personalizado, debería usar ‘git fast-import’.. Este comando lee instrucciones simples de stdin para escribir datos Git específicos. Es mucho más fácil crear objetos Git de esta manera que ejecutar los comandos raw Git o intentar escribir los objetos raw (ver [ch10-git-internals] para más información). De esta manera, puede escribir un script de importación que lee la documentación necesaria del sistema desde el que está cargando e imprime instrucciones directas a stdout. A continuación, puede ejecutar este programa y canalizar su resultado mediante `git fast-import
Para demostrar rápidamente, podrá escribir un simple mensaje
Supongamos que trabajas en current
, haces una copia de seguridad de tu proyecto copiando el directorio ocasionalmente en un directorio de copia de seguridad con el código ‘back_YYYY_MM_DD" directorio de copia de seguridad y desea importar esta en Git.
Tu Estructura del directorio se ve así:
$ ls /opt/import_from
back_2014_01_02
back_2014_01_04
back_2014_01_14
back_2014_02_03
current
Para poder importar un directorio Git, necesitas revisar cómo Git almacena sus datos. Como recordará, Git es fundamentalmente una listado enlazado de objetos commit que apuntan a una imágen de contenido. Todo lo que tienes por hacer es indicarle a `fast-import`qué son las snapshots de contenido, cuáles son los puntos de datos de confirmación y el orden en que van a entrar. Su estrategia será para ir a través de snapshots Uno a la vez y crear commits con el contenido de cada directorio, vinculando cada commit al anterior.
Como hicimos en Un ejemplo de implantación de una determinada política en Git, scribiremos esto en Ruby, porque es con lo que generalmente trabajamos y tiende a ser fácilmente legible.Usted puede escribir este ejemplo con bastante facilidad en cualquier elemento con el que esté familiarizado - sólo tiene que escribir la información apropiada a "stdout"., si se está ejecutando en Windows, esto significa que usted tendrá que tener especial cuidado de no introducir porte devoluciones al final de sus líneas - Importación rápida de git es muy particular acerca de que sólo quieren saltos de línea (LF) salto de línea (CRLF) usando windows.
Para empezar, cambiará al directorio de destino e identificará cada subdirectorio, cada uno de los cuales es snapshot que desea importar como un commit. Cambiará a cada subdirectorio e imprimirán los comandos necesarios para exportarlo. Tu loop principal básico se ve así:
last_mark = nil
# loop through the directories
Dir.chdir(ARGV[0]) do
Dir.glob("*").each do |dir|
next if File.file?(dir)
# move into the target directory
Dir.chdir(dir) do
last_mark = print_export(dir, last_mark)
end
end
end
Si ejecuta print_export
dentro del directorio, que toma el registro y la señal de la instantánea anterior y devuelve el registro y la señal de ésta; de esa manera, se pueden enlazar correctamente.“Mark” is the fast-import
para un código de identificación que se da a un commit; mientras crea commits,dar a cada uno de ellos una anotación que se puede utilizar para vincular al mismo desde otro commits.
Por lo tanto, lo primero que debe hacer en el método ‘print_export’ es generar una etiqueta a partir del nombre del directorio:
mark = convert_dir_to_mark(dir)
Para ello, creará una matriz de directorios y utilizará el valor índice como punto, ya que una línea debe ser un código entero. Tu sistema se ve así:
$marks = []
def convert_dir_to_mark(dir)
if !$marks.include?(dir)
$marks << dir
end
($marks.index(dir) + 1).to_s
end
Ahora que tiene una representación entera de su commit, necesita una dirección para los metadatos de commit.
Como la información está expresada en el nombre del directorio, la analizarás.
La siguiente línea del archivo print_export
es
date = convert_dir_to_date(dir)
Donde`convert_dir_to_date` esta definido como
def convert_dir_to_date(dir)
if dir == 'current'
return Time.now().to_i
else
dir = dir.gsub('back_', '')
(year, month, day) = dir.split('_')
return Time.local(year, month, day).to_i
end
end
Esto devuelve un valor entero para la data de cada directorio. La última parte de la meta-información que necesita para cada committer son los datos del committer, que usted codifica en una variable global:
$author = 'John Doe <john@example.com>'
Ahora está listo para empezar a publicar los datos de validación para su importador.: La información inicial indica que está definiendo un objeto de commit y en qué rama está activado, seguido de la línea que ha generado, la información de committer y el mensaje de committer y, a continuación, la línea anterior, si la hay. El código se ve así:
# print the import information
puts 'commit refs/heads/master'
puts 'mark :' + mark
puts "committer #{$author} #{date} -0700"
export_data('imported from ' + dir)
puts 'from :' + last_mark if last_mark
Usted codifica la zona horaria (-0700) porque hacerlo es fácil.
Si está importando desde otro sistema, debe especificar el uso horario como un intervalo de tiempo. El mensaje de confirmación debe expresarse en un formato especial:
data (size)\n(contents)
El formato consiste en los datos de la palabra, el tamaño de los datos a leer, una nueva línea, y finalmente los datos. Puesto que necesita utilizar el mismo formato para especificar el contenido del archivo más tarde, cree un sistema de ayuda,"export_data":[source,ruby]
def export_data(string) print "data #{string.size}\n#{string}" end
Todo lo que queda es especificar el contenido del archivo para cada uno de ellos. snapshot.
Esto es fácil, porque tiene cada uno de ellos en un directorio - puede crear el comando borrar todo
seguido del contenido de cada archivo en el directorio.
Git entonces grabará cada instantánea apropiadamente:
puts 'deleteall'
Dir.glob("**/*").each do |file|
next if !File.file?(file)
inline_data(file)
end
Nota: Porque muchos sistemas piensan que sus modificaciones son cambios de una confirmación a otra, fast-import también puede tomar comandos con cada confirmación para especificar qué archivos se han agregado, eliminado o modificado y cuáles son los nuevos archivos. Podrías calcular las diferencias entre snapshots y proporcionar sólo estos archivos, pero hacerlo es más complejo - también puedes darle a Git todos los datos y dejar que lo resuelva. Si esto se adapta mejor a sus archivos, consulte la página de manual "Importación rápida" para obtener más detalles sobre cómo proporcionar sus archivos de esta manera. El formato para listar el nuevo contenido del archivo o especificar un archivo modificado con el nuevo contenido es el siguiente:
M 644 inline path/to/file
data (size)
(file contents)
Aquí, 644 es el modulo (si tiene archivos ejecutables, necesita detectar y especificar 755 en su lugar), e inline dice que listará el archivo inmediatamente después de esta línea. Su método de "datos_inline" se ve así:
def inline_data(file, code = 'M', mode = '644')
content = File.read(file)
puts "#{code} #{mode} inline #{file}"
export_data(content)
end
Se reutiliza el modo export_data
que definió anteriormente, porque es el mismo que el de los datos del mensaje de confirmación.
Lo último que necesita hacer es devolver la línea actual para que pueda pasar a la siguiente edición:
return mark
Nota
|
Si se está ejecutando en Windows, deberá asegurarse de añadir un paso más. Como se ha dicho antes, Windows utiliza CRLF para nuevos carácteres de línea, mientras que git fast-import sólo espera LF. Para solucionar este problema y hacer git fast-importar feliz, necesita decirle a ruby para utilizar LF en lugar de CRLF:
|
Eso es todo. Aquí está el script en su totalidad:
#!/usr/bin/env ruby
$stdout.binmode
$author = "John Doe <john@example.com>"
$marks = []
def convert_dir_to_mark(dir)
if !$marks.include?(dir)
$marks << dir
end
($marks.index(dir)+1).to_s
end
def convert_dir_to_date(dir)
if dir == 'current'
return Time.now().to_i
else
dir = dir.gsub('back_', '')
(year, month, day) = dir.split('_')
return Time.local(year, month, day).to_i
end
end
def export_data(string)
print "data #{string.size}\n#{string}"
end
def inline_data(file, code='M', mode='644')
content = File.read(file)
puts "#{code} #{mode} inline #{file}"
export_data(content)
end
def print_export(dir, last_mark)
date = convert_dir_to_date(dir)
mark = convert_dir_to_mark(dir)
puts 'commit refs/heads/master'
puts "mark :#{mark}"
puts "committer #{$author} #{date} -0700"
export_data("imported from #{dir}")
puts "from :#{last_mark}" if last_mark
puts 'deleteall'
Dir.glob("**/*").each do |file|
next if !File.file?(file)
inline_data(file)
end
mark
end
# Loop through the directories
last_mark = nil
Dir.chdir(ARGV[0]) do
Dir.glob("*").each do |dir|
next if File.file?(dir)
# move into the target directory
Dir.chdir(dir) do
last_mark = print_export(dir, last_mark)
end
end
end
If you run this script, you’ll get content that looks something like this:
$ ruby import.rb /opt/import_from
commit refs/heads/master
mark :1
committer John Doe <john@example.com> 1388649600 -0700
data 29
imported from back_2014_01_02deleteall
M 644 inline README.md
data 28
# Hello
This is my readme.
commit refs/heads/master
mark :2
committer John Doe <john@example.com> 1388822400 -0700
data 29
imported from back_2014_01_04from :1
deleteall
M 644 inline main.rb
data 34
#!/bin/env ruby
puts "Hey there"
M 644 inline README.md
(...)
Para ejecutar el importador, se debe pasar esta señal a través de git fast-import
mientras que en el directorio Git se desea copiar.
Puede crear un nuevo directorio y luego ejecutar git init
en él para un punto de partida, y luego ejecutar su script:
$ git init
Initialized empty Git repository in /opt/import_to/.git/
$ ruby import.rb /opt/import_from | git fast-import
git-fast-import statistics:
---------------------------------------------------------------------
Alloc'd objects: 5000
Total objects: 13 ( 6 duplicates )
blobs : 5 ( 4 duplicates 3 deltas of 5 attempts)
trees : 4 ( 1 duplicates 0 deltas of 4 attempts)
commits: 4 ( 1 duplicates 0 deltas of 0 attempts)
tags : 0 ( 0 duplicates 0 deltas of 0 attempts)
Total branches: 1 ( 1 loads )
marks: 1024 ( 5 unique )
atoms: 2
Memory total: 2344 KiB
pools: 2110 KiB
objects: 234 KiB
---------------------------------------------------------------------
pack_report: getpagesize() = 4096
pack_report: core.packedGitWindowSize = 1073741824
pack_report: core.packedGitLimit = 8589934592
pack_report: pack_used_ctr = 10
pack_report: pack_mmap_calls = 5
pack_report: pack_open_windows = 2 / 2
pack_report: pack_mapped = 1457 / 1457
---------------------------------------------------------------------
Como puedes ver, cuando se completa con éxito, te da un conjunto de estadísticas sobre lo que logró.
En este caso, ha importado un total de 13 objetos para 4 confirmaciones en 1 rama.
Ahora, puedes ejecutar git log
para ver tu nueva historial:
$ git log -2
commit 3caa046d4aac682a55867132ccdfbe0d3fdee498
Author: John Doe <john@example.com>
Date: Tue Jul 29 19:39:04 2014 -0700
imported from current
commit 4afc2b945d0d3c8cd00556fbe2e8224569dc9def
Author: John Doe <john@example.com>
Date: Mon Feb 3 01:00:00 2014 -0700
imported from back_2014_02_03
Ahí tienes, un buen y limpio depósito de Git. Es importante tener en cuenta que nada está comprobado - no tiene archivos en su directorio de trabajo al principio. Para obtenerlos, debe reajustar su rama a donde "maestro" está ahora:
$ ls
$ git reset --hard master
HEAD is now at 3caa046 imported from current
$ ls
README.md main.rb
Puedes hacer mucho más con la herramienta "Importación rápida": maneja diferentes modos, datos binarios, múltiples ramas y fusiones, etiquetas, indicadores de progreso y mucho más. Varios ejemplos de escenarios más complejos están disponibles en el directorio ‘contrib/fast-import’ del código fuente Git.