更新git镜像而不修剪特定模式后的本地分支

时间:2018-02-09 15:27:09

标签: git git-fetch git-mirror

我必须经常在Github上更新git存储库的镜像。 与此同时,我在本地镜像上创建了一个特定模式(例如foo-[1-9]+[0-9]*)的分支。这些分支是在给定标记处创建的,包含内部补丁。

我想经常更新我的镜像,并获得Github的存储库+包含内部补丁的分支的精确副本。

在我创建镜像时,让我们假设Github的存储库状态如下:

      C---D branchA
     /
A---B---E---F master
        \
         G---H branchB

v0.1 --> F

我们使用标签 v0.1 的软件,我们创建了修补程序,原因是为了修复构建或软件。现在是本地存储库的状态:

      C---D branchA
     /
A---B---E---F master
        \   \
         \   I---J foo-1
          \
           G---H branchB

v0.1 --> F
foo-1 has been created and host patches for v0.1

与此同时,新的提交,分支出现在Github上,并且开发分支被合并然后被删除。 Github的存储库现在是:

                          J'---K branchC
                         /
A---B---E---F---C---D---I' master
            \
             G---H branchB

v0.1 --> F
v0.2 --> D
branchB has been rebased
branchC has been created
branchA has been merged into master and then deleted

起初我克隆了镜子。

git clone --mirror ${url_local_repo}

然后我将Github的存储库添加为远程。

git remote add --mirror=fetch github ${url_github_repo}

最后,我从github获取更改。

git fetch --tags --prune github
   From ${url_github_repo}                                                                                     
    x [deleted]         (none)     -> branchA                                                     
    x [deleted]         (none)     -> foo-1                                                                                                               
    * [new branch]      branchC    -> branchC
    E..F                branchB    -> branchB
    F..I'               master     -> master

foo-1已删除,但我想保留它。 我尝试使用glob来屏蔽获取,但它不起作用。

git fetch --dry-run --prune github '+refs/heads/*:refs/heads/[!f][!o][!o]*'
fatal: Invalid refspec '+refs/heads/*:refs/heads/[!f][!o][!o]*'

你会建议什么?

1 个答案:

答案 0 :(得分:0)

(目前至少)无法组合获取镜像(这实际上意味着获取refspec +refs/*:refs/*--prune并实现您想要的效果。

refspec字符串不是真正的globs:唯一允许的模式字符是*。在旧版本的Git中,*也必须包含斜杠包围的字符,尽管这个限制在Git 2.6.0中放宽了(通过commit 8d3981ccbed9fc211b4e67105015179d9d2a5692

--prune代码基本上可以通过检测某些引用名称空间是模式的目标,并且没有匹配的源引用来提供给模式。因此,只要源模式为refs/*refs/heads/*,Git就会删除任何没有来自其他存储库的源的名称。

您可以做的是避免 --prune(或其任何等价物),并以您喜欢的任何语言编写自己的代码,以扫描{{1}的结果加上git ls-remote的结果来决定删除哪些引用。使用git for-each-ref根据需要删除它们。