4

これが私がやりたいことです:

  • アップストリームのリポジトリをミラーリングするローカル git リポジトリを用意する
  • 「ローカル」ブランチ/変更をそのリポジトリにプッシュし、それらをローカルに保持できる
  • このリポジトリをアップストリームのリポジトリと同期させます。これには次のものが含まれます。
    • 新しいブランチをフェッチする
    • アップストリームで削除されたブランチの参照を削除します

次のように、アップストリームからすべての変更を取得し、削除されたブランチを整理するように cron ジョブをセットアップします。

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

これまでに試したこと(および失敗した理由):

1- git リポジトリをミラーとしてセットアップします (ここで説明されているように)

git clone --bare --mirror URL

それに関する問題は、それが実行されるときであり、git remote pruneそこにプッシュされた(上流サーバーではなく)「ローカル」変更への参照も削除されます。

また、このローカル リポジトリを 2 つの個別のリポジトリ (マスターは同じですが、ブランチがいくつか異なる) のミラーにしようとしましたが、実行時に同様の問題が発生git remote pruneし、他のリポジトリからのブランチが削除されます。

2- ベア リポジトリとしてのみ git をセットアップします。

git clone --bare URL

しかし、git fetch origin適切に更新されていません。オブジェクトをダウンロードしているようですが、参照を作成せずに印刷するだけです

 * branch            HEAD       -> FETCH_HEAD

現在のブランチの「場所」は、上流のサーバーにあるもので更新されていません。

私もここgit remote updateで説明したように試してみましたが、同じ結果が得られました。

そのリポジトリをミラーとして変換するには、次のようにします。

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

しかし、それは(1)の問題に戻るだけです

4

1 に答える 1

5

「ミラー」要件を削除でき、「ローカル (ベア) リポジトリ $X も、refs/heads/upstream/$branch を使用して上流リポジトリ $UX をコピーし、そこで refs/heads/$X として知られる上流ブランチに名前を付けることができる」と仮定すると、 2 番目のアプローチを使用しますが、代わりに次のようにします。

$ 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

upstream/masterこれは、自分で何かのようにブランチ名を使用しないことを前提としています。(また/代わりに次のようなこともできます:

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

しかし、参照は通常の、 などでrefs/upstream/*はコピーされないため、これは「通常の」git ユーザーにとっては苦痛です。)git clonegit fetch

--bare先に進むにつれて何が起こるかを確認するために、レポのクローンも作成しましょう。(参考までに$upstream_host、 には/tmp/t、通常の git リポジトリがあります。$local_host完全にミラー化されていないマシンである には/tmp/tt/t.git--bareこの上流の追跡を行うリポジトリがあります。実際には両方に同じホストを使用していますが、原則は適用されます。 ..)

$ 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

に変更を加え、$upstream_hostコミット/tmp/tしました。戻る$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)

したがって、アップストリームで行われた変更は、「ミラーのようなものですが、正確ではない」裸の git リポジトリに、より一般的には への変更としてupstream/master表示masterupstream/$branchれます$branch。それらをマージしたい場合は、手動で行う必要があります。以下の私の例は、私が行った変更$upstream_hostが履歴の書き換え (したがってすべてのforced updateもの) であり、クローンを介してここに公開されることになるため、少し面倒です。公開したくない場合は、どの更新が履歴の書き換えであったかをメモし、(事実上) 手動でそれらを独自の非完全ミラーにコピーしてから、そのクローンにコピーする必要があります。先に進んで実際のマージを行います。

では、 の非裸レポに移動$local_host/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

--bareクローン ( $local_host, ) を裸でないクローンを介して更新/tmp/tt/t.gitし、アップストリームの作業をローカルの正確にミラー化されていないものにマージしました。リビジョンは私のHEADマージでHEAD^1あり、元の (壊れた) 更新origin/upstream/master(すべての「強制更新」の前) であり、現在(その後)HEAD^2の修正された更新です。origin/upstream/master

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

(名前はクローンにあるだけupstream/master--bareので、git rev-parse上記は/tmp/xt/tnotからのもの/tmp/tt/t.gitです。)

于 2013-07-31T22:12:33.467 に答える