【问题标题】:Git local mirror and repositoryGit本地镜像和存储库
【发布时间】:2013-08-01 14:14:12
【问题描述】:

这是我想做的:

  • 拥有一个镜像上游的本地 git 存储库
  • 能够将“本地”分支/更改推送到该存储库并保留在本地
  • 保持此存储库与上游存储库同步,包括:
    • 获取任何新分支
    • 删除上游删除的分支的任何引用

我设置我的 cron 作业以从上游获取所有更改并修剪任何已删除的分支,如下所示:

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

到目前为止我尝试过的(以及失败的原因):

1- 将 git 存储库设置为镜像(如 here 所述)

git clone --bare --mirror URL

问题在于,当它执行git remote prune 时,它还会删除对已推送到那里(而不是上游服务器)的“本地”更改的引用。

我还尝试让这个本地存储库成为两个独立存储库的镜像(具有相同的主存储库但有一些不同的分支),并且在执行git remote prune 时遇到了类似的问题,它将删除来自另一个存储库的分支.

2- 仅将 git 设置为裸存储库:

git clone --bare URL

但是git fetch origin 没有正确更新,它似乎正在下载对象,但没有创建参考,然后只打印

 * branch            HEAD       -> FETCH_HEAD

并且当前分支的“位置”并未使用上游服务器中的内容进行更新。

我还按照here 的描述尝试了git remote update,结果相同。

我可以convert that repository as a mirror 与:

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

但这只会让我回到 (1) 中的问题

【问题讨论】:

  • “有一个镜像”(repo X 总是相同,mod 镜像延迟,作为上游版本 UX)和“保持本地更改”(repo X 与上游 UX 绝对不同)之间存在根本冲突)。最多选择一个,然后决定实施。

标签: git mirror


【解决方案1】:

假设您可以放弃“镜像”要求,并让“本地(裸)repo $X 也使用 refs/heads/upstream/$branch 复制上游 repo $UX 以将上游分支命名为 refs/heads/$ X",请使用第二种方法,但改为这样做:

$ 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 clonegit fetch 等复制,所以这对于“普通”git 用户来说更痛苦。)

让我们也克隆--bare repo,看看我们继续进行时会发生什么。 (作为参考,在$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

现在我在/tmp/t 中对$upstream_host 进行了更改,并提交了它。回到$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 的更改而不是 master,或者更一般地说,upstream/$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 是更正的更新,现在是 @987654354 @(后):

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

(名称只是--bare克隆中的upstream/master,所以上面的git rev-parse来自/tmp/xt/t而不是/tmp/tt/t.git。)

【讨论】:

    猜你喜欢
    • 2021-09-18
    • 2013-01-29
    • 2013-04-06
    • 2015-07-16
    • 2012-08-14
    • 2019-08-03
    • 2011-02-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多