Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/git/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Git本地镜像和存储库_Git_Mirror - Fatal编程技术网

Git本地镜像和存储库

Git本地镜像和存储库,git,mirror,Git,Mirror,以下是我想做的: 拥有一个本地git存储库,该存储库镜像上游存储库 能够将“本地”分支/更改推送到该存储库,并将其保存在本地 使此存储库与上游存储库保持同步,包括: 找到新的分支 删除上游删除的分支的任何引用 我将cron作业设置为从上游获取所有更改,并修剪任何已删除的分支,如下所示: */5 * * * * cd /home/git/myrepo.git && git fetch origin && git remote prune origin >

以下是我想做的:

  • 拥有一个本地git存储库,该存储库镜像上游存储库
  • 能够将“本地”分支/更改推送到该存储库,并将其保存在本地
  • 使此存储库与上游存储库保持同步,包括:
    • 找到新的分支
    • 删除上游删除的分支的任何引用
我将cron作业设置为从上游获取所有更改,并修剪任何已删除的分支,如下所示:

*/5 * * * * cd /home/git/myrepo.git && git fetch origin && git remote prune origin > /dev/null
到目前为止,我尝试了什么(以及失败的原因):

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

问题是,当它执行
git远程修剪
时,它还删除了对“本地”更改的引用,这些更改被推送到那里(而不是上游服务器)

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

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

git clone --bare URL
但是,
git fetch origin
没有正确更新,它似乎正在下载对象,但没有创建引用,然后只打印

 * branch            HEAD       -> FETCH_HEAD
并且当前分支的“位置”没有使用上游服务器中的内容进行更新

我还尝试了如上所述的git remote update,得到了相同的结果

我可以:

但这只会让我回到(1)

中的问题,假设您可以放弃“镜像”要求,并让“本地(裸)回购$X也使用refs/heads/upstream/$branch复制上游回购$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
这假设您自己不会使用分支名称,如
上游/master
。(您也可以/代替执行以下操作:

git config remote.origin.fetch '+refs/*:refs/upstream/*'
但是
refs/upstream/*
引用不会被正常的
git clone
git fetch
等复制,因此这对“正常”git用户来说更痛苦。)

让我们也复制一下
--bare
回购协议,看看接下来会发生什么。(作为参考,在
$upstream\u host
上,我有一个
/tmp/t
,一个常规的git repo。在
$local\u host
,一个不完全镜像的机器上,我有一个
/tt/t.git
,一个
--bare
repo,它做这个上游跟踪的事情。我实际上对这两个主机都使用相同的主机,但原则适用……)

现在我在
/tmp/t
中对
$upstream\u host
进行了更改,并提交了它。回到
$local\u主机上

$ 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)
因此,上游所做的更改将作为对
上游/master
的更改,而不是
,或者更一般地,对于任何
$branch
而言,
上游/$branch
,出现在您的“某种镜像,但不完全是”裸git回购中。如果你想合并它们,你必须手动操作。我下面的例子有点混乱,因为我对
$upstream\u host
所做的更改是一次历史重写(因此所有
强制更新
的东西),最终通过克隆暴露在这里。如果你不想让它暴露出来,你必须注意哪些更新是历史重写,并(实际上)手动将它们复制到你自己的不完全镜像,然后复制到它的任何克隆。我会继续做一个真正的合并

因此,现在我们转到
$local\u 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\u host
/tmp/tt/t.git
),以将上游工作合并到我的本地非精确镜像中。
HEAD
版本是我的合并,
HEAD^1
是原始(断开的)更新,以前是
origin/upstream/master
(在所有“强制更新”之前),而
HEAD^2
是更正后的更新,现在是
origin/upstream/master
(之后):


(在
--bare
克隆中,名称只是
上游/master
,因此上面的
git rev parse
来自
/tmp/xt/t
而不是
/tmp/tt/t.git

在“拥有镜像”(repo X总是相同的,mod mirroring delay,与上游版本UX一样)和“保持本地更改”之间存在根本冲突(回购X肯定与上游UX不同)。最多选择一个,然后决定实施。
$ 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
$ 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)
$ 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
$ git rev-parse HEAD^2 origin/upstream/master
5e013711f5d6eb3f643ef562d49a131852aa4aa1
5e013711f5d6eb3f643ef562d49a131852aa4aa1