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
.)
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