[{"data":1,"prerenderedAt":863},["ShallowReactive",2],{"gitee":3},[4],{"id":5,"title":6,"articleId":7,"articleThumb":8,"body":9,"categoryId":332,"categoryInfo":832,"createDate":836,"description":837,"excerpt":838,"extension":842,"isHidden":843,"isHot":844,"isRecommend":843,"isTop":843,"keywords":845,"meta":846,"navigation":844,"path":847,"rawbody":848,"readingTime":849,"seo":850,"sitemap":851,"stem":852,"tagIds":853,"tagInfo":854,"updateDate":860,"wordCount":861,"__hash__":862},"blog\u002Fblog\u002F2.github仓库代码和gitee仓库代码双向自动同步方案.md","github仓库代码和gitee仓库代码双向自动同步方案","20250909215534","https:\u002F\u002Fgcore.jsdelivr.net\u002Fgh\u002FAnyFork\u002FResource\u002Fimages\u002F20260327203348205.webp",{"type":10,"value":11,"toc":816},"minimark",[12,16,19,22,25,30,42,54,60,73,79,86,91,94,103,126,137,140,144,147,156,201,204,207,210,221,229,233,240,244,250,254,260,264,267,284,471,474,478,487,498,502,505,510,519,524,531,536,546,692,699,712,715,791,794,798,801,804,808,812],[13,14,15],"p",{},"到目前为止，想要实现在本地提交代码至Github仓库时，同时更新至Gitee仓库是可行的。相反，想要在本地提交代码至Gitee仓库时，同时更新至Github仓库也可以实现的。无论我们使用Github还是Gitee任意一个远程仓库，在代码提交时，头可以自动同步到另一个远程仓库，即所谓的双向自动同步(可推送至远端仓库，亦可从远端仓库同步更新)。当然，日常开发中，按照个人喜好，我们只需要选择一种即可。",[13,17,18],{},"Github同步代码至Gitee或者是从Gitee更新代码，都需要借助Github Actions功能。GitHub Actions‌ 是 GitHub 提供的持续集成与持续交付（CI\u002FCD）平台，主要用于自动化软件开发流程中的构建、测试和部署任务。通过yml格式文件配置workflow实现自动化操作，可以实现一次提交，多仓库代码同步。目前Github Actions在实现本地代码提交Github仓库时，同步代码到Gitee，可以自动触发workflow执行，实现自动同步功能。反过来，当Gitee代码库存在更新，Github从Gitee同步更新时，借助Github Actions无法实现自动，只能借助定时任务，定时从Gitee同步代码。",[13,20,21],{},"相对于Github同步方案而言，Gitee同步代码至Github或者从Github更新代码非常简单。借助Gitee提供的强大的仓库镜像功能，只需要在Gitee的源仓库上进行简单配置就可以实现。",[13,23,24],{},"下面介绍Github和Gitee双向同步的具体实现步骤。",[26,27,29],"h2",{"id":28},"_1-github自动同步gitee","1 Github自动同步Gitee",[13,31,32,33,41],{},"Github自动同步Gitee是指在本地提交代码至Github远程仓库时，同步将代码更新至Gitee仓库。目前通过Github Actions 实现Github仓库同步到gitee的Actions有很多，本文主要讲述如何使用【",[34,35,40],"a",{"href":36,"rel":37,"target":39},"https:\u002F\u002Fgithub.com\u002Fwearerequired\u002Fgit-mirror-action",[38],"nofollow","_blank","git-mirror-action","】镜像来实现同步操作。",[13,43,44,48,49,53],{},[45,46,40],"code",{"color":47},"primary"," 是一个用于自动同步 GitHub 和 Gitee（或其他 Git 平台）仓库的 GitHub Action，通过配置工作流（workflow）实现自动化部署。github仓库地址为：【",[34,50,52],{"href":36,"rel":51,"target":39},[38],"wearerequired\u002Fgit-mirror-action@master","】",[13,55,56],{},[57,58,59],"strong",{},"核心功能如下：",[61,62,63,67,70],"ul",{},[64,65,66],"li",{},"双向同步：支持将 GitHub 仓库同步到 Gitee 或其他平台，也可实现反向同步。",[64,68,69],{},"‌灵活配置‌：通过 .yml 文件定义同步规则，支持源仓库与目标仓库的地址映射。",[64,71,72],{},"自动化部署‌：结合 GitHub Actions 工作流，可在代码更新时自动触发同步操作。",[13,74,75,78],{},[57,76,77],{},"同步的原理","：利用 SSH 公私钥配对的方式拉取 Github 仓库的代码并推送到 Gitee 仓库中。",[13,80,81,82],{},"详细配置参考：",[34,83,85],{"href":36,"rel":84},[38],"github源码仓库文档",[87,88,90],"h3",{"id":89},"_11-创建gitee目标仓库","1.1 创建Gitee目标仓库",[13,92,93],{},"在实现github仓库同步到gitee仓库之前，首先需要在gitee初始化一个仓库，作为同步的目标仓库。可以直接创建一个空仓库，或者直接通过gitee自带的导入github仓库代码功能。具体导入github仓库步骤如下：",[13,95,96,97,102],{},"① 登陆[",[34,98,101],{"href":99,"rel":100,"target":39},"https:\u002F\u002Fgitee.com\u002Flogin",[38],"gitee","] -> 右上角加号 -> 从github\u002Fgitlab导入仓库。进入页面后，可直接通过url输入，也可以通过github授权后，批量选择导入的仓库。",[104,105,108],"callout",{"color":106,"icon":107},"warning","material-symbols:info-outline",[13,109,110,111,114,115,118,119,53,123,125],{},"温馨提示",[112,113],"br",{},"\n1 从url导入私有仓库时，需要填写仓库的账户和个人令牌。此处的令牌并非密码(github现在不建议直接账户密码认证)，而是GitHub 的「",[57,116,117],{},"Personal access token","」。点击前往设置【",[34,120,117],{"href":121,"rel":122,"target":39},"https:\u002F\u002Fgithub.com\u002Fsettings\u002Ftokens",[38],[112,124],{},"\n2 从github导入仓库，需要github授权才行，授权后可以选择需要导入的仓库。",[13,127,128,129,133,134,136],{},"② 仓库导入成功后，进入仓库，仓库名称后面会显示一个 ",[130,131],"icon",{"name":132},"material-symbols-light:refresh-rounded"," 符号，点击便可手动同步github仓库代码至gitee。私有仓库同步时，需要输入账号和个人令牌(github的",[57,135,117],{},")",[13,138,139],{},"至此，github仓库同步gitee仓库前期准备工作已准备完毕，下面开始介绍如何配置github自动同步代码至gitee。",[87,141,143],{"id":142},"_12-创建ssh公私钥","1.2 创建SSH公私钥",[13,145,146],{},"SSH密钥对由公钥和私钥组成，公钥用于加密数据，私钥用于解密数据，通过非对称加密确保通信安全。使用 SSH 协议可以连接远程服务器和服务并向它们验证。 利用 SSH 密钥可以连接到 GitHub，而无需在每次访问时都提供用户名和 personal access token。GitHub通过公钥加密信息，私钥用于解密，从而确认用户身份。",[13,148,149,150,152,153,155],{},"①在本地机器上打开终端应用程序",[112,151],{},"\n②生成SSH密钥对",[112,154],{},"\n使用ssh-keygen命令来生成密钥对。您可以通过以下命令开始：",[157,158,163],"pre",{"className":159,"code":160,"language":161,"meta":162,"style":162},"language-shell shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","ssh-keygen -t rsa  -b 4096 -C \"youremail@example.com\"\n","shell","",[45,164,165],{"__ignoreMap":162},[166,167,170,174,178,181,184,188,191,195,198],"span",{"class":168,"line":169},"line",1,[166,171,173],{"class":172},"sBMFI","ssh-keygen",[166,175,177],{"class":176},"sfazB"," -t",[166,179,180],{"class":176}," rsa",[166,182,183],{"class":176},"  -b",[166,185,187],{"class":186},"sbssI"," 4096",[166,189,190],{"class":176}," -C",[166,192,194],{"class":193},"sMK4o"," \"",[166,196,197],{"class":176},"youremail@example.com",[166,199,200],{"class":193},"\"\n",[13,202,203],{},"这里，-t rsa指定了密钥的类型为RSA，-b 4096指定了密钥的位长度为4096位。RSA密钥的长度可以是1024位、2048位或4096位，推荐使用2048位或更高的安全性。-C（Comment）是 ssh-keygen 命令的一个选项，用于为生成的 SSH 密钥对添加注释。注释内容可以是任意文本，但通常推荐使用邮箱地址或密钥用途描述。注释仅保存在公钥文件中，私钥文件不包含此信息。",[13,205,206],{},"执行上述命令后，系统会询问您希望将密钥存储在哪个文件中，默认是~\u002F.ssh\u002Fid_rsa（私钥）和~\u002F.ssh\u002Fid_rsa.pub（公钥）。您可以按回车接受默认设置，或者输入其他路径来存储密钥文件。",[13,208,209],{},"接下来，系统会询问您是否要为密钥设置密码（passphrase）。强烈建议设置密码，因为即使私钥文件被保护，知道密码仍然可以访问您的服务器。如果您不想设置密码，可以按回车跳过此步骤。",[13,211,212,213,216,217,220],{},"如果连续三次回车，生成的秘钥对存储默认位置。",[45,214,215],{"color":47},"id_rsa"," 为私钥，",[45,218,219],{"color":47},"id_rsa.pub","为公钥。如果提示：already exists（已经存在），则可以到电脑位置：C:\\Users\\电脑账号名\\ .ssh 直接使用。",[13,222,223,224,53],{},"具体图文参考：【",[34,225,228],{"href":226,"rel":227,"target":39},"https:\u002F\u002Fgitee.com\u002Fhelp\u002Farticles\u002F4181#article-header0",[38],"生成\u002F添加SSH公钥",[87,230,232],{"id":231},"_13-github配置ssh私钥","1.3 GitHub配置SSH私钥",[13,234,235,236],{},"打开Github需要同步的项目，点击Settings->Secrets->Actions，设置私钥名称为：GITEE_RSA_PRIVATE_KEY，值为：上面生成SSH的私钥，即id_rsa 文件的内容\n",[237,238],"img",{"alt":162,"src":239},"https:\u002F\u002Fgcore.jsdelivr.net\u002Fgh\u002FAnyFork\u002FResource\u002Fimages\u002F20250910125740784.webp",[87,241,243],{"id":242},"_14-github配置ssh公钥","1.4 GitHub配置SSH公钥",[13,245,246,247],{},"在Github点击右上角用户图像，点击Settings->SSH and GPG keys->New SSH key，名称为：GITEE_RSA_PUBLIC_KEY，值为：上面生成SSH的公钥，即id_rsa_pub文件内容\n",[237,248],{"alt":162,"src":249},"https:\u002F\u002Fgcore.jsdelivr.net\u002Fgh\u002FAnyFork\u002FResource\u002Fimages\u002F20250910130224827.webp",[87,251,253],{"id":252},"_15-gitee配置ssh公钥","1.5 Gitee配置SSH公钥",[13,255,256,257],{},"在Gitee 设置->安全设置->SSH公钥，标题为：GITEE_RSA_PUBLIC_KEY，值为：上面生成SSH的公钥，即id_rsa_pub文件内容\n",[237,258],{"alt":162,"src":259},"https:\u002F\u002Fgcore.jsdelivr.net\u002Fgh\u002FAnyFork\u002FResource\u002Fimages\u002F20250910130741176.webp",[87,261,263],{"id":262},"_16-创建github-workflow","1.6 创建Github workflow",[13,265,266],{},"github创建workflow有2种方式，第一种直接在github项目中，点击actions创建新的workflow，第二种就是将项目clone本地，进行配置。二者大同小异，都是配置相应的设置。",[13,268,269,270,273,276,279,280,283],{},"①第一种：点击actions创建新的workflow\n",[237,271],{"alt":162,"src":272},"https:\u002F\u002Fgcore.jsdelivr.net\u002Fgh\u002FAnyFork\u002FResource\u002Fimages\u002F20250910131433758.webp",[237,274],{"alt":162,"src":275},"https:\u002F\u002Fgcore.jsdelivr.net\u002Fgh\u002FAnyFork\u002FResource\u002Fimages\u002F20250910131520866.webp",[237,277],{"alt":162,"src":278},"https:\u002F\u002Fgcore.jsdelivr.net\u002Fgh\u002FAnyFork\u002FResource\u002Fimages\u002F20250910131747275.webp","\n②第二种：将项目clone到本地，用vscode打开，根目录下创建文件",[45,281,282],{"color":47},".github\\workflows\\sync-to-gitee.yml","，内容如下：",[157,285,290],{"className":286,"code":287,"filename":288,"language":289,"meta":162,"style":162},"language-yml shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","name: Sync to Gitee\non:\n    push:\n        branches:\n            # 或者你想要同步的分支\n            - main\njobs:\n    sync:\n        runs-on: ubuntu-latest\n        steps:\n            - name: Sync to Gitee\n              uses: wearerequired\u002Fgit-mirror-action@master\n              env:\n                  # 注意在 Settings->Secrets 配置 GITEE_RSA_PRIVATE_KEY\n                  SSH_PRIVATE_KEY: ${{ secrets.GITEE_RSA_PRIVATE_KEY }}\n              with:\n                  # 注意替换为你的 GitHub 源仓库地址\n                  source-repo: git@github.com:AnyFork\u002Fanyfork-docs-client.git\n                  # 注意替换为你的 Gitee 目标仓库地址\n                  destination-repo: git@gitee.com:AnyFork\u002Fanyfork-docs-client.git\n","sync-to-gitee.yml","yml",[45,291,292,304,314,322,330,337,346,354,362,373,381,393,404,412,418,429,437,443,454,460],{"__ignoreMap":162},[166,293,294,298,301],{"class":168,"line":169},[166,295,297],{"class":296},"swJcz","name",[166,299,300],{"class":193},":",[166,302,303],{"class":176}," Sync to Gitee\n",[166,305,307,311],{"class":168,"line":306},2,[166,308,310],{"class":309},"sfNiH","on",[166,312,313],{"class":193},":\n",[166,315,317,320],{"class":168,"line":316},3,[166,318,319],{"class":296},"    push",[166,321,313],{"class":193},[166,323,325,328],{"class":168,"line":324},4,[166,326,327],{"class":296},"        branches",[166,329,313],{"class":193},[166,331,333],{"class":168,"line":332},5,[166,334,336],{"class":335},"sHwdD","            # 或者你想要同步的分支\n",[166,338,340,343],{"class":168,"line":339},6,[166,341,342],{"class":193},"            -",[166,344,345],{"class":176}," main\n",[166,347,349,352],{"class":168,"line":348},7,[166,350,351],{"class":296},"jobs",[166,353,313],{"class":193},[166,355,357,360],{"class":168,"line":356},8,[166,358,359],{"class":296},"    sync",[166,361,313],{"class":193},[166,363,365,368,370],{"class":168,"line":364},9,[166,366,367],{"class":296},"        runs-on",[166,369,300],{"class":193},[166,371,372],{"class":176}," ubuntu-latest\n",[166,374,376,379],{"class":168,"line":375},10,[166,377,378],{"class":296},"        steps",[166,380,313],{"class":193},[166,382,384,386,389,391],{"class":168,"line":383},11,[166,385,342],{"class":193},[166,387,388],{"class":296}," name",[166,390,300],{"class":193},[166,392,303],{"class":176},[166,394,396,399,401],{"class":168,"line":395},12,[166,397,398],{"class":296},"              uses",[166,400,300],{"class":193},[166,402,403],{"class":176}," wearerequired\u002Fgit-mirror-action@master\n",[166,405,407,410],{"class":168,"line":406},13,[166,408,409],{"class":296},"              env",[166,411,313],{"class":193},[166,413,415],{"class":168,"line":414},14,[166,416,417],{"class":335},"                  # 注意在 Settings->Secrets 配置 GITEE_RSA_PRIVATE_KEY\n",[166,419,421,424,426],{"class":168,"line":420},15,[166,422,423],{"class":296},"                  SSH_PRIVATE_KEY",[166,425,300],{"class":193},[166,427,428],{"class":176}," ${{ secrets.GITEE_RSA_PRIVATE_KEY }}\n",[166,430,432,435],{"class":168,"line":431},16,[166,433,434],{"class":296},"              with",[166,436,313],{"class":193},[166,438,440],{"class":168,"line":439},17,[166,441,442],{"class":335},"                  # 注意替换为你的 GitHub 源仓库地址\n",[166,444,446,449,451],{"class":168,"line":445},18,[166,447,448],{"class":296},"                  source-repo",[166,450,300],{"class":193},[166,452,453],{"class":176}," git@github.com:AnyFork\u002Fanyfork-docs-client.git\n",[166,455,457],{"class":168,"line":456},19,[166,458,459],{"class":335},"                  # 注意替换为你的 Gitee 目标仓库地址\n",[166,461,463,466,468],{"class":168,"line":462},20,[166,464,465],{"class":296},"                  destination-repo",[166,467,300],{"class":193},[166,469,470],{"class":176}," git@gitee.com:AnyFork\u002Fanyfork-docs-client.git\n",[13,472,473],{},"至此，github workflow配置完毕。以后提交代码至github仓库时，便会触发workflow自动执行，自动将github仓库代码同步至gitee仓库中。",[26,475,477],{"id":476},"_2-github从gitee同步更新","2 Github从Gitee同步更新",[13,479,480,481,486],{},"Github仓库从Gitee仓库同步代码，也是借助Github Actions功能进行实现，能够实现此功能的Actions较多，本文还是采用\n【",[34,482,485],{"href":483,"rel":484,"target":39},"https:\u002F\u002Fgithub.com\u002FYikun\u002Fhub-mirror-action",[38],"Yikun\u002Fgitee-mirror-action","】进行实现。",[13,488,489,490,493,494,497],{},"由于Github Actions在Gitee代码仓库更新时，无法自动感知gitee仓库发生更新，从而不能自动触发workflow的执行，因此形成了2种不同的同步方式：",[57,491,492],{},"webhooks实时同步方式","和",[57,495,496],{},"定时延迟同步方式","。下面分别介绍这2种同步方式的具体实现步骤。",[87,499,501],{"id":500},"_21-定时延迟同步方式","2.1 定时延迟同步方式",[13,503,504],{},"定时延迟同步方式是最简单的一种方式，虽然存在延迟，但大部分情况下对代码同步的实时性要求并不高。可以根据实际需求，调整定时任务频率，增加同步次数。",[13,506,507],{},[57,508,509],{},"1 创建Github目标仓库",[13,511,512,513,518],{},"在实现从Gitee同步代码至目标仓库Github之前，需要在Github上创建一个空的仓库作为同步的目标仓库。登陆【",[34,514,517],{"href":515,"rel":516,"target":39},"https:\u002F\u002Fgithub.com\u002F",[38],"gihub","】->右上角加号->创建仓库，私有或者公有仓库均可。",[13,520,521],{},[57,522,523],{},"2 目标仓库配置SSH私钥",[13,525,526,527,53],{},"github目标仓库创建好后，需要配置仓库SSH私钥，具体步骤参考：【",[34,528,530],{"href":529},"#_13-github%E9%85%8D%E7%BD%AEssh%E7%A7%81%E9%92%A5","1.3 github配置ssh私钥",[13,532,533],{},[57,534,535],{},"3 目标仓库创建Github workflow",[13,537,538,539,542,543,283],{},"在【",[34,540,263],{"href":541},"#_16-%E5%88%9B%E5%BB%BAgithub-workflow","】已经讲述了如何创建Github workflow，此处不在赘述。下面采用第二种方式进行配置。将项目clone到本地，用vscode打开，根目录下创建文件",[45,544,545],{"color":47},".github\\workflows\\sync-to-github.yml",[157,547,550],{"className":286,"code":548,"filename":549,"language":289,"meta":162,"style":162},"name: Sync to Github\non:\n   schedule:\n    # 每个小时10-59分钟之间，从10分钟开始，每5分钟执行一次\n    - cron:  '10\u002F5 * * * *'\njobs:\n    sync:\n        runs-on: ubuntu-latest\n        steps:\n            - name: Sync to Github\n              uses: wearerequired\u002Fgit-mirror-action@master\n              env:\n                  # 注意在 Settings->Secrets 配置 GITEE_RSA_PRIVATE_KEY\n                  SSH_PRIVATE_KEY: ${{ secrets.GITEE_RSA_PRIVATE_KEY }}\n              with:\n                  # 注意替换为你的 Gitee源仓库地址\n                  source-repo: git@gitee.com:AnyFork\u002Fanyfork-docs-client.git\n                  # 注意替换为你的 Github 目标仓库地址\n                  destination-repo: git@github.com:AnyFork\u002Fanyfork-docs-client.git\n","sync-to-github.yml",[45,551,552,561,567,574,579,598,604,610,618,624,634,642,648,652,660,666,671,679,684],{"__ignoreMap":162},[166,553,554,556,558],{"class":168,"line":169},[166,555,297],{"class":296},[166,557,300],{"class":193},[166,559,560],{"class":176}," Sync to Github\n",[166,562,563,565],{"class":168,"line":306},[166,564,310],{"class":309},[166,566,313],{"class":193},[166,568,569,572],{"class":168,"line":316},[166,570,571],{"class":296},"   schedule",[166,573,313],{"class":193},[166,575,576],{"class":168,"line":324},[166,577,578],{"class":335},"    # 每个小时10-59分钟之间，从10分钟开始，每5分钟执行一次\n",[166,580,581,584,587,589,592,595],{"class":168,"line":332},[166,582,583],{"class":193},"    -",[166,585,586],{"class":296}," cron",[166,588,300],{"class":193},[166,590,591],{"class":193},"  '",[166,593,594],{"class":176},"10\u002F5 * * * *",[166,596,597],{"class":193},"'\n",[166,599,600,602],{"class":168,"line":339},[166,601,351],{"class":296},[166,603,313],{"class":193},[166,605,606,608],{"class":168,"line":348},[166,607,359],{"class":296},[166,609,313],{"class":193},[166,611,612,614,616],{"class":168,"line":356},[166,613,367],{"class":296},[166,615,300],{"class":193},[166,617,372],{"class":176},[166,619,620,622],{"class":168,"line":364},[166,621,378],{"class":296},[166,623,313],{"class":193},[166,625,626,628,630,632],{"class":168,"line":375},[166,627,342],{"class":193},[166,629,388],{"class":296},[166,631,300],{"class":193},[166,633,560],{"class":176},[166,635,636,638,640],{"class":168,"line":383},[166,637,398],{"class":296},[166,639,300],{"class":193},[166,641,403],{"class":176},[166,643,644,646],{"class":168,"line":395},[166,645,409],{"class":296},[166,647,313],{"class":193},[166,649,650],{"class":168,"line":406},[166,651,417],{"class":335},[166,653,654,656,658],{"class":168,"line":414},[166,655,423],{"class":296},[166,657,300],{"class":193},[166,659,428],{"class":176},[166,661,662,664],{"class":168,"line":420},[166,663,434],{"class":296},[166,665,313],{"class":193},[166,667,668],{"class":168,"line":431},[166,669,670],{"class":335},"                  # 注意替换为你的 Gitee源仓库地址\n",[166,672,673,675,677],{"class":168,"line":439},[166,674,448],{"class":296},[166,676,300],{"class":193},[166,678,470],{"class":176},[166,680,681],{"class":168,"line":445},[166,682,683],{"class":335},"                  # 注意替换为你的 Github 目标仓库地址\n",[166,685,686,688,690],{"class":168,"line":456},[166,687,465],{"class":296},[166,689,300],{"class":193},[166,691,453],{"class":176},[13,693,694,695,698],{},"上面配置了",[45,696,697],{"color":47},"on:schedule:cron","定时任务，时间到了定时任务设置的时间，便会触发workflow执行。",[104,700,701],{"color":106,"icon":107},[13,702,110,703,705,706,708,709,711],{},[112,704],{},"\n1 设定的 schedule 是UCT时间，比如设置的08:00（也就是北京时间的16:00），但实际运行的时间为北京时间17:00 至 17：20 不等。",[112,707],{},"\n2 Schedule在 GitHub 操作工作流运行的高负载期间，事件可能会延迟。高负载时间包括每小时开始。为了减少延迟的可能性，请安排您的工作流在不同的时间运行。实测延迟的时间为几十分钟，或者超过一个小时，甚至在某种极端情况下，将不会执行。",[112,710],{},"\n3 Schedule 设置的 cron 时刻，仅仅是工作流进行计划排队的时刻，而不是准确的运行时刻。",[13,713,714],{},"GitHub Actions 默认使用 UTC 时间。如果你的工作流程应该在特定本地时间执行，你可以在 YAML 文件中指定时区：",[157,716,718],{"className":286,"code":717,"language":289,"meta":162,"style":162},"jobs:\n  job1:\n    runs-on: ubuntu-latest\n    steps:\n    - name: Set Timezone\n      uses: szenius\u002Fset-timezone@v1.0\n      with:\n        timezoneLinux: \"Asia\u002FShanghai\"\n\n",[45,719,720,726,733,742,749,760,770,777],{"__ignoreMap":162},[166,721,722,724],{"class":168,"line":169},[166,723,351],{"class":296},[166,725,313],{"class":193},[166,727,728,731],{"class":168,"line":306},[166,729,730],{"class":296},"  job1",[166,732,313],{"class":193},[166,734,735,738,740],{"class":168,"line":316},[166,736,737],{"class":296},"    runs-on",[166,739,300],{"class":193},[166,741,372],{"class":176},[166,743,744,747],{"class":168,"line":324},[166,745,746],{"class":296},"    steps",[166,748,313],{"class":193},[166,750,751,753,755,757],{"class":168,"line":332},[166,752,583],{"class":193},[166,754,388],{"class":296},[166,756,300],{"class":193},[166,758,759],{"class":176}," Set Timezone\n",[166,761,762,765,767],{"class":168,"line":339},[166,763,764],{"class":296},"      uses",[166,766,300],{"class":193},[166,768,769],{"class":176}," szenius\u002Fset-timezone@v1.0\n",[166,771,772,775],{"class":168,"line":348},[166,773,774],{"class":296},"      with",[166,776,313],{"class":193},[166,778,779,782,784,786,789],{"class":168,"line":356},[166,780,781],{"class":296},"        timezoneLinux",[166,783,300],{"class":193},[166,785,194],{"class":193},[166,787,788],{"class":176},"Asia\u002FShanghai",[166,790,200],{"class":193},[13,792,793],{},"对于一些不需要实时进行同步的需求，可以采用定时延迟同步方案，方便配置也简单。",[87,795,797],{"id":796},"_22-实时同步方式","2.2 实时同步方式",[13,799,800],{},"Webhook是一种事件驱动的通知机制，当发生特定事件（如代码推送、拉取请求创建等）时，会自动向指定的外部服务器发送HTTP POST请求（通常包含事件数据）。这种机制替代了轮询API的实时通知方式，允许开发者在事件发生时立即触发外部操作（如部署、测试或发送通知）。",[13,802,803],{},"Github和Gitee都支持Webhook功能，因此我们可以借助这一功能，在gitee代码发生提交时，触发gitee配置的自定义webhook，webhook通过调用github Api触发github actions自动执行，从而实现实时同步方式。",[26,805,807],{"id":806},"_3-gitee自动同步github","3 Gitee自动同步Github",[26,809,811],{"id":810},"_4-gitee从github同步更新","4 Gitee从Github同步更新",[813,814,815],"style",{},"html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}html pre.shiki code .sfNiH, html code.shiki .sfNiH{--shiki-light:#FF5370;--shiki-default:#FF9CAC;--shiki-dark:#FF9CAC}html pre.shiki code .sHwdD, html code.shiki .sHwdD{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}",{"title":162,"searchDepth":316,"depth":316,"links":817},[818,826,830,831],{"id":28,"depth":306,"text":29,"children":819},[820,821,822,823,824,825],{"id":89,"depth":316,"text":90},{"id":142,"depth":316,"text":143},{"id":231,"depth":316,"text":232},{"id":242,"depth":316,"text":243},{"id":252,"depth":316,"text":253},{"id":262,"depth":316,"text":263},{"id":476,"depth":306,"text":477,"children":827},[828,829],{"id":500,"depth":316,"text":501},{"id":796,"depth":316,"text":797},{"id":806,"depth":306,"text":807},{"id":810,"depth":306,"text":811},{"name":833,"symbol":834,"icon":835,"id":332},"仓库同步","repository","material-symbols-light:sync-desktop-outline","2025-09-09 21:55:35","‌日常工作中，可能会遇到github代码仓库需要自动同步代码至gitee仓库，或者gitee仓库代码同步至github仓库的应用场景，针对这个应用场景，下面便归纳一下github和gitee仓库实现双向自动同步方案和步骤。",{"type":10,"value":839},[840],[13,841,15],{},"md",false,true,"GitHub Actions‌，github，CI\u002FCD，gitee，自动代码同步，双向代码同步，镜像仓库。",{},"\u002Fblog\u002Fgithubgitee","---\ntitle: github仓库代码和gitee仓库代码双向自动同步方案\ndescription: ‌日常工作中，可能会遇到github代码仓库需要自动同步代码至gitee仓库，或者gitee仓库代码同步至github仓库的应用场景，针对这个应用场景，下面便归纳一下github和gitee仓库实现双向自动同步方案和步骤。\nkeywords: GitHub Actions‌，github，CI\u002FCD，gitee，自动代码同步，双向代码同步，镜像仓库。\narticleId: 20250909215534\ncreateDate: \"2025-09-09 21:55:35\"\nupdateDate: \"2026-03-12 10:02:23\"\narticleThumb: https:\u002F\u002Fgcore.jsdelivr.net\u002Fgh\u002FAnyFork\u002FResource\u002Fimages\u002F20260327203348205.webp\ntagIds: \n    - 2\n    - 3\ncategoryId: 5\nisTop: false\nisRecommend: false\nisHot: true\nisHidden: false\nnavigation: true\n---\n\n\n到目前为止，想要实现在本地提交代码至Github仓库时，同时更新至Gitee仓库是可行的。相反，想要在本地提交代码至Gitee仓库时，同时更新至Github仓库也可以实现的。无论我们使用Github还是Gitee任意一个远程仓库，在代码提交时，头可以自动同步到另一个远程仓库，即所谓的双向自动同步(可推送至远端仓库，亦可从远端仓库同步更新)。当然，日常开发中，按照个人喜好，我们只需要选择一种即可。\n\u003C!--more-->\n\n\nGithub同步代码至Gitee或者是从Gitee更新代码，都需要借助Github Actions功能。GitHub Actions‌ 是 GitHub 提供的持续集成与持续交付（CI\u002FCD）平台，主要用于自动化软件开发流程中的构建、测试和部署任务。通过yml格式文件配置workflow实现自动化操作，可以实现一次提交，多仓库代码同步。目前Github Actions在实现本地代码提交Github仓库时，同步代码到Gitee，可以自动触发workflow执行，实现自动同步功能。反过来，当Gitee代码库存在更新，Github从Gitee同步更新时，借助Github Actions无法实现自动，只能借助定时任务，定时从Gitee同步代码。\n\n\n相对于Github同步方案而言，Gitee同步代码至Github或者从Github更新代码非常简单。借助Gitee提供的强大的仓库镜像功能，只需要在Gitee的源仓库上进行简单配置就可以实现。\n\n\n下面介绍Github和Gitee双向同步的具体实现步骤。\n\n\n## 1 Github自动同步Gitee\nGithub自动同步Gitee是指在本地提交代码至Github远程仓库时，同步将代码更新至Gitee仓库。目前通过Github Actions 实现Github仓库同步到gitee的Actions有很多，本文主要讲述如何使用【[git-mirror-action](https:\u002F\u002Fgithub.com\u002Fwearerequired\u002Fgit-mirror-action){target=_blank}】镜像来实现同步操作。\n\n`git-mirror-action`{color=primary} 是一个用于自动同步 GitHub 和 Gitee（或其他 Git 平台）仓库的 GitHub Action，通过配置工作流（workflow）实现自动化部署。github仓库地址为：【[wearerequired\u002Fgit-mirror-action@master](https:\u002F\u002Fgithub.com\u002Fwearerequired\u002Fgit-mirror-action){target=_blank}】\n \n**核心功能如下：**\n- 双向同步：支持将 GitHub 仓库同步到 Gitee 或其他平台，也可实现反向同步。\n- ‌灵活配置‌：通过 .yml 文件定义同步规则，支持源仓库与目标仓库的地址映射。\n- 自动化部署‌：结合 GitHub Actions 工作流，可在代码更新时自动触发同步操作。\n\n**同步的原理**：利用 SSH 公私钥配对的方式拉取 Github 仓库的代码并推送到 Gitee 仓库中。\n\n\n详细配置参考：[github源码仓库文档](https:\u002F\u002Fgithub.com\u002Fwearerequired\u002Fgit-mirror-action)\n\n\n### 1.1 创建Gitee目标仓库\n在实现github仓库同步到gitee仓库之前，首先需要在gitee初始化一个仓库，作为同步的目标仓库。可以直接创建一个空仓库，或者直接通过gitee自带的导入github仓库代码功能。具体导入github仓库步骤如下：\n\n\n① 登陆[[gitee](https:\u002F\u002Fgitee.com\u002Flogin){target=_blank}] -> 右上角加号 -> 从github\u002Fgitlab导入仓库。进入页面后，可直接通过url输入，也可以通过github授权后，批量选择导入的仓库。\n::callout{icon=\"material-symbols:info-outline\" color=\"warning\"}\n温馨提示\u003C\u002Fbr>\n1 从url导入私有仓库时，需要填写仓库的账户和个人令牌。此处的令牌并非密码(github现在不建议直接账户密码认证)，而是GitHub 的「**Personal access token**」。点击前往设置【[Personal access token](https:\u002F\u002Fgithub.com\u002Fsettings\u002Ftokens){target=_blank}】\u003C\u002Fbr>\n2 从github导入仓库，需要github授权才行，授权后可以选择需要导入的仓库。\n::\n② 仓库导入成功后，进入仓库，仓库名称后面会显示一个 :icon{name=\"material-symbols-light:refresh-rounded\"} 符号，点击便可手动同步github仓库代码至gitee。私有仓库同步时，需要输入账号和个人令牌(github的**Personal access token**)\n\n\n至此，github仓库同步gitee仓库前期准备工作已准备完毕，下面开始介绍如何配置github自动同步代码至gitee。\n\n\n### 1.2 创建SSH公私钥\nSSH密钥对由公钥和私钥组成，公钥用于加密数据，私钥用于解密数据，通过非对称加密确保通信安全。使用 SSH 协议可以连接远程服务器和服务并向它们验证。 利用 SSH 密钥可以连接到 GitHub，而无需在每次访问时都提供用户名和 personal access token。GitHub通过公钥加密信息，私钥用于解密，从而确认用户身份。\n\n\n①在本地机器上打开终端应用程序  \n②生成SSH密钥对  \n使用ssh-keygen命令来生成密钥对。您可以通过以下命令开始：\n```shell\nssh-keygen -t rsa  -b 4096 -C \"youremail@example.com\"\n```\n这里，-t rsa指定了密钥的类型为RSA，-b 4096指定了密钥的位长度为4096位。RSA密钥的长度可以是1024位、2048位或4096位，推荐使用2048位或更高的安全性。-C（Comment）是 ssh-keygen 命令的一个选项，用于为生成的 SSH 密钥对添加注释。注释内容可以是任意文本，但通常推荐使用邮箱地址或密钥用途描述。注释仅保存在公钥文件中，私钥文件不包含此信息。\n\n\n执行上述命令后，系统会询问您希望将密钥存储在哪个文件中，默认是~\u002F.ssh\u002Fid_rsa（私钥）和~\u002F.ssh\u002Fid_rsa.pub（公钥）。您可以按回车接受默认设置，或者输入其他路径来存储密钥文件。\n\n接下来，系统会询问您是否要为密钥设置密码（passphrase）。强烈建议设置密码，因为即使私钥文件被保护，知道密码仍然可以访问您的服务器。如果您不想设置密码，可以按回车跳过此步骤。\n\n\n如果连续三次回车，生成的秘钥对存储默认位置。`id_rsa`{color=primary} 为私钥，`id_rsa.pub`{color=primary}为公钥。如果提示：already exists（已经存在），则可以到电脑位置：C:\\Users\\电脑账号名\\ .ssh 直接使用。\n\n\n具体图文参考：【[生成\u002F添加SSH公钥](https:\u002F\u002Fgitee.com\u002Fhelp\u002Farticles\u002F4181#article-header0){target=_blank}】\n\n\n### 1.3 GitHub配置SSH私钥\n打开Github需要同步的项目，点击Settings->Secrets->Actions，设置私钥名称为：GITEE_RSA_PRIVATE_KEY，值为：上面生成SSH的私钥，即id_rsa 文件的内容\n![](https:\u002F\u002Fgcore.jsdelivr.net\u002Fgh\u002FAnyFork\u002FResource\u002Fimages\u002F20250910125740784.webp)\n\n\n### 1.4 GitHub配置SSH公钥\n在Github点击右上角用户图像，点击Settings->SSH and GPG keys->New SSH key，名称为：GITEE_RSA_PUBLIC_KEY，值为：上面生成SSH的公钥，即id_rsa_pub文件内容\n![](https:\u002F\u002Fgcore.jsdelivr.net\u002Fgh\u002FAnyFork\u002FResource\u002Fimages\u002F20250910130224827.webp)\n\n\n### 1.5 Gitee配置SSH公钥\n在Gitee 设置->安全设置->SSH公钥，标题为：GITEE_RSA_PUBLIC_KEY，值为：上面生成SSH的公钥，即id_rsa_pub文件内容\n![](https:\u002F\u002Fgcore.jsdelivr.net\u002Fgh\u002FAnyFork\u002FResource\u002Fimages\u002F20250910130741176.webp)\n\n\n### 1.6 创建Github workflow\ngithub创建workflow有2种方式，第一种直接在github项目中，点击actions创建新的workflow，第二种就是将项目clone本地，进行配置。二者大同小异，都是配置相应的设置。\n\n\n①第一种：点击actions创建新的workflow\n![](https:\u002F\u002Fgcore.jsdelivr.net\u002Fgh\u002FAnyFork\u002FResource\u002Fimages\u002F20250910131433758.webp)\n![](https:\u002F\u002Fgcore.jsdelivr.net\u002Fgh\u002FAnyFork\u002FResource\u002Fimages\u002F20250910131520866.webp)\n![](https:\u002F\u002Fgcore.jsdelivr.net\u002Fgh\u002FAnyFork\u002FResource\u002Fimages\u002F20250910131747275.webp)\n②第二种：将项目clone到本地，用vscode打开，根目录下创建文件`.github\\workflows\\sync-to-gitee.yml`{color=primary}，内容如下：\n```yml[sync-to-gitee.yml]\nname: Sync to Gitee\non:\n    push:\n        branches:\n            # 或者你想要同步的分支\n            - main\njobs:\n    sync:\n        runs-on: ubuntu-latest\n        steps:\n            - name: Sync to Gitee\n              uses: wearerequired\u002Fgit-mirror-action@master\n              env:\n                  # 注意在 Settings->Secrets 配置 GITEE_RSA_PRIVATE_KEY\n                  SSH_PRIVATE_KEY: ${{ secrets.GITEE_RSA_PRIVATE_KEY }}\n              with:\n                  # 注意替换为你的 GitHub 源仓库地址\n                  source-repo: git@github.com:AnyFork\u002Fanyfork-docs-client.git\n                  # 注意替换为你的 Gitee 目标仓库地址\n                  destination-repo: git@gitee.com:AnyFork\u002Fanyfork-docs-client.git\n```\n至此，github workflow配置完毕。以后提交代码至github仓库时，便会触发workflow自动执行，自动将github仓库代码同步至gitee仓库中。\n\n\n## 2 Github从Gitee同步更新\nGithub仓库从Gitee仓库同步代码，也是借助Github Actions功能进行实现，能够实现此功能的Actions较多，本文还是采用\n【[Yikun\u002Fgitee-mirror-action](https:\u002F\u002Fgithub.com\u002FYikun\u002Fhub-mirror-action){target=_blank}】进行实现。\n\n由于Github Actions在Gitee代码仓库更新时，无法自动感知gitee仓库发生更新，从而不能自动触发workflow的执行，因此形成了2种不同的同步方式：**webhooks实时同步方式**和**定时延迟同步方式**。下面分别介绍这2种同步方式的具体实现步骤。\n\n### 2.1 定时延迟同步方式\n定时延迟同步方式是最简单的一种方式，虽然存在延迟，但大部分情况下对代码同步的实时性要求并不高。可以根据实际需求，调整定时任务频率，增加同步次数。\n\n**1 创建Github目标仓库**\n\n 在实现从Gitee同步代码至目标仓库Github之前，需要在Github上创建一个空的仓库作为同步的目标仓库。登陆【[gihub](https:\u002F\u002Fgithub.com\u002F){target=_blank}】->右上角加号->创建仓库，私有或者公有仓库均可。\n\n\n**2 目标仓库配置SSH私钥**\n\n\ngithub目标仓库创建好后，需要配置仓库SSH私钥，具体步骤参考：【[1.3 github配置ssh私钥](#_13-github配置ssh私钥)】\n\n**3 目标仓库创建Github workflow**\n\n在【[1.6 创建Github workflow](#_16-创建github-workflow)】已经讲述了如何创建Github workflow，此处不在赘述。下面采用第二种方式进行配置。将项目clone到本地，用vscode打开，根目录下创建文件`.github\\workflows\\sync-to-github.yml`{color=primary}，内容如下：\n```yml[sync-to-github.yml]\nname: Sync to Github\non:\n   schedule:\n    # 每个小时10-59分钟之间，从10分钟开始，每5分钟执行一次\n    - cron:  '10\u002F5 * * * *'\njobs:\n    sync:\n        runs-on: ubuntu-latest\n        steps:\n            - name: Sync to Github\n              uses: wearerequired\u002Fgit-mirror-action@master\n              env:\n                  # 注意在 Settings->Secrets 配置 GITEE_RSA_PRIVATE_KEY\n                  SSH_PRIVATE_KEY: ${{ secrets.GITEE_RSA_PRIVATE_KEY }}\n              with:\n                  # 注意替换为你的 Gitee源仓库地址\n                  source-repo: git@gitee.com:AnyFork\u002Fanyfork-docs-client.git\n                  # 注意替换为你的 Github 目标仓库地址\n                  destination-repo: git@github.com:AnyFork\u002Fanyfork-docs-client.git\n```\n上面配置了`on:schedule:cron`{color=primary}定时任务，时间到了定时任务设置的时间，便会触发workflow执行。\n::callout{icon=\"material-symbols:info-outline\" color=\"warning\"}\n温馨提示\u003C\u002Fbr>\n1 设定的 schedule 是UCT时间，比如设置的08:00（也就是北京时间的16:00），但实际运行的时间为北京时间17:00 至 17：20 不等。\u003C\u002Fbr>\n2 Schedule在 GitHub 操作工作流运行的高负载期间，事件可能会延迟。高负载时间包括每小时开始。为了减少延迟的可能性，请安排您的工作流在不同的时间运行。实测延迟的时间为几十分钟，或者超过一个小时，甚至在某种极端情况下，将不会执行。\u003C\u002Fbr>\n3 Schedule 设置的 cron 时刻，仅仅是工作流进行计划排队的时刻，而不是准确的运行时刻。\n::\nGitHub Actions 默认使用 UTC 时间。如果你的工作流程应该在特定本地时间执行，你可以在 YAML 文件中指定时区：\n```yml\njobs:\n  job1:\n    runs-on: ubuntu-latest\n    steps:\n    - name: Set Timezone\n      uses: szenius\u002Fset-timezone@v1.0\n      with:\n        timezoneLinux: \"Asia\u002FShanghai\"\n\n```\n对于一些不需要实时进行同步的需求，可以采用定时延迟同步方案，方便配置也简单。\n\n\n### 2.2 实时同步方式\nWebhook是一种事件驱动的通知机制，当发生特定事件（如代码推送、拉取请求创建等）时，会自动向指定的外部服务器发送HTTP POST请求（通常包含事件数据）。这种机制替代了轮询API的实时通知方式，允许开发者在事件发生时立即触发外部操作（如部署、测试或发送通知）。\n\n\nGithub和Gitee都支持Webhook功能，因此我们可以借助这一功能，在gitee代码发生提交时，触发gitee配置的自定义webhook，webhook通过调用github Api触发github actions自动执行，从而实现实时同步方式。\n\n\n\n\n## 3 Gitee自动同步Github\n## 4 Gitee从Github同步更新\n",16.1,{"title":6,"description":837},{"loc":847},"blog\u002F2.github仓库代码和gitee仓库代码双向自动同步方案",[306,316],[855,857],{"name":101,"icon":856,"symbol":101,"id":306},"simple-icons:gitee",{"name":858,"symbol":858,"icon":859,"id":316},"github","ri:github-fill","2026-03-12 10:02:23",2904,"FXvOcy6wtiRSX7i0FdOsE_ihnBq3V8O5p82vesoduYM",1778143539077]