2010-04-21 20 views
9

Estoy tratando de configurar un espejo darcs de un repositorio git. Tengo algo que funciona bien, pero hay un problema importante: si presiono un montón de confirmaciones para el repositorio de git, esas confirmaciones se fusionan en un solo parche de darcs. Realmente quiero asegurarme de que cada commit de git se configure como un único parche de darcs. Apuesto a que esto es posible haciendo algún tipo de git fetch seguido de un interrogatorio de la copia local de la sucursal remota, pero mi git fu no está a la altura.¿Cómo extraer un compromiso a la vez de un repositorio remoto de git?

Aquí está el código (ksh) estoy usando ahora, más o menos:

git pull -v # pulls all the commits from remote --- bad! 

# gets information about only the last commit pulled -- bad! 
author="$(git log HEAD^..HEAD --pretty=format:"%an <%ae>")" 
logfile=$(mktemp) 
git log HEAD^..HEAD --pretty=format:"%s%n%b%n" > $logfile 

# add all new files to darcs and record a patchset. this part is OK 
darcs add -q --umask=0002 -r . 
darcs record -a -A "$author" --logfile="$logfile" 
darcs push -a 
rm -f $logfile 

Mi idea es

  1. Trate git fetch para obtener copia local de la rama remota (no estoy seguro exactamente qué argumentos son necesarios)
  2. De alguna manera interrogar a la copia local para obtener un hash para cada confirmación desde la última operación de duplicación (no tengo ni idea de cómo hacerlo)
  3. Recorrer todos los hashes, tirando sólo que cometió y que registran el conjunto de parches asociados (estoy bastante seguro de que sabe cómo hacer esto si le ponga las manos en el hash)

daría la bienvenida a cualquiera ayuda descarnado fuera del escenario anterior o sugerencias sobre algo más que debo probar.

Ideas?

+0

Solo como recordatorio, hay un par de nuevas respuestas a continuación que no ha comentado. (Obviamente uno de ellos creo que en realidad responde muy bien a tu pregunta;)) –

Respuesta

0

git remote update # fetch all remotes I like it better than just fetch

git log origin/master # can be any remote/branch

git cherry-pick origin/master # example remote/branch you can also specify a sha1

cereza-escoge recogerá el parche superior por defecto.

para la tercera parte Creo que tendrás que escribir un script para que lo haga por ti. hay otras formas de obtener los hash y muchas opciones para el registro. De hecho, puede haber un gancho para cherry-pick o tal vez solo post commit ... para ejecutar el código de darcs. echa un vistazo a los ganchos git.

de hecho, cada parche aplicado en una rebase podría llamar a un enganche git commit para que pueda escribir eso y luego hacer un git pull --rebase y tener ese código en cada solicitud ...

+0

+1 por citar githooks. – jweyrich

+1

He estudiado información en la web para 'git cherry-pick', ¡y no es lo que quiero en absoluto! ¡Crea un nuevo compromiso distinto! Profundizaré más. –

0

Utilice esta opción para recuperar los hash de una rama:

git log --pretty=format:"%h" HEAD..origin/master 

a continuación, utilice git cherry-pick -n <hash> aplicar cada uno.

Otra opción, citada por @xenoterracide, es usar githooks.

+4

He estudiado información en la web para 'git cherry-pick', ¡y no es lo que quiero en absoluto! ¡Crea un nuevo compromiso distinto! Profundizaré más. –

2

¿Ha intentado ver algunas soluciones existentes para mover conjuntos de cambios entre sistemas de control de versiones, como Tailor, que dice que incluye soporte para git y darcs? (Hay sugerencias para sistemas similares en esa página también.)

De lo contrario, si desea utilizar el enfoque propuesto, se podría utilizar git checkout en cada confirmación después de HEAD a origin/master a la caja que cometen en la "cabeza separada" modo de .Por ejemplo, para modificar el ejemplo que das (y en shell Bourne, me temo, ya que yo no uso ksh):

# Update all remote-tracking branches from origin 
git fetch origin 

for c in `git log --pretty=format:"%h" HEAD..origin/master` 
do 
    git checkout $c 
    author=$(git log -1 --pretty=format:"%an <%ae>") 
    logfile=$(mktemp) 
    git log -1 --pretty=format:"%s%n%n%b%n" > $logfile 

    darcs add -q --umask=0002 -r . 
    darcs record -a -A "$author" --logfile="$logfile" 
    darcs push -a 
    rm -f $logfile   
done 

# Now go back to master, and merge to keep your master branch up to date: 
git checkout master 
git merge origin/master 

Tenga en cuenta que esto va a linealizar la historia de Git, que no lo haría ser lo que yo quería, personalmente. :) Creo que es mejor usar una herramienta existente para esto, pero el enfoque anterior podría funcionar.

1

se podría hacer algo como esto:

#!/bin/bash 
git fetch 
count=$(git log --pretty=oneline | wc -l) 
git merge origin/master 
git reset --hard HEAD~$((count-1)) 

he creado un repositorio para este guión y probé. A continuación se presenta antes y después de la fusión:

enter image description here

enter image description here

Ahora yo no tenía un repositorio remoto de modo que fingí el git fetch y la rama remota con un local (llamado Kalle), pero entiendes la idea Solo haz la fusión completa y luego haz una copia de seguridad del puntero HEAD hasta llegar al primer compromiso desde el origen/maestro.

Cuestiones relacionadas