【问题标题】:"fetch --all" in a git bare repository doesn't synchronize local branches to the remote onesgit 裸存储库中的“fetch --all”不会将本地分支同步到远程分支
【发布时间】:2011-07-30 09:09:05
【问题描述】:

我正在尝试定期同步一个 git 裸存储库,我的本地分支是使用“--track”选项创建的。这是我的配置(没有不必要的东西):

[core]
        bare = true
[remote "origin"]
        url = git@github.com:Ummon/D-LAN.git
        fetch = +refs/heads/*:refs/remotes/origin/*
[branch "master"]
        remote = origin
        merge = refs/heads/master
[branch "website"]
        remote = origin
        merge = refs/heads/website

我必须使用'cp'命令来更新本地分支:

 git fetch --all
 cp -r refs/remotes/origin/* refs/heads

有没有更优雅的解决方案?

【问题讨论】:

    标签: git git-fetch git-bare


    【解决方案1】:

    使用git update-ref而不是复制参考文件(坏坏!)

    请注意,在推送而不是拉取时,您可以很容易地将所需的内容放到裸存储库中。

    使用这个:

     git clone --mirror . /tmp/bareclone
    

    创建要保持完全同步的裸存储库 现在,要将所有分支同步到裸克隆镜像,请使用

     git push /tmp/bareclone --mirror
    

    请注意,这还将删除不在源代码库中但(仍然)在裸克隆中的任何头。另请注意,您可以使用 send-pack 而不是 push 那里,因为这个接口是相当低级的,实际上是由 send-pack 实现的

    HTH


    正如评论者所指出的,我略微回避了似乎不可能立即进行相反操作的主题。但是,您可以通过做一些稍微高级的事情来实现目标,例如:

    1。简单、安全且相当乏味。

    git fetch $url -- $(git ls-remote -h $url |
        while read sha ref; do echo "$ref:refs/remotes/fetched/${ref#refs/heads/}"; done)
    

    设置 `url=git://your.server/project.git' 例如

    我确保在适度安全的位置创建参考。效果和doing很相似。

    git remote add fetched $url --fetch
    

    所以没什么,但是它向您展示了如何使用管道命令来实现它,所以我们现在可以根据我们的需要调整它们:

    2。直接提取到本地分支(头部)

    现在如果您确定自己知道自己在做什么,您可以使用以下样式在本地复制分支:

    git init --bare .
    git fetch $url -- $(git ls-remote -h $url |
        while read sha ref; do echo "$ref:$ref"; done)
    

    注意:如果您想强制更新(例如,由于上游 rebase、reset、filter-branch、或修改的提交(一般来说——任何重写的历史)将echo "$ref:$ref"替换为echo "+$ref:$ref";(感谢Dov

    3。满月

    这也可以组合,所以你也可以有一个远程定义。 我建议这样做,因为这意味着本地分支实际上正在跟踪来自远程的分支,如果您不小心使用这些强大的功能破坏了这些分支上的一些本地提交,您将拥有更好的隔离/恢复选项获取命令

    git init --bare .
    git remote add fetched $url --fetch
    git for-each-ref --format='%(refname:short)' -- 'refs/remotes/fetched/' |
        while read ref; do git branch -t "$(basename "$ref")" "$ref"; done
    

    玩得开心,HTH

    【讨论】:

    • 谢谢,我为每个分支都这样做:git update-ref refs/heads/master refs/remotes/origin/master
    • 有没有办法与git push --mirror 做同样的事情,但从接收存储库启动。如果源代码库托管在 github 等其他地方,则不能使用 git push。
    • @Mark:我在原始答案中回避了这个问题。我已经用你可能喜欢的提示和技巧更新了答案:)
    • 谢谢。我最终只做git fetch 然后做git update-ref 从 refs/remotes/remotename/$ref 移动到 refs/heads/$ref。不完全是最安全的事情,但在我的情况下,它是一个只读镜像并且完成了这项工作。不过,您的解决方案看起来好多了,我最终可能会将其更改为您使用的第二种方法。
    • 我不会使用basename,而是进行参数扩展并使用git branch -t ${ref#fetched/} $ref,这样您仍然可以在fetch 和本地拥有分支名称foo/bar
    猜你喜欢
    • 2013-06-09
    • 1970-01-01
    • 2022-11-09
    • 2022-11-19
    • 2021-03-27
    • 1970-01-01
    • 1970-01-01
    • 2014-06-20
    • 1970-01-01
    相关资源
    最近更新 更多