2013-07-31 17 views
2

Voici ce que je voudrais faire:Git miroir local et le dépôt

  • Avoir un dépôt git locale qui reflète une amont un
  • pouvoir pousser les branches « locales »/modifications apportées à ce dépôt et garder les locaux
  • conserver ce dépôt en phase avec celui en amont, y compris:
    • toute nouvelle branche Fetch
    • Supprimer toute référence de son Ches qui sont supprimés en amont

-je configurer mon travail cron pour aller chercher tous les changements de l'amont et de pruneau toute branche qui ont été supprimés comme ceci:

*/5 * * * * cd /home/git/myrepo.git && git fetch origin && git remote prune origin > /dev/null 

Jusqu'à présent, ce que j'ai essayé (et pourquoi il n'a pas):

1- Configuration du dépôt git comme un miroir (comme décrit here)

git clone --bare --mirror URL 

Le problème avec cela est quand il fait le git remote prune, il supprime également des références aux changements "locaux" qui ont été poussés là (et pas au serveur en amont). J'ai également essayé de faire en sorte que ce référentiel local soit le miroir de deux dépôts séparés (avec le même maître mais avec des branches différentes) et que je rencontre un problème similaire en faisant git remote prune, il supprimera les branches provenant de l'autre référentiel.

2- git d'installation seulement en tant que dépôt nu:

git clone --bare URL 

Mais git fetch origin est pas mis à jour correctement, il semble être le téléchargement des objets, mais ne crée pas les refs et imprime seulement

* branch   HEAD  -> FETCH_HEAD 

et la "localisation" des branches actuelles n'est pas mise à jour avec ce qui est dans le serveur amont.

J'ai également essayé git remote update comme décrit here, avec le même résultat.

je peux convert that repository as a mirror avec:

git config remote.origin.fetch 'refs/heads/*:refs/heads/*' 

Mais cela me amène seulement à partir du problème (1)

+0

Il y a un conflit fondamental entre « avoir un miroir » (repo X est toujours identique, le délai de mise en miroir mod, en amont version UX) et "garder local c hanges "(repo X n'est certainement pas identique à UX en amont). Choisissez au plus un, puis décidez de la mise en œuvre. – torek

Répondre

2

En supposant que vous pouvez laisser tomber l'exigence du "miroir", et ont « local (nu) repo $ X copie également repo UX $ en amont à l'aide refs/têtes/amont/branche $ pour nommer les branches en amont connues là comme refs/heads/$ X », utilisez votre deuxième approche, mais le faire à la place:

$ cd /tmp; mkdir tt; cd tt; git clone --bare ssh://$upstream_host/tmp/t 
$ cd t.git 
$ git config remote.origin.fetch '+refs/heads/*:refs/heads/upstream/*' 
$ git fetch -p # accidentally omitted this step from cut/paste earlier 

Cela suppose que vous n'utiliserez pas de noms de branches comme upstream/master pour vous-même.(Vous pouvez aussi/au lieu de faire quelque chose comme:

git config remote.origin.fetch '+refs/*:refs/upstream/*' 

mais refs/upstream/* références ne sont pas copiés par la normale git clone, git fetch, etc., c'est donc plus d'une douleur pour utilisateurs « normaux » git.)

Faisons aussi un clone du repo --bare pour voir ce qui se passe au fur et à mesure. (Pour référence, sur $upstream_host, j'ai un repo git régulier.A $local_host, la machine pas tout à fait-miroir, j'ai /tmp/tt/t.git, un repo --bare qui fait cette chose de suivi en amont.Je suis en fait en utilisant le même hôte pour les deux mais le principe est ...)

$ cd /tmp; mkdir xt; cd xt; git clone ssh://$local_host/tmp/tt/t.git 
Cloning into 't'... 
remote: Counting objects: 96, done. 
remote: Compressing objects: 100% (54/54), done. 
remote: Total 96 (delta 33), reused 96 (delta 33) 
Receiving objects: 100% (96/96), 17.11 KiB | 0 bytes/s, done. 
Resolving deltas: 100% (33/33), done. 
Checking connectivity... done 

maintenant, je fait un changement sur $upstream_host en /tmp/t, et il commited. Retour sur $local_host:

$ cd /tmp/tt/t.git; git fetch -p origin # -p will prune deleted upstream/foo's 
remote: Counting objects: 5, done. 
remote: Compressing objects: 100% (4/4), done. 
remote: Total 4 (delta 1), reused 0 (delta 0) 
Unpacking objects: 100% (4/4), done. 
From ssh://$host/tmp/t 
+ c10e54c...5e01371 master  -> upstream/master (forced update) 

Ainsi, les modifications apportées apparaissent en amont dans votre « sorte d'un miroir, mais pas exactement » git nue comme un changement de upstream/master plutôt que master, ou plus généralement, upstream/$branch pour tout $branch. Si vous voulez les fusionner, vous devrez le faire manuellement. Mon exemple ci-dessous est un peu brouillon parce que le changement que j'ai fait sur $upstream_host était une réécriture de l'histoire (d'où toutes les choses forced update), qui finit par être exposé ici via les clones. Si vous ne voulez pas qu'il soit exposé, vous devrez noter quelles mises à jour ont été réécrites par l'historique et (en fait) les copier manuellement dans votre propre miroir, et ensuite sur n'importe quel clone de celui-ci. Je vais juste aller de l'avant et faire une vraie fusion.

Donc, maintenant nous allons à la pension non-nue sur $local_host, en /tmp/xt/t:

$ cd /tmp/xt/t 
$ git fetch 
remote: Counting objects: 5, done. 
remote: Compressing objects: 100% (4/4), done. 
remote: Total 4 (delta 1), reused 1 (delta 0) 
Unpacking objects: 100% (4/4), done. 
From ssh://$local_host/tmp/tt/t 
+ c10e54c...5e01371 upstream/master -> origin/upstream/master (forced update) 
$ git status 
# On branch master 
nothing to commit, working directory clean 
$ git log --oneline --decorate --graph 
* 5e01371 (origin/upstream/master) add ast example 
| * c10e54c (HEAD, origin/master, origin/HEAD, master) add ast example 
|/ 
* 309b36c add like_min.py 
... [snipped] 
$ git merge origin/upstream/master 

Merge remote-tracking branch 'origin/upstream/master' 

# Please enter a commit message to explain why this merge is necessary, 
# especially if it merges an updated upstream into a topic branch. 
# 
# Lines starting with '#' will be ignored, and an empty message aborts 
# the commit. 
... 
$ git push 
warning: push.default is unset; its implicit value is changing in 
Git 2.0 from 'matching' to 'simple'. To squelch this message 
... 
Counting objects: 1, done. 
Writing objects: 100% (1/1), 244 bytes | 0 bytes/s, done. 
Total 1 (delta 0), reused 0 (delta 0) 
To ssh://$local_host/tmp/tt/t.git 
    c10e54c..e571182 master -> master 

J'ai maintenant mis à jour le clone --bare ($local_host, /tmp/tt/t.git) via le clone non-nu pour fusionner les travail en amont dans mon local pas exactement un miroir. La révision HEAD est ma fusion, HEAD^1 est la mise à jour (cassé) d'origine qui était autrefois origin/upstream/master (avant tout la « mise à jour forcée » ing) et HEAD^2 est la mise à jour corrigée qui est maintenant origin/upstream/master (suite):

$ git rev-parse HEAD^2 origin/upstream/master 
5e013711f5d6eb3f643ef562d49a131852aa4aa1 
5e013711f5d6eb3f643ef562d49a131852aa4aa1 

(le nom est juste upstream/master dans le clone --bare, de sorte que le git rev-parse ci-dessus est de /tmp/xt/t pas /tmp/tt/t.git.)

+0

Merci pour les tests approfondis ... – Matthieu

Questions connexes