0

我必须经常更新 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]*'

你有什么建议?

4

1 回答 1

0

(目前至少)没有办法结合 fetch 镜像(这实际上意味着 fetch refspec+refs/*:refs/*--prune并实现你想要的。

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

--prune代码的工作原理是检测某些 ref 名称空间是模式的目标,并且没有匹配的源引用可以输入到模式中。因此,只要源模式是refs/*or refs/heads/*,Git 就会修剪任何没有来自其他存储库的源的名称。

您可以做的是避免 --prune(或其任何等效项),并以您喜欢的任何语言编写自己的代码,以扫描结果git ls-remote加上结果git for-each-ref以确定要删除哪些引用。使用git update-ref酌情删除它们。

于 2018-02-09T17:48:27.747 回答