一、基础 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 pull 和 git 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