【问题标题】:How to update my fork to have the same branches and tags as the original repository on github?如何更新我的 fork 以与 github 上的原始存储库具有相同的分支和标签?
【发布时间】:2013-03-24 16:04:42
【问题描述】:

当您在 github 上 fork 存储库时,您的 fork 存储库包含所有分支和标签。

随着时间的推移,这些分支和标签会过时。

如何使用 fork 轻松确保您的 fork 具有所有分支和标签而无需重新克隆?

即一个 git magicpull --rebase upstream/* myremote/*

它将获取上游的所有分支和标签,并确保 myremote 中存在相同的内容。

【问题讨论】:

    标签: git github


    【解决方案1】:

    这假设您的“上游”遥控器被命名为“origin”,并且您的用户名下有您的自定义分支(即“maxandersen”)

    当你让你的克隆运行以下单行(刷新Track all remote git branches as local branches:

    remote=origin ; for brname in `git branch -r | grep origin | grep -v master | grep -v HEAD | sed -e 's/.*\///g'`; do git branch --track $brname  $remote/$brname ; done
    

    这将为在名为“origin”的远程中找到的所有分支设置跟踪分支。 如果您已经使用此分支名称结帐,它不会更改任何内容,除非确保跟踪到位。

    (可选)现在确保您的所有分支都是最新的(如果您已经签出分支,则很有用):

    git pull --rebase --all
    

    现在所有分支都设置为跟踪和更新推送分支和标签到你的远程(用你的远程名称替换'maxandersen'):

    git push --all maxandersen
    git push --tags maxandersen
    

    在这之后你的分叉就同步了。

    以下脚本会执行所有这些操作,包括要求确认:

    ## Checkout all branches from remote as tracking branches. Based on    https://stackoverflow.com/questions/379081/track-all-remote-git-branches-as-local-branches/6300386#6300386
    
    UPSTREAM=$1
    MYREPO=$2
    
    usage() {
       echo "Usage:"
       echo "$0 <upstream-remote> <target-remote>"
       echo ""
       echo "Example which ensures remote named 'maxandersen' have all the same branches and tags as 'origin'"
       echo "$0 origin maxandersen"
       exit 1
    }
    
    if [ -z "$UPSTREAM" ]
    then
     echo Missing upstream remote name.
     usage
    fi
    
    if [ -z "$MYREPO" ]
    then
     echo Missing target remote name. 
     usage
    fi
    
    read -p "1. This will setup '$MYREPO' to track all branches in '$UPSTREAM' - Are you sure ?" -n 1 -r
    
    if [[ $REPLY =~ ^[Yy]$ ]]
    then
     for brname in `git branch -r | grep "$UPSTREAM" | grep -v master | grep -v HEAD | sed -e 's/.*\///g'`; do git branch --track $brname  $UPSTREAM/$brname ; done
    fi
    
    read -p "2. This will push all local branches and tags into '$MYREPO' - Are you sure ?" -n 1 -r
    
    if [[ $REPLY =~ ^[Yy]$ ]]
    then
     git push --all $MYREPO
     git push --tags $MYREPO
    fi
    

    将其保存为“updateallbranchestags.sh”并执行:

    sh updateallbranches.sh origin maxandersen
    

    来自“origin”的所有分支/标签都将在名为“maxandersen”的远程中可用

    【讨论】:

    • 听起来是我回答的具体实现。 +1
    • 是的,请注意,我也开始使用 --track 而不是 --set-upstream 来摆脱烦人的弃用警告 + 我使用 sed 而不是 awk 来使 oneliner 更短:) 因此谢谢你的提示!
    • 我不推荐 --track 原因在我的单行答案stackoverflow.com/a/6300386/6309(更新)中解释:您应该使用--set-upstream-to(或-u),如stackoverflow.com/a/10002469/6309 中所述
    • 谢谢 - 没有意识到细微的差别。答案已更新。
    • 非常好,我会调整 sed 表达式以避免删除带有斜杠的部分分支名称:'s/^[^\/]*\///'
    【解决方案2】:

    你仍然需要一个本地克隆,它会:

    • git push --all origin(起源是你的叉子):假设:
      • 所有本地分支都在跟踪所有上游分支(参见上一步)。
        否则,您将默认只推送一个本地分支,因为克隆只会创建一个本地分支(默认分支)
      • 您尚未在这些分支上推送您自己的提交。

    【讨论】:

      【解决方案3】:

      您可以直接推送远程参考。 显然这并没有考虑到分叉的变化,但它仍然回答了这个问题。如果更改受到限制,那么您可以使用本地分支轻松合并/重新设置它们。

      git push -f origin refs/remotes/upstream/*:refs/heads/*
      

      【讨论】:

        【解决方案4】:

        我已将Max 的出色答案中给出的 Bash 脚本翻译成批处理脚本,以防万一您在 Windows 上需要它。唯一的问题是,要在 Windows 上运行它,您需要在首选终端应用程序中提供 grep 和 sed 工具(我个人使用 Scoop 和 Windows 终端)。

        @echo off
        
        set UPSTREAM=%~1
        set MYREPO=%~2
        
        if "%UPSTREAM%" == "" (
            echo Missing upstream remote name.
            goto :usage
        )
        
        if "%MYREPO%" == "" (
            echo Missing target remote name.
            goto :usage
        )
        
        set /p REPLY="Setup '%MYREPO%' to track all branches in '%UPSTREAM%' [y/n]? "
        
        set "_YES=0"
        if "%REPLY%" == "y" set "_YES=1"
        if "%REPLY%" == "Y" set "_YES=1"
        if %_YES% equ 1 (
            for /f "tokens=1" %%G in ('git branch -r ^| grep %UPSTREAM% ^| grep -v master ^| grep -v HEAD ^| sed -e "s/.*\///g"') do (
                git branch --track %%G %UPSTREAM%/%%G
            )
        )
        
        set /p REPLY="Push all local branches in '%MYREPO%' [y/n]? "
        
        set "_YES=0"
        if "%REPLY%" == "y" set "_YES=1"
        if "%REPLY%" == "Y" set "_YES=1"
        if %_YES% equ 1 (
            git pull --rebase --all
            git push --all %MYREPO%
            git push --tags %MYREPO%
        )
        
        exit /B %ERRORLEVEL%
        
        :usage
        echo Usage:
        echo %~0 upstream-remote target-remote
        echo Example which ensures remote named 'origin' have all the same branches and tags as 'upstream'
        echo %~0 upstream origin
        exit 1
        

        【讨论】:

          【解决方案5】:

          这里的https://asciinema.org/a/lv9v5mh1GGQJsfKIzUSlzsg7i 是一个简单的实际演示,我如何从上游同步我的克隆仓库的master 和release-18.09 分支。

          【讨论】:

          • 必须观看几分钟才能看到您似乎正在执行上述操作的手动更长版本,这并不是很好。因此投反对票。
          猜你喜欢
          • 2011-04-23
          • 2019-08-05
          • 2012-12-15
          • 1970-01-01
          • 2021-09-29
          • 2013-03-16
          • 2015-12-26
          • 2015-05-21
          相关资源
          最近更新 更多