跳至正文
老丹的足迹 —— 代码写给机器,游记写给自己,感悟写给时间
老丹的足迹 老丹的足迹
老丹的足迹 老丹的足迹
  • 首页
  • 示例页面
  • 首页
  • 示例页面
老丹的足迹 老丹的足迹
老丹的足迹 老丹的足迹
  • 首页
  • 示例页面
  • 首页
  • 示例页面

一招搞定:如何将 Git 项目同时推送到多个远程仓库

前言

在实际开发中,我们常常需要将同一个 Git 项目推送到多个远程服务器。比如公司的内部代码托管平台和 GitHub 各放一份,又或者像国内很多开发者一样,既推送到 Gitee(码云),又推送到华为云 CodeHub。这样做的目的可能是备份、方便不同团队协作,也可能是为了满足不同环境的部署需求。

本文将从最基础的配置讲起,逐步带你掌握一套清晰、安全的推送流程。

一、理解几个关键概念

在开始操作之前,我们需要先厘清几个容易混淆的概念。

1. 本地仓库 vs 远程仓库

本地仓库就是你电脑上的项目文件夹,它包含了完整的代码和提交历史。远程仓库则是存放在服务器上的代码仓库,比如 Gitee 或华为云上的仓库。

通俗地说,远程仓库相当于云盘上的备份,本地仓库就是你电脑里的源文件。

2. 分支:本地和远程是两套名字系统

Git 有一个很重要的特性:本地分支名和远程分支名是相互独立的。

你可以把本地分支叫做 xhsgit,推送到远程后让它叫 master;也可以让两边都叫 xhsgit。这完全由你决定,只需要在推送时指定好映射关系即可。

3. Tag 与分支的区别

这是新手最容易混淆的地方。分支会随着新的提交不断向前移动,它是一条动态的开发线。而 Tag 则像一个钉子,钉在某个固定的提交上就不再移动了,通常用来标记版本号(如 v1.0.0、X0.3.4)。

更重要的是,Tag 不区分分支。无论你在哪个分支上,打上的 Tag 都是全局可见的,它指向的就是那一个固定的提交哈希值。这个特性让 Tag 在推送到多个服务器时格外方便。

二、配置多个远程仓库

1. 查看当前配置

首先,看看你的项目当前配置了哪些远程仓库:

git remote -v

输出结果会显示所有远程仓库的别名和地址。通常默认的别名是 origin,指向你的主要托管平台。

如果你的项目还没有添加额外的远程仓库,可以用以下命令添加。

2. 添加第二个远程仓库

假设你已经在 Gitee 上有一个仓库(默认叫 origin),现在想添加华为云 CodeHub 作为第二个远程仓库:

git remote add xhszjy git@codehub.xxx.com:路径/仓库名.git

这里的 xhszjy 是你给华为云起的别名,可以随意命名,但建议起一个有意义的名字,方便记忆。添加完成后,再次执行 git remote -v 就能看到两个远程仓库了。

三、推送代码到多个服务器

1. 分别推送(最推荐的方式)

这是最清晰、最安全的方式。每次推送时明确指定远程仓库别名和分支名:

# 推送到 Gitee
git push origin xhsgit

# 推送到华为云
git push xhszjy xhsgit

如果想让远程分支名和本地不一致,可以使用完整的写法:

git push origin xhsgit:xhsgit      # 本地 xhsgit 推送到远程 xhsgit
git push xhszjy xhsgit:master      # 本地 xhsgit 推送到远程 master

格式为:git push <远程别名> <本地分支名>:<远程分支名>。

2. 查看本地分支与远程分支的关联关系

执行以下命令可以清晰地看到每个本地分支关联了哪个远程分支:

git branch -vv

如果输出显示类似 领先 2 的字样,说明本地比远程多了 2 个提交,意味着你还有改动没有推上去。

3. 关于强制推送

有时我们需要用本地代码覆盖远程分支,这时可以加上 --force 参数:

git push origin xhsgit:xhsgit --force

需要注意的是,强制推送会丢弃远程分支上那些本地没有的提交,操作前务必确认远程的旧代码确实不再需要了。

四、推送 Tag 到多个服务器

Tag 的推送和分支有所不同。Tag 不会随普通的 git push 自动上传,需要单独推送。

1. 推送单个 Tag

git push origin XG0.3.4
git push xhszjy XG0.3.4

2. 一次性推送所有 Tag

git push origin --tags
git push xhszjy --tags

3. 为什么 Tag 推送如此简单?

因为 Tag 是指向某个固定提交哈希的全局标签,不区分分支。你在本地给某个提交打上 Tag,无论推送到哪个远程仓库,这个 Tag 指向的始终是同一个提交。所以不需要做任何分支切换或适配工作,只需把 Tag 名告诉每个远程仓库即可。

五、实战案例:统一混乱的分支

在实际工作中,我们经常会遇到分支混乱的情况。下面以一个真实场景为例,展示如何理清思路、统一分支。

场景描述

你的项目有两个远程仓库,分别叫 origin(Gitee)和 xhszjy(华为云)。本地有多个分支:master、xhs、xhsgit、xhs-ss、xhsstn,它们指向不同的提交,代码内容各不相同。最终你决定以本地的 xhsgit 分支为准,让它成为唯一的最终版本。

操作步骤

第一步:确认当前在正确的分支上

git branch

确保 * 号在 xhsgit 前面。如果不是,执行 git checkout xhsgit 切换过去。

第二步:推送到所有远程仓库

git push origin xhsgit:xhsgit --force
git push xhszjy xhsgit:xhsgit --force

第三步:将本地 master 分支也指向同一个提交(可选)

git branch -f master xhsgit

第四步:修改本地 xhsgit 的默认关联(可选)

如果希望以后执行 git pull 和 git push 时默认操作 Gitee,可以修改上游关联:

git branch --set-upstream-to=origin/xhsgit xhsgit

第五步:清理多余的分支

删除本地已废弃的分支:

git branch -D xhs xhs-ss xhsstn

删除远程已废弃的分支:

git push origin --delete xhs xhs-ss xhsstn
git push xhszjy --delete master

最终状态

所有仓库现在都只保留一个主干分支 xhsgit,代码内容完全一致,彻底告别混乱。

六、常见问题与避坑指南

1. 为什么我的 Tag 在远程仓库看不到?

Tag 不会自动随 git push 上传,需要用 git push origin --tags 或指定单个 Tag 名手动推送。

2. 推送时提示”包含未合并的变更”是什么意思?

这意味着当前分支有一些修改还没有提交。用 git status 查看状态,先把修改提交或暂存后再推送。

3. 如何查看本地比远程多了哪些提交?

git log origin/xhsgit..xhsgit --oneline

4. 如何恢复被强制覆盖的分支?

如果本地还有正确的代码,重新推送即可。如果本地也被覆盖了,可以尝试从 git reflog 中找回:

git reflog
git reset --hard <提交哈希>

5. Tag 和分支到底有什么区别?

简单来说:分支是活的,会随着开发不断前进;Tag 是死的,钉在某个提交上就不再动了。分支用于日常开发,Tag 用于标记版本。

七、总结与日常操作清单

日常开发提交流程

# 1. 提交本地修改
git add .
git commit -m "功能描述"

# 2. 推送到 Gitee
git push origin xhsgit

# 3. 推送到华为云
git push xhszjy xhsgit

# 4. 如果有新版本需要打 Tag
git tag X0.3.5
git push origin X0.3.5
git push xhszjy X0.3.5

几条核心建议

  • 明确指定远程和分支:不要依赖默认行为,每次推送都把目标写清楚。
  • 推送前先看一眼差异:用 git diff 和 git log 确认改了什么。
  • Tag 单独推送:记住 --tags 参数,或者逐条推送。
  • 保持分支名一致:如果条件允许,让本地和远程的分支名保持一致,能显著减少困惑。
  • 谨慎使用 --force:强制推送前务必确认远程旧代码不再需要。

掌握了以上内容,你就能轻松应对”一个项目推多个 Git 服务器”的场景了。无论是日常协作、跨平台备份,还是版本发布,都能从容处理。

作者

老丹

关注我
其他文章
上一个

Linux 系统的“不可重入”:一个你必须懂的“线程安全”陷阱

下一个

Linux 内核参数 rp_filter 完全解析

关于博主

    老丹是一名C/C++后台开发工程师,信奉“无抽象不设计,无性能不生产”。

  • 技术栈:Modern C++、Linux环境编程、多线程/并发、网络编程等。
  • 信条:能用constexpr解决的问题绝不拖到运行时,能靠RAII避免的泄漏绝不写析构。
  • 正在填坑:从解封装到渲染的C++全链路实现,正在驯服FFmpeg与H.264/H.265。
  • 输出原则:这里的每一段代码都经过-Wall -Wextra -Werror -O2的洗礼。

近期文章

  • Ubuntu 防火墙迁移指南:从 UFW 到 firewalld 的完整实践 2026年9月12日
  • Nano 编辑器完全操作指南:从入门到熟练 2026年9月12日
  • SSCG:让自签名证书不再“危险”的生成工具 2026年9月12日
  • Ubuntu Samba 服务安装与配置完全指南 2026年9月12日
  • 从零开始:用 Docker 部署 Jellyfin 并启用英特尔核显硬件加速 2026年9月11日

文章分类

  • C/C++开发 (22)
  • Docker容器 (5)
  • Linux工具包 (17)
  • Linux服务配置 (50)
  • Linux系统 (16)
  • OpenWrt路由 (3)
  • Shell脚本 (3)
  • 代码管理 (1)
  • 安防技术 (4)
  • 数据安全 (36)
  • 未分类 (1)
  • 网络协议 (25)
  • 计算机理论 (23)
  • 音视频技术 (5)
联系我们:📍 地址:中国·广东省深圳市   |   ✉️ 邮箱:support@tanglinux.com   |   💬 QQ:870866607
版权所有:老丹的足迹粤ICP备2026061170号-1       公安备案图标 粤公网安备44030002013274号