一、基础 Git 推送流程(单账号)

# 1. 初始化本地仓库
git init
# 2. 添加所有文件到暂存区
git add --all
# 3. 提交到本地仓库
git commit -m "test"
# 4. 添加远程仓库(默认命名为 origin)
git remote add origin [email protected]:yourname/repo.git
# 5. 查看当前远程地址配置
git remote -v
# 6. 推送代码到远程仓库的 main 分支
git push -u origin main

注意:在第 6 步中,Git 会:

  • 查找 origin 对应的远程地址(如 [email protected]:yourname/repo.git);
  • 尝试通过 SSH 连接 [email protected]
  • 使用默认的私钥(通常是 ~/.ssh/id_rsa 或 ~/.ssh/id_ed25519)来进行身份验证;
  • 成功后将本地 main 分支推送到远程仓库。

理解 origin 和 git@… 的含义

概念 含义
origin Git 中远程仓库的本地别名,默认用于标识克隆来源
[email protected]:yourname/repo.git GitHub 的 SSH 远程仓库地址
git SSH 登录用户(GitHub 固定使用 git
github.com 远程主机名(可以通过 ~/.ssh/config 设置别名)

二、支持多个 GitHub 账号的 SSH 配置方法

如果你有多个 GitHub 账号(如:个人账号 + 公司账号),建议为每个账号生成独立 SSH 密钥,并通过 ~/.ssh/config 配置 Host 别名。

1. 生成多个 SSH 密钥对

运行下面的命令,生成多个密钥对,并将各自的 .pub 文件内容添加到对应 GitHub 账号 → Settings → SSH and GPG keys

# 个人账号密钥
ssh-keygen -t ed25519 -C "[email protected]" -f ~/.ssh/id_ed25519_personal
# 公司账号密钥
ssh-keygen -t ed25519 -C "[email protected]" -f ~/.ssh/id_ed25519_work

2. 配置 SSH config 文件(~/.ssh/config),并测试是否生效

在文件夹 ~/.ssh/ 中创建一个config文件(无后缀),并编辑如下: 其中 Host github-personal 是 SSH 的主机别名,后续远程地址就可以用这个别名代替 github.com

# 个人账号配置
Host github-personal
  HostName github.com
  User git
  IdentityFile ~/.ssh/id_ed25519_personal

# 公司账号配置
Host github-work
  HostName github.com
  User git
  IdentityFile ~/.ssh/id_ed25519_work


# 下面是测试部分,运行以下命令,如果输出全部符合预期说明配置成功
ssh -T git@github-personal
# 输出应为:Hi yourname! You've successfully authenticated...
ssh -T git@github-work
# 输出应为:Hi company! You've successfully authenticated...

3. 设置 Git 仓库远程地址使用对应 Host,并 push 推送代码

在一个仓库执行以下的远程仓库设置命令之后,这个仓库中origin的值就会对应git@github-×××:yourname/repo.git ,由于在config中配置了不同×××对应的ssh私钥,因此在不同的仓库执行push操作就会使用相应的ssh私钥认证。

需要注意的是:SSH 配置只负责验证你有没有权限推送,但不负责决定这次提交是谁写的。为了避免个人项目的提交历史里混入公司账号的头像(或反之),在配置远程地址的同时,务必在当前仓库单独设置局部的 Git 用户信息。

# 修改当前仓库的远程地址,将其设置为对应特定账号的 SSH 别名路径,下文为工作账号
git remote set-url origin git@github-work:company/repo.git

# 单独配置当前仓库的局部用户名和邮箱(切勿使用 --global 参数)
# 这里解释一下 user.name 与 user.email 的区别
# user.name:一个纯文本标签,告诉别人“这个提交自称是谁写的”。你在本地用 git log 
#     看日志时会显示这个名字。你可以随便填,比如真名、网名或花名。
# user.email:这是 Git 提交记录中最核心的身份绑定标识。当代码推送到 GitHub 后,
#     决定显示哪个头像的,正是 user.email 。在提交代码时,GitHub 会读取提交记
#     录里的邮箱,并在其数据库里比对。如果这个邮箱和你某一个 GitHub 账号里验证过
#     的邮箱对上了,它就会在网页上显示那个账号的头像,并把提交关联到那个账号的主页。
git config user.name "YourWorkName"
git config user.email "[email protected]"

# 1. 执行代码推送操作后,git识别到 git@github-work:company 后,使用config中配置
# 的 ssh 密钥免密登陆 github 并推送代码到远程仓库。
# 2. 在github仓库中,贡献者部分会显示 邮箱 [email protected] 对应的 github
# 账号提交了这个代码,并显示这个账号的头像
git push -u origin main


# 使用个人账号推送代码时一样的步骤
git remote set-url origin git@github-personal:yourname/repo.git
# 设置本项目的用户,从而防止贡献者混乱
git config user.name "YourPersonalName"
git config user.email "[email protected]"
# 正常推送代码即可
git push -u origin main

4. SSH的22端口被封怎么办

在部分网络环境(如学校、公司、酒店或部分云服务器)中,防火墙常常会屏蔽 SSH 默认的 22 端口。由于 22 端口被封锁,通过 SSH 进行的 git pullgit push 命令将会全部执行失败。

在某些网络环境(学校、公司、酒店、云服务器等)下,防火墙会屏蔽 SSH 默认的 22 端口。 这会导致 命令执行全部失败,原因正是因为 22 端口被封了 为了解决这个问题,可以利用 GitHub 提供的备用 SSH 网关服务。GitHub 允许用户通过 ssh.github.com 的 443 端口来进行 SSH 连接。因为 443 端口是 HTTPS 的标准网页端口,绝大多数网络环境都不会对其进行屏蔽。具体的操作步骤如下:

# 以下命令执行失败
git push
git pull
ssh -T [email protected]
# 通常报错是下面这样:
ssh: connect to host github.com port 22: Connection refused
fatal: Could not read from remote repository.

# 1. 编辑 SSH 配置 ~/.ssh/config  :  在 config 中加入以下内容(根据你的密钥路径):
Host ssh.github.com
  HostName ssh.github.com
  Port 443
  User git
  IdentityFile ~/.ssh/id_ed25519_×××××××

# 2. 使用以下命令修改远程仓库的 SSH 地址为 443 版本。
git remote add origin ssh://[email protected]:443/yourname/RTS-UAV.git # 第一次添加使用
git remote set-url origin ssh://[email protected]:443/yourname/RTS-UAV.git # 更改origin的地址时使用

# 【上述命令的解释】
# ------------------------------------------------------------------------
# 原默认地址:
#   [email protected]:yourname/RTS-UAV.git
# 这是 GitHub SSH 的标准格式,本质上等价于:
#   ssh://[email protected]:22/yourname/RTS-UAV.git
# 
# 新地址 及其与原地址的差异:
#   ssh://[email protected]:443/yourname/RTS-UAV.git
# 差异
#   1. 主机名变成 ssh.github.com,该地址由 GitHub 官方提供,专门用于绕过封锁】
#   2. 端口从 22 → 443 【443 是 HTTPS 端口,几乎不会被屏蔽】
#   3. 协议使用完整格式 ssh://...,可以明确地指定端口和主机
# 故,把 origin 地址改成 ssh.github.com:443 后,SSH 连接都走 443 端口以绕过防火墙。
# ------------------------------------------------------------------------

# 3. 测试 443 端口是否能连接,能得话可直接 push 或者 pull
ssh -T -p 443 [email protected]                    # 测试命令 
Hi username! You've successfully authenticated ...  # 成功会显示的内容
git push -u origin main                             # 成功后可自由push

总结

想要push代码到远程库

  1. git init 初始化仓库
  2. git add --all 添加暂存区
  3. git commit -m “test” 提交本地库
  4. git remote add origin [email protected]: … 增加远程库 origin ,他的地址为 git@…
  5. git remote -v 查看当前远程库是什么
  6. git push -u origin main 将main分支提交到远程库origin中

在执行"git push -u origin main"时,Git 会首先解析 origin 远程地址中配置的主机名(例如 [email protected]:…),并尝试通过 SSH 使用默认密钥进行身份验证,完成与远程仓库的连接。

当一台机器上配置了多个 GitHub 账号,并为每个账号生成了对应的 SSH 密钥对时,可以通过编辑 ~/.ssh/config 文件,为 github.com 设置不同的主机别名,并为每个别名绑定特定的私钥路径,从而实现账号之间的隔离。

例如,将远程地址设置为 “git@custom-alias:username/repo.git”,然后通过:"git remote set-url origin git@custom-alias:username/repo.git"替换 origin 的 URL,Git 在执行 push 时会识别到该地址中的主机名为 custom-alias,从而查找 SSH 配置中与该别名对应的密钥,使用对应账号进行认证。这也可以在首次添加远程时直接设置为别名,避免后续修改: “git remote add origin git@custom-alias:username/repo.git”。

注意:

在jetbrains的工具中使用git push的时候,工具会弹窗让用户选择使用哪一个ssh密钥,如果不选择,默认会使用它的git agent管理ssh密钥,这会和.ssh中config文件中的配置冲突。

因此,在jetbrains中push代码时,如果出现这个弹窗,记得选择正确的ssh密钥。也可以使用其他支持 git 命令的工具push代码,这样就会按照config中的配置自动选择相应的ssh密钥。


Git 子模块相关的简单操作

子模块使用记录

这里记录了简单的 git submodule 命令,仅作为个人笔记。


一、添加子模块

用于将外部依赖(如密码学库)作为子模块引入到项目中:

git submodule add <子模块仓库地址> <目标路径>
# eg. git submodule add https://github.com/×××/×××.git external/gmp
git submodule update --init --recursive

二、清理子模块中的构建产物(恢复干净状态)

编译子模块后可能会生成一些中间文件,可使用命令彻底清理子模块状态。 该命令会删除所有未跟踪文件和目录(包括构建产物),并将子模块重置为主项目中记录的提交版本。

git submodule foreach --recursive 'git clean -xfd && git reset --hard'

三、提交子模块相关变更

添加或更新子模块之后,务必提交 .gitmodules 和子模块路径,否则其他人拉取项目时可能会缺失子模块。

git add .gitmodules external/gmp external/miracl_core
git commit -m "feat(submodule): 添加 GMP 和 MIRACL Core 作为依赖"

四、删除子模块(如不再需要)

可以通过以下步骤彻底移除某个子模块:

# 1. 取消初始化并移除子模块引用
git submodule deinit -f external/gmp
git rm -f external/gmp

# 2. 删除 .git/modules 中的元数据
rm -rf .git/modules/external/gmp