深入 Git 账户模型:从提交身份到 SSH 多账户隔离的完整实践

文章目录

    • [一、Git 账户基本理论](#一、Git 账户基本理论)
      • [1.1 Git 的"账户"到底是什么?](#1.1 Git 的“账户”到底是什么?)
      • [1.2 提交身份(Identity)](#1.2 提交身份(Identity))
      • [1.3 远程账户认证(Credentials)](#1.3 远程账户认证(Credentials))
        • [1.3.1 HTTPS + gitcredentials](#1.3.1 HTTPS + gitcredentials)
        • [1.3.2 SSH](#1.3.2 SSH)
        • [1.3.3 协议与凭据系统的关系](#1.3.3 协议与凭据系统的关系)
    • [二、SSH 配置实操](#二、SSH 配置实操)
      • [2.1 配置 SSH 流程概览](#2.1 配置 SSH 流程概览)
      • [2.2 创建密钥对](#2.2 创建密钥对)
      • [2.3 复制公钥到服务器](#2.3 复制公钥到服务器)
      • [2.4 配置本地 SSH](#2.4 配置本地 SSH)
      • [2.5 测试 SSH 连接](#2.5 测试 SSH 连接)
    • [三、 多账户场景与完整解决方案](#三、 多账户场景与完整解决方案)
      • [3.1 什么是多账户场景?](#3.1 什么是多账户场景?)
      • [3.2 多账户分流方案对比](#3.2 多账户分流方案对比)
      • [3.3 完整解决方案](#3.3 完整解决方案)
        • [3.3.1 提交身份自动切换](#3.3.1 提交身份自动切换)
        • [3.3.2 SSH 认证隔离(多 Key)](#3.3.2 SSH 认证隔离(多 Key))
    • 参考资料

一、Git 账户基本理论

许多开发者习惯性地使用 git config --global user.name 来配置 Git,却鲜少意识到这一"提交身份"与远程仓库的"认证鉴权"完全解耦。本文旨在穿透日常操作的表象,系统厘清 Git 账户模型背后的分层设计逻辑。

1.1 Git 的"账户"到底是什么?

Git 本身是分布式版本控制系统,没有传统意义上的"用户账户"概念 。官方将实际使用中的"账户"拆解为两个完全独立的维度:

  • 提交身份(Identity):写入提交对象的元数据,回答"谁写的代码"。
  • 认证凭据(Credentials):与远程仓库交互时的鉴权信息,回答"谁有权推送"。

两者相互独立,共同完成代码提交和推送的完整流程。

1.2 提交身份(Identity)

user.nameuser.email 仅用于标识作者,不参与任何远程认证。一旦提交,该信息将永久进入历史(修改需重写历史)。

复制代码
# 全局配置(对当前用户所有仓库生效)
git config --global user.name "Your Name"
git config --global user.email "you@example.com"

# 仅对当前仓库生效(在项目目录下去掉 --global)
git config user.name "Your Name"
git config user.email "you@example.com"

1.3 远程账户认证(Credentials)

Git 早期即支持多种传输协议(local、ssh、git、http),其认证逻辑被刻意解耦:

  • SSH:复用系统级安全基础设施(密钥对),同时解决加密传输与身份认证。
  • HTTPS :通过 credential helper 适配各 OS 的密钥管理体系,降低用户门槛。

这种分层使 Git 核心保持轻量,不重复造轮子。

维度 HTTPS + gitcredentials SSH
所属层级 应用层(Git 凭据管理) 传输层(协议 + 认证)
核心职责 提供用户名 + Token 建立加密通道,用密钥对认证
是否参与加密 否(依赖 TLS)
典型场景 个人开发、企业代理环境 多账户、自动化、大型仓库(如 AOSP)
1.3.1 HTTPS + gitcredentials

设计动机:兼容企业防火墙(443 端口),降低新手使用门槛。

工作流程 :Git 客户端在推送时触发 credential helper,后者从系统钥匙串(Windows 的 wincred、macOS 的 osxkeychain 或 Linux 的 libsecret)中检索或缓存凭据。Git 本身不存储密码,仅负责在 HTTPS 请求中携带 Token。
远程仓库 HTTPS 通道 Credential Helper Git Client 远程仓库 HTTPS 通道 Credential Helper Git Client #mermaid-svg-HjWWtl7A0u1vbgqP{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-HjWWtl7A0u1vbgqP .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-HjWWtl7A0u1vbgqP .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-HjWWtl7A0u1vbgqP .error-icon{fill:#552222;}#mermaid-svg-HjWWtl7A0u1vbgqP .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-HjWWtl7A0u1vbgqP .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-HjWWtl7A0u1vbgqP .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-HjWWtl7A0u1vbgqP .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-HjWWtl7A0u1vbgqP .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-HjWWtl7A0u1vbgqP .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-HjWWtl7A0u1vbgqP .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-HjWWtl7A0u1vbgqP .marker{fill:#333333;stroke:#333333;}#mermaid-svg-HjWWtl7A0u1vbgqP .marker.cross{stroke:#333333;}#mermaid-svg-HjWWtl7A0u1vbgqP svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-HjWWtl7A0u1vbgqP p{margin:0;}#mermaid-svg-HjWWtl7A0u1vbgqP .actor{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-HjWWtl7A0u1vbgqP text.actor>tspan{fill:black;stroke:none;}#mermaid-svg-HjWWtl7A0u1vbgqP .actor-line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-HjWWtl7A0u1vbgqP .innerArc{stroke-width:1.5;stroke-dasharray:none;}#mermaid-svg-HjWWtl7A0u1vbgqP .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333;}#mermaid-svg-HjWWtl7A0u1vbgqP .messageLine1{stroke-width:1.5;stroke-dasharray:2,2;stroke:#333;}#mermaid-svg-HjWWtl7A0u1vbgqP #arrowhead path{fill:#333;stroke:#333;}#mermaid-svg-HjWWtl7A0u1vbgqP .sequenceNumber{fill:white;}#mermaid-svg-HjWWtl7A0u1vbgqP #sequencenumber{fill:#333;}#mermaid-svg-HjWWtl7A0u1vbgqP #crosshead path{fill:#333;stroke:#333;}#mermaid-svg-HjWWtl7A0u1vbgqP .messageText{fill:#333;stroke:none;}#mermaid-svg-HjWWtl7A0u1vbgqP .labelBox{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-HjWWtl7A0u1vbgqP .labelText,#mermaid-svg-HjWWtl7A0u1vbgqP .labelText>tspan{fill:black;stroke:none;}#mermaid-svg-HjWWtl7A0u1vbgqP .loopText,#mermaid-svg-HjWWtl7A0u1vbgqP .loopText>tspan{fill:black;stroke:none;}#mermaid-svg-HjWWtl7A0u1vbgqP .loopLine{stroke-width:2px;stroke-dasharray:2,2;stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-HjWWtl7A0u1vbgqP .note{stroke:#aaaa33;fill:#fff5ad;}#mermaid-svg-HjWWtl7A0u1vbgqP .noteText,#mermaid-svg-HjWWtl7A0u1vbgqP .noteText>tspan{fill:black;stroke:none;}#mermaid-svg-HjWWtl7A0u1vbgqP .activation0{fill:#f4f4f4;stroke:#666;}#mermaid-svg-HjWWtl7A0u1vbgqP .activation1{fill:#f4f4f4;stroke:#666;}#mermaid-svg-HjWWtl7A0u1vbgqP .activation2{fill:#f4f4f4;stroke:#666;}#mermaid-svg-HjWWtl7A0u1vbgqP .actorPopupMenu{position:absolute;}#mermaid-svg-HjWWtl7A0u1vbgqP .actorPopupMenuPanel{position:absolute;fill:#ECECFF;box-shadow:0px 8px 16px 0px rgba(0,0,0,0.2);filter:drop-shadow(3px 5px 2px rgb(0 0 0 / 0.4));}#mermaid-svg-HjWWtl7A0u1vbgqP .actor-man line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-HjWWtl7A0u1vbgqP .actor-man circle,#mermaid-svg-HjWWtl7A0u1vbgqP line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;stroke-width:2px;}#mermaid-svg-HjWWtl7A0u1vbgqP :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} HTTPS + gitcredentials alt 凭据已存在 凭据不存在 用户 git push (https://host/repo.git) 1 请求凭据 (host) 2 返回 用户名 + PAT 3 未命中 4 提示输入用户名/Token 5 输入凭据 6 store 缓存凭据 7 TLS 握手 + HTTP Basic Auth 8 传输 (带凭据) 9 认证结果 + 数据 10 完成推送 11 用户

1.3.2 SSH

设计动机:避免反复输入凭据,提供更强的安全性和自动化能力。

工作流程 :Git 调用 SSH 客户端,后者读取本地私钥(~/.ssh/id_rsaid_ed25519),通过"密钥交换 + 签名挑战"向服务器证明身份。Git 全程不接触私钥,仅利用已建立的加密通道传输数据。
远程仓库 SSH Client / ssh-agent Git Client 远程仓库 SSH Client / ssh-agent Git Client #mermaid-svg-fV5pt19uF1h0Zasr{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-fV5pt19uF1h0Zasr .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-fV5pt19uF1h0Zasr .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-fV5pt19uF1h0Zasr .error-icon{fill:#552222;}#mermaid-svg-fV5pt19uF1h0Zasr .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-fV5pt19uF1h0Zasr .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-fV5pt19uF1h0Zasr .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-fV5pt19uF1h0Zasr .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-fV5pt19uF1h0Zasr .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-fV5pt19uF1h0Zasr .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-fV5pt19uF1h0Zasr .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-fV5pt19uF1h0Zasr .marker{fill:#333333;stroke:#333333;}#mermaid-svg-fV5pt19uF1h0Zasr .marker.cross{stroke:#333333;}#mermaid-svg-fV5pt19uF1h0Zasr svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-fV5pt19uF1h0Zasr p{margin:0;}#mermaid-svg-fV5pt19uF1h0Zasr .actor{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-fV5pt19uF1h0Zasr text.actor>tspan{fill:black;stroke:none;}#mermaid-svg-fV5pt19uF1h0Zasr .actor-line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-fV5pt19uF1h0Zasr .innerArc{stroke-width:1.5;stroke-dasharray:none;}#mermaid-svg-fV5pt19uF1h0Zasr .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333;}#mermaid-svg-fV5pt19uF1h0Zasr .messageLine1{stroke-width:1.5;stroke-dasharray:2,2;stroke:#333;}#mermaid-svg-fV5pt19uF1h0Zasr #arrowhead path{fill:#333;stroke:#333;}#mermaid-svg-fV5pt19uF1h0Zasr .sequenceNumber{fill:white;}#mermaid-svg-fV5pt19uF1h0Zasr #sequencenumber{fill:#333;}#mermaid-svg-fV5pt19uF1h0Zasr #crosshead path{fill:#333;stroke:#333;}#mermaid-svg-fV5pt19uF1h0Zasr .messageText{fill:#333;stroke:none;}#mermaid-svg-fV5pt19uF1h0Zasr .labelBox{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-fV5pt19uF1h0Zasr .labelText,#mermaid-svg-fV5pt19uF1h0Zasr .labelText>tspan{fill:black;stroke:none;}#mermaid-svg-fV5pt19uF1h0Zasr .loopText,#mermaid-svg-fV5pt19uF1h0Zasr .loopText>tspan{fill:black;stroke:none;}#mermaid-svg-fV5pt19uF1h0Zasr .loopLine{stroke-width:2px;stroke-dasharray:2,2;stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-fV5pt19uF1h0Zasr .note{stroke:#aaaa33;fill:#fff5ad;}#mermaid-svg-fV5pt19uF1h0Zasr .noteText,#mermaid-svg-fV5pt19uF1h0Zasr .noteText>tspan{fill:black;stroke:none;}#mermaid-svg-fV5pt19uF1h0Zasr .activation0{fill:#f4f4f4;stroke:#666;}#mermaid-svg-fV5pt19uF1h0Zasr .activation1{fill:#f4f4f4;stroke:#666;}#mermaid-svg-fV5pt19uF1h0Zasr .activation2{fill:#f4f4f4;stroke:#666;}#mermaid-svg-fV5pt19uF1h0Zasr .actorPopupMenu{position:absolute;}#mermaid-svg-fV5pt19uF1h0Zasr .actorPopupMenuPanel{position:absolute;fill:#ECECFF;box-shadow:0px 8px 16px 0px rgba(0,0,0,0.2);filter:drop-shadow(3px 5px 2px rgb(0 0 0 / 0.4));}#mermaid-svg-fV5pt19uF1h0Zasr .actor-man line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-fV5pt19uF1h0Zasr .actor-man circle,#mermaid-svg-fV5pt19uF1h0Zasr line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;stroke-width:2px;}#mermaid-svg-fV5pt19uF1h0Zasr :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} SSH (密钥认证) 用户 git push (git@host:repo.git) 1 建立 SSH 会话 (读取私钥) 2 密钥交换 + 签名挑战 3 验证公钥身份 4 加密通道已建立 5 在 SSH 通道上传输数据 6 完成推送 7 用户

1.3.3 协议与凭据系统的关系

切换远程 URL 的协议(HTTPS ↔ SSH)不等于切换凭据系统。Git 根据 remote URL 自动决定调用哪条链路:

bash 复制代码
# HTTPS(依赖 gitcredentials)
https://github.com/user/repo.git

# SSH(依赖 SSH Agent / 密钥)
git@github.com:user/repo.git

关键结论gitcredentials 与 SSH 并非互斥,而是分别对应不同协议。使用 HTTPS 时才涉及 credential helper;使用 SSH 时 Git 完全绕过它。

二、SSH 配置实操

在理解账户模型后,本章从零开始搭建 SSH 环境。

2.1 配置 SSH 流程概览

将 SSH 公钥添加到 Git 服务器账号,核心作用是实现安全的免密码身份认证。连接时,服务器用公钥加密随机字符串发送给客户端,本地 SSH 通过私钥解密并返回结果,服务器校验通过后即完成认证。

注意:Git 安装时可选择使用自带 SSH 或系统 SSH。执行 Git 命令时,Git 会自动调用配置的 SSH 客户端,无需手动干预。

2.2 创建密钥对

使用系统自带 OpenSSH 生成密钥对,可按提示设置 passphrase(也可留空):

bash 复制代码
$ ssh-keygen -t rsa -C "username@example.com"
Generating public/private rsa key pair.
Enter file in which to save the key (C:\Users\username/.ssh/id_rsa):
Created directory 'C:\Users\username/.ssh'.
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in C:\Users\username/.ssh/id_rsa
Your public key has been saved in C:\Users\username/.ssh/id_rsa.pub
The key fingerprint is:
SHA256:aBcDeFgHiJkLmNoPqRsTuVwXyZ1234567890abcd username@example.com
The key's randomart image is:
+---[RSA 3072]----+
|          .o+*   |
|         + o .+  |
|        . + .  . |
|       . . .  .  |
|        S   .  . |
|       .   .  .  |
|      . . . ..   |
|     . . . .o.   |
|      . ...=.    |
+----[SHA256]-----+

生成成功后,会在 ~/.ssh/ 目录下生成两个文件:

  • id_rsa.pub 公钥:需上传至 Git 服务器,用于身份校验
  • id_rsa 私钥:保存在本地,绝不外传

2.3 复制公钥到服务器

将公钥文件内容(含算法、公钥数据、注释三部分)完整添加到 Git 服务器(GitHub / GitLab / Gerrit)的 SSH Keys 设置中。

复制公钥到 Github 服务器具体操作如下图所示。

2.4 配置本地 SSH

为每个目标服务器创建 Host 别名,明确指定端口、用户和私钥路径,避免 SSH 自动尝试错误密钥。

手动创建配置文件 ~/.ssh/config ,在里面添加以上内容:

复制代码
# ~/.ssh/config

# Gerrit 示例
Host gerrit
    HostName 192.168.1.100                # 真实服务器 IP 或域名
    Port 29418                            # 真实服务器 SSH 端口(非默认 22)
    User yourname					      # 服务器登录用户名(Gerrit 用此映射账号)
    IdentityFile ~/.ssh/id_rsa            # 对应的私钥文件
    IdentitiesOnly yes					  # 仅使用指定的私钥,禁止 SSH 自动尝试其他 key
    PreferredAuthentications publickey    # 优先使用公钥认证,避免密码提示
    
# GitHub 示例
Host github-work
    HostName github.com
    User git                      		  # GitHub 统一要求为 git
    IdentityFile ~/.ssh/id_ed25519_work
    IdentitiesOnly yes    

2.5 测试 SSH 连接

在配置完成后,测试连接:

bash 复制代码
$ ssh -T gerrit
The authenticity of host '[192.168.10.50]:29418 ([192.168.10.50]:29418)' can't be established.
ED25519 key fingerprint is SHA256:xK9vN3rT7yF2aB8cD4eH6jK1lM5nP9qR0sU7vW2xY4z.
This key is not known by any other names.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '[192.168.10.50]:29418' (ED25519) to the list of known hosts.

  ****    Welcome to Gerrit Code Review    ****

  Hi devuser, you have successfully connected over SSH.

  Unfortunately, interactive shells are disabled.
  To clone a hosted Git repository, use:

  git clone ssh://devuser@192.168.10.50:29418/REPOSITORY_NAME.git

当 SSH 首次连接到一个陌生服务器(如 192.168.10.50)时,客户端会收到服务器的 公钥指纹(fingerprint) ,并询问你是否信任该服务器。输入 yes 后,SSH 会将该服务器的主机密钥写入 ~/.ssh/known_hosts 文件,后续连接将不再提示。

其中 ,ssh-ed25519 表示服务器使用的密钥类型(Ed25519 椭圆曲线算法,相比 RSA 更安全、性能更好)。

三、 多账户场景与完整解决方案

掌握 SSH 基础配置后,我们面对一个更现实的工程问题:**同一台电脑、多个 Git 账号,该如何优雅地共存?**本章将给出解决方案。

3.1 什么是多账户场景?

同一台机器上,以不同平台账号(如公司号 company-account 与个人号 personal-account)向同一 Git 托管平台(如 GitHub)进行认证和提交。Git 默认"一台电脑 = 一个身份"的假设会导致提交身份与认证凭据冲突。

3.2 多账户分流方案对比

维度 HTTPS + gitcredentials SSH
分流依据 URL 中的用户名或不同 host 段 ~/.ssh/config 的 Host 别名
隔离粒度 凭据按 host 缓存,同 host 默认共享 每个 Host 别名绑定独立私钥,天然隔离
典型做法 https://userA@github.com/... Host github-workIdentityFile ~/.ssh/id_ed25519_work

可以看出,同一平台多账户时,SSH 多 Key 方案更清爽;HTTPS 需通过修改 remote URL 或按 host 配置 helper scope 来绕行,维护成本较高。

3.3 完整解决方案

一个健壮的多账户环境需要叠加三层配置:

  1. 物理隔离(目录边界) :用不同目录存放不同账号的项目(如 ~/work/~/personal/)。
  2. 提交身份隔离(Git 配置层) :利用 includeIf 按目录自动加载不同的 user.name/email,确保提交元数据正确。
  3. 认证隔离 :通过 ~/.ssh/config 的 Host 别名绑定不同私钥,确保远程仓库识别为正确的账号。
3.3.1 提交身份自动切换

includeIf 仅在 Git 读取配置时生效,影响提交元数据,与 SSH 认证无关。它解决的是"commit 里显示谁"的问题。配置示例如下:

ini 复制代码
# ~/.gitconfig
[includeIf "gitdir:~/work/"]
    path = ~/work/.gitconfig-work
[includeIf "gitdir:~/personal/"]
    path = ~/personal/.gitconfig-personal
ini 复制代码
# ~/work/.gitconfig-work
[user]
    name = Your Work Name
    email = you@company.com

另外,我们顺便了解 Git 配置的优先级级别(从高到低),以便了解提交仓库使用的哪个身份。Git 配置加载遵循严格的优先级顺序(从高到低):

  1. 仓库级(.git/config):仅对当前仓库生效,优先级最高。
  2. 用户级(~/.gitconfig):当前 Windows 登录用户的 Git 全局配置,对该用户下的所有仓库生效。当条件匹配时,被 includeIf 引入的文件(如 .gitconfig-work)优先级高于主配置文件~/.gitconfig
  3. 系统级(/etc/gitconfig):面向整台机器所有用户、所有仓库的兜底配置,通常由管理员或安装程序写入,普通用户很少手动改它。
3.3.2 SSH 认证隔离(多 Key)

SSH 的身份选择由 ~/.ssh/config 控制,与 Git 配置完全解耦,管"推送到哪个账号"。每个 Host 别名绑定独立私钥,平台通过公钥识别不同账号,天然隔离。

配置示例如下:

复制代码
# ~/.ssh/config
Host github-work
    HostName github.com
    User git
    IdentityFile ~/.ssh/id_ed25519_work
    IdentitiesOnly yes

Host github-personal
    HostName github.com
    User git
    IdentityFile ~/.ssh/id_ed25519_personal
    IdentitiesOnly yes

克隆仓库时使用对应的 Host 别名:

bash 复制代码
# 公司项目
git clone git@github-work:company-account/internal-project.git

# 个人项目
git clone git@github-personal:personal-account/my-blog.git

SCP 风格地址结构<user>@<ssh-host>:<repository-path>

  • user:远程用户(GitHub 固定为 git
  • ssh-host:SSH Host 别名(来自 ~/.ssh/config
  • repository-path:GitHub 上的 组织/用户/仓库 路径

参考资料

Git - First-Time Git Setup

Git - gitcredentials Documentation

相关推荐
是2的10次方啊1 小时前
误推 master 该 revert 还是 reset?撤销与补 MR 流程
git
菠萝加点糖16 小时前
Git 删除远程文件、本地保留并取消跟踪
git
理智.62919 小时前
Git 工具使用之项目版本回退与修改备份:stash、reset、reflog 常用指令详解
git·gitee·github
就叫飞六吧21 小时前
SSH 本地端口转发:用 localhost 访问远程服务
运维·ssh
妙码生花1 天前
GIT 提交规范
git
云雀衔光1 天前
多个 MCP Server 怎么编排:数据库 / Redis / Git / 飞书一把梭
java·数据库·人工智能·redis·git·语言模型·飞书
Java后端的Ai之路1 天前
Git pull弹出vim编辑器完整排查指南
开发语言·人工智能·git·编辑器·vim
一只积极向上的小咸鱼1 天前
Codex Remote SSH / Dev Container 无限转圈与 GPT-6 可用问题排查总结
运维·gpt·ssh
云泽8081 天前
Git 版本控制系统(下):从 .git 目录结构到冲突解决机制详解
大数据·git·elasticsearch