Mac电脑 Git 安装配置与 VSCode 图形化操作指南
很多人拿到一台 Mac装完编辑器、配好输入法第三件事就是把 Git 拾掇利索。但真动手时会发现Mac 上的 Git 有点三头六臂系统自带一份、Homebrew 装一份、Xcode 命令行工具里还藏着一份which -a git一敲能出来三行路径。再叠加 VSCode 的图形化操作界面很多人就卡在我到底在用哪个 Git为什么源代码管理面板是空的提交按钮点了没反应这类问题上。这篇就按我自己的实际配置顺序把mac电脑上git的安装与配置讲透再把vscode的图形化操作界面从开关到日常提交流程一路走完。适合刚换 Mac 的开发者、习惯命令行但想试试图形界面的老手以及被 SSH 密钥和多账号搞晕过的同学。全程按先搞清家底、再连远程、最后上手操作的顺序推进每一步都说明为什么这么做。1. 先把 Mac 上 Git 的家底摸清楚再决定装不装1.1 系统自带的那份 Git 是什么来路在终端敲git --version如果直接报一串版本号说明系统里已经有 Git 了如果弹出一个对话框让你安装命令行开发者工具那就是没有。macOS 自带的 Git 并不是苹果单独打包给你的它属于Xcode Command Line Tools的一部分实际路径在/usr/bin/git。这个路径有个特点它是个壳真正的可执行文件在/Library/Developer/CommandLineTools/usr/bin/git。为什么要关心这个因为它决定了你的 Git 版本号跟随系统更新走。比如 macOS 12 上自带的 Git 可能是 2.32 左右而当时最新已经到了 2.36。日常 clone、commit、push 差别不大但涉及到git restore --staged、git switch这些较新的子命令或者git sparse-checkout完整功能时版本差一截就会报git: switch is not a git command。遇到这种报错不用怀疑人生先看版本号。如果你只是想快速用一下装命令行工具就够了一条命令搞定xcode-select --install提示这一步会弹窗点击安装后要等几分钟到十几分钟不等取决于网速。中途别关窗口装完再敲git --version验证。1.2 用 Homebrew 装一份自己能控制的 Git我更推荐用 Homebrew 单独装一份原因很实在一是版本新二是升级不用等系统大版本更新三是卸载干净不会和系统组件纠缠。# 如果还没有 Homebrew先装 /bin/bash -c $(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh) # 安装最新版 Git brew install git # 升级 brew upgrade git装完之后关键问题是PATH 顺序。Apple Silicon 芯片的 MacHomebrew 装在/opt/homebrewGit 在/opt/homebrew/bin/gitIntel 芯片在/usr/local/bin/git。你可以这样确认which -a git如果输出的第一行是/usr/bin/git说明系统自带的那份排在前面你敲git用的还是老版本。这时需要调整 shell 配置。macOS Catalina 之后默认 shell 是 zsh所以要改~/.zshrc不是~/.bash_profile这个是新手最常踩的坑# 编辑 ~/.zshrc export PATH/opt/homebrew/bin:$PATH # 让配置生效 source ~/.zshrc # 再次确认 which git # 期望输出/opt/homebrew/bin/git注意Intel 机型要写/usr/local/bin。不确定自己芯片型号敲uname -marm64是 Apple Siliconx86_64是 Intel。1.3 第一次配置必须落到实处的几个字段Git 装好后第一件事是报户口否则提交记录上会显示unknown或者用本机用户名当作者名以后想改都很麻烦。git config --global user.name 你的名字或昵称 git config --global user.email 你的邮箱这里有个细节值得展开邮箱要和你托管平台账号绑定的邮箱一致否则提交记录不会归到你名下贡献图是灰的。如果你在同一台机器上要区分工作和个人身份可以去掉--global在具体仓库里单独配一遍。除了身份下面这几项我基本是装机必配# 新仓库默认分支用 main而不是 master git config --global init.defaultBranch main # 换行符处理Mac 上用 input 最省心详见第 6 节 git config --global core.autocrlf input # 中文文件名不转义显示 git config --global core.quotepath false # 中文文件名在 macOS 上是 NFD 编码这个开关避免同名文件被识别成两个 git config --global core.precomposeunicode true # pull 时默认用合并而不是变基新手先用 merge理解后再换 git config --global pull.rebase false配完想知道每一项到底写在哪个文件里用这条命令比逐个翻文件高效得多git config --list --show-origin输出里会标出每一行来自~/.gitconfig、/opt/homebrew/etc/gitconfig还是某个仓库的.git/config。优先级是仓库级 全局级 系统级同一个键被高层覆盖时低层不生效这点在排查我明明配了却不生效时特别有用。想直接改配置文件而不是敲命令用git config --global --edit会拉起默认编辑器打开~/.gitconfig改完存盘即生效适合批量调整。2. 让 Mac 和远程仓库对暗号SSH 密钥与多身份并存2.1 为什么我一直推荐用 SSH 而不是每次输账号密码HTTPS 方式 clone 当然能用但每次 push 都要输凭据虽然可以用钥匙串记住而且一旦平台调整了鉴权规则老仓库就会突然推不上去。SSH 方式配好一次后面所有仓库都省事也能天然支持多账号。现在的推荐算法是ed25519比老式的 RSA 更短、更快安全性也够ssh-keygen -t ed25519 -C 你的邮箱 -f ~/.ssh/id_ed25519执行过程会问你两件事一是密钥保存路径直接回车用默认二是 passphrase口令。建议设一个口令这样即使私钥文件泄露别人也用不了。如果嫌每次输麻烦下一步的 ssh-agent 会帮你记住。生成后目录里会出现两个文件文件名作用能否外传id_ed25519私钥相当于家门钥匙绝对不能分享id_ed25519.pub公钥相当于门锁编号需要上传到平台把公钥内容复制出来pbcopy ~/.ssh/id_ed25519.pubpbcopy是 macOS 特有命令直接把内容塞进剪贴板比cat出来手动选中方便也不容易漏字符。然后到托管平台的 SSH Keys 设置页粘贴保存。2.2 ssh-agent让口令只输一次macOS 上的 ssh-agent 需要手动把私钥加进去并且可以借助系统钥匙串记住口令# 启动 agent如果已在运行会提示 eval $(ssh-agent -s) # 添加私钥并把口令存进钥匙串 ssh-add --apple-use-keychain ~/.ssh/id_ed25519--apple-use-keychain是 macOS 专有参数老版本上是-K加上它以后重启终端、重启电脑都不用再输口令。这个细节网上很多教程没写导致有人抱怨我明明加了 agent重启就失效。如果想让终端一打开就自动加载把下面这段写进~/.zshrcif [ -z $SSH_AUTH_SOCK ]; then eval $(ssh-agent -s) /dev/null ssh-add --apple-use-keychain ~/.ssh/id_ed25519 2/dev/null fi2.3 一台 Mac 挂两个账号用 config 文件把身份分开工作一个账号、个人一个账号这在开发者里太常见了。麻烦点在于默认情况下 SSH 只会用~/.ssh/id_ed25519去连所有主机第二个账号就会认证失败。解决办法是给不同的主机起别名。先给第二个账号生成一把新密钥ssh-keygen -t ed25519 -C workexample.com -f ~/.ssh/id_ed25519_work然后在~/.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 IdentitiesOnly yes注意IdentityFile只写私钥路径不要写成.pub这是极高频的错误。IdentitiesOnly yes的作用是告诉 SSH 只用指定的这把钥匙不要到处乱试能避免账号 A 的密钥去认证账号 B的诡异情况。配好之后仓库地址要跟着改成别名形式git clone gitgithub-work:团队/仓库名.git如果仓库已经 clone 过了改一下 remote 就行git remote set-url origin gitgithub-work:团队/仓库名.git验证连通性ssh -T gitgithub-work看到欢迎语通常会告诉你认证成功以及该账号的用户名就说明通了。如果报Permission denied (publickey)按这个顺序排查ls -l ~/.ssh看私钥权限是不是600、.ssh目录是不是700、config 里的 Host 别名和 remote 地址里的别名是否完全一致差一个字母就不匹配。3. VSCode 里让 Git 面板活过来的几个开关3.1 安装后的第一件事是装 code 命令从官网下载 macOS 版是.zip双击解压得到一个Visual Studio Code.app拖进应用程序文件夹。这一步之后有个容易被忽略的动作把命令行工具装上。打开 VSCode按Cmd Shift P唤出命令面板输入shell command选择Shell Command: Install code command in PATH。装完之后你就可以在任意终端里这样用code . # 用 VSCode 打开当前目录 code ~/.zshrc # 直接编辑某个文件界面是英文的话在扩展面板搜Chinese安装官方那个简体中文语言包重启后就是中文界面。这一步不影响任何功能纯粹降低理解成本新手建议装。3.2 源代码管理面板是空的先分清三种空左侧活动栏那个分叉图标就是源代码管理面板。点开发现是空的通常有三种原因判断方法完全不同第一种你没打开文件夹。VSCode 是文件夹优先的编辑器只打开单个文件时Git 功能不会启用。用文件 打开文件夹选一个目录面板立刻就有反应。这是最常见的原因。第二种这个目录本身不是 Git 仓库。面板会显示未初始化仓库下面有个初始化仓库按钮点了就相当于执行git init。这里有个细节点完之后它会用当前全局的init.defaultBranch作为默认分支名如果你的全局配置没改默认还是master。第三种VSCode 找不到 Git。表现是面板整个消失或者提示未找到 Git。这时按Cmd ,打开设置搜git.path把 Homebrew 装的 Git 绝对路径填进去{ git.path: /opt/homebrew/bin/git }用which git拿到实际路径再填别凭记忆写。另外确认git.enabled是true这个开关如果被某个配置模板关掉了面板也不会出现。3.3 我每次装完 VSCode 都会改的几项配置打开设置 搜索 git或者直接编辑settings.jsonCmd Shift P输入Open User Settings (JSON)。下面是我自己用了很久的一套逐项说明理由{ git.enabled: true, git.path: /opt/homebrew/bin/git, git.autofetch: true, git.autofetchPeriod: 180, git.confirmSync: false, git.enableSmartCommit: true, git.smartCommitChanges: tracked, git.postCommitCommand: push, git.openDiffOnClick: true, git.ignoreLegacyWarning: true }git.autofetch后台定时去远程拉取最新引用这样你在分支列表里能看到本地落后远程 3 个提交避免盲推。周期设 180 秒太频繁会一直占网络。git.confirmSync关掉确定要同步吗的弹窗。有人担心误操作但在个人项目上这个弹窗纯粹是打断节奏。git.enableSmartCommit当暂存区为空时提交会自动把所有改动加入暂存。装了这个之后操作快很多但改文件很多时容易把不想提交的内容一起带上所以我配了smartCommitChanges: tracked只自动带上已被跟踪的文件新文件仍需手动暂存算是个折中。git.postCommitCommand: push提交完自动推送。这个开关看团队习惯如果你们走 PR 流程、不允许直推主干建议设成none。git.openDiffOnClick点文件直接进 diff 视图而不是打开原文件。习惯后效率提升明显。提示settings.json里如果已有内容注意 JSON 语法多了个逗号整个文件都会失效VSCode 会在编辑器里用红色波浪线提示。4. 图形界面下的日常提交流程从改代码到推上远程4.1 行级暂存把顺手改的和本次要提交的分开图形界面最大的价值就在这里。假设你改了一个功能文件同时顺手删了几行调试日志、调了一下缩进。命令行下要拆成两次提交得用git add -p一路交互回答一串 y/n。在 VSCode 里就直观得多打开源代码管理面板点某个文件进入 diff 视图。左边是原始内容右边是当前内容。把鼠标悬停在某个改动块上会出现几个小按钮其中一个是暂存此代码块Stage Change。点一下只有这一块被加进暂存区其余留在工作区。如果想更细可以选中具体几行右键选择暂存所选范围。这个能力配合git.enableSmartCommit要特别小心如果暂存区已经有内容了智能提交不会自动把其余改动带上这是对的但如果你刚提交完、暂存区空了再点提交就会把所有改动一锅端。我的习惯是先手动暂存确认暂存列表里只有预期文件再写提交信息不要依赖自动暂存。4.2 提交信息的输入体验和提交模板在面板顶部的输入框写提交信息按Cmd Enter提交。这里有两个提升效率的小技巧。第一如果你想写多行提交信息标题 详细说明按输入框右侧的展开图标会变成一个多行文本框。团队如果用 Conventional Commitsfeat:/fix:/docs:这种前缀建议在仓库里放一个提交模板文件.gitmessage# 类型: 简短描述 # 类型可选feat / fix / docs / style / refactor / test / chore # # 详细说明为什么改而不是改了什么然后配置git config --local commit.template .gitmessageVSCode 的提交框目前不会自动加载模板内容命令行git commit不带-m时会加载所以模板更多是给命令行兜底用。第二输入框支持范围暂存按钮。写提交信息时输入框右上角会多出暂存所有更改和暂存所有更改并提交两个按钮。第二个按钮非常方便但它是全量暂存 提交用之前务必看一遍改动列表。4.3 分支切换、合并与冲突解决图形界面真正省事的地方左下角状态栏会显示当前分支名点一下会弹出分支列表可以切换、新建、从某个提交建分支。新建分支时 VSCode 会问从哪里创建默认是当前 HEAD可以选其他分支或某个具体标签这个选择器比记git switch -c 名字 起点直观。冲突是新手最怕的场景而图形界面对这块的提升最明显。合并或拉取产生冲突后冲突文件在面板里会被标记为!打开文件会看到这样的标记块 HEAD 当前分支的内容 对方分支的内容 feature/xxx上方会出现一行操作链接采用当前更改 / 采用传入更改 / 采用两者 / 比较更改。点比较更改会打开三向合并编辑器左边是你的、右边是对方的、中间是合并结果可以逐块接受也可以手动编辑。我的经验是简单的二选一冲突用链接按钮就够了复杂冲突一定进三向编辑器因为中间结果区可以手动改改完直接保存比在纯文本里删标记可靠得多。全部冲突解决后把文件逐个暂存VSCode 会提示所有冲突已解决这时才能提交。没暂存完就提交Git 会拒绝——这是保护机制不是 bug。4.4 拉取和推送的时机先拉后推别硬推面板底部的同步按钮两个箭头转圈那个在git.confirmSync: false时点一下就直接拉取 推送。听起来爽但有个前提本地和远程没有分叉。如果两边都有新提交同步会触发一次合并可能直接把冲突带进来。我自己的习惯是拆开做先用...菜单里的拉取Pull确认无冲突后再推送Push。分支后面带↑2表示本地领先 2 个提交↓1表示落后 1 个。关于 pull 的行为前面全局配了pull.rebase false即拉取时合并。这个选择对新手的意义是合并会产生一个合并提交历史是网状但信息完整变基会把你的提交搬到对方提交之上历史是一条直线但会重写提交哈希。个人项目、单人分支我倾向变基多人共享分支我倾向合并。VSCode 在git.pullRebase为 true 时拉取会走变基路径。改法git config --global pull.rebase true # 想用变基 git config --global pull.rebase false # 想用合并5. 图形界面搞不定的时候回到终端才是正解5.1 哪些操作我从来不指望图形界面VSCode 的 Git 集成覆盖了日常八成操作但有几类事它做起来别扭甚至做不了交互式变基git rebase -i压缩、重排、改写历史提交。命令行会拉起一个编辑器让你写pick/squash/reword图形界面基本无能为力。挑选提交git cherry-pick面板里没有入口得用命令。顺带一提cherry-pick 后如果冲突git cherry-pick --abort是唯一的退路这个命令值得记牢。找回误删的提交见下一节。仓库体检与清理git gc、git fsck、.git目录瘦身这些必须命令行。所以我把 VSCode 内置终端Ctrl 当成标配。它默认打开的就是当前项目目录Git 的图形界面和命令行共享同一个仓库状态你在终端里的任何操作面板会立刻刷新两边混着用没有问题。5.2 撤销这件事必须分清三个命令这是我在带新人时发现最容易搞混的地方做个表说清楚。命令影响范围典型用途是否安全git restore 文件只丢工作区改动改乱了想还原会丢改动谨慎git restore --staged 文件只把它移出暂存区误 add 了文件内容仍在工作区git revert 提交生成一个反向提交已推送的提交要撤销安全保留历史git reset --hard 提交移动分支指针并清空本地未推送的提交撤销会丢提交靠 reflog 救VSCode 面板里右键文件能看到放弃更改对应git restore和取消暂存对应git restore --staged这两个够用了。revert和reset我基本都在终端里做。万一reset --hard用错了怎么办别慌只要提交过就不算丢。用git reflog它会列出 HEAD 移动的完整历史包括刚才那次 reset。找到目标提交的哈希git reset --hard 哈希或git branch 救回来 哈希就能回来。默认保留 90 天不可达对象 30 天时间相当充裕。这个技巧救过我不止一次。5.3 值得装的几个 Git 相关插件VSCode 自带的 Git 面板够用但下面几个装了之后体验会上一个台阶插件主要作用适合谁GitLens行内 blame、提交历史、文件历史对比需要频繁追溯这行谁改的Git Graph可视化提交图支持在图上建分支、cherry-pick想看整体历史脉络Git History单文件历史、按行查看演变排查某文件何时被改动GitLens 的行内 blame 有个副作用每行末尾会多出一段灰色的作者信息有人觉得干扰阅读。可以在设置里关掉{ gitlens.currentLine.enabled: false, gitlens.hovers.currentLine.over: line }保留悬停查看、关掉常驻显示是我用下来比较舒服的平衡点。Git Graph 特别提醒一句它虽然能在图上直接操作分支和 cherry-pick但这类操作本质是写历史动手前先确认当前没有未提交的改动否则容易把自己绕进去。6. 几个我踩过、且身边人几乎都会踩的坑6.1 换行符一个改动导致整个文件全变了Windows 用 CRLFmacOS 和 Linux 用 LF。如果团队里有人用 Windows而你没配好换行符策略可能出现我只改了一行diff 却显示整个文件都变了。原因是 Git 把行尾差异也算进了改动。全局配置里我们写了core.autocrlf input含义是提交时把 CRLF 转成 LF检出时不转换。在 Mac 上这是比较合适的取值。它的对照关系是取值提交时检出时适用平台inputCRLF → LF不转换macOS / LinuxtrueCRLF → LFLF → CRLFWindowsfalse不转换不转换全平台一致的项目如果仓库里已经混进了 CRLF光配autocrlf不够还需要在仓库根目录加.gitattributes来一锤定音* textauto *.sh text eollf *.png binary* textauto让 Git 自动判断文本文件并统一成 LF*.sh text eollf强制脚本文件用 LF否则在 Mac 上执行会报bad interpreter*.png binary明确告诉 Git 别对二进制文件做任何转换避免图片损坏。6.2.DS_Store和那些不该进仓库的文件macOS 的 Finder 会在访问过的目录里写入.DS_Store记录图标位置这类信息。如果不忽略它会被git add .一起提上去然后每次打开文件夹都可能变造成无意义的提交。在项目根目录建.gitignore写清楚.DS_Store **/.DS_Store node_modules/ dist/ .env *.log .idea/ .vscode/settings.json其中**/.DS_Store是递归匹配只写.DS_Store在某些情况下匹配不到子目录。另外设个全局忽略文件更省心省得每个仓库都写一遍# 建立全局忽略文件 echo .DS_Store ~/.gitignore_global git config --global core.excludesfile ~/.gitignore_global注意.vscode/settings.json是否忽略要看团队约定。如果团队希望统一格式化规则反而应该把它提交上去。我个人的做法是只忽略.vscode里和本机路径强相关的部分比如git.path。6.3 中文文件名显示成一串八进制如果git status里中文文件名显示成\346\226\207\344\273\266.md这种样子就是core.quotepath的默认行为在作怪。前面配的git config --global core.quotepath false就是解决它的。这个问题在图形界面下表现略有不同VSCode 一般显示正常但你在终端里看到的和面板里看到的不一样容易误以为文件被改名了。统一配好就没事。另外还有一个更隐蔽的坑macOS 文件系统用 NFD 编码存中文也就是é可能被存成e 组合符。如果同一个中文名文件在 Linux 上提交、Mac 上检出Git 可能认为这是两个不同文件导致重复。core.precomposeunicode true就是把这个行为拉齐中文项目建议必配。6.4 权限变化也会触发无改动却显示已修改macOS 是类 Unix 系统Git 会记录文件的执行位executable bit。如果某个文件从 644 变成 755即使内容一字未改git status也会显示为已修改。常见的触发场景是把文件从 Windows 拷过来、或者从压缩包里解压出来。判断方法git diff # 如果输出类似 old mode 100644 / new mode 100755就是权限问题处理方式有两种一是不想让 Git 管权限直接关掉这个跟踪git config --global core.filemode false二是确实需要保留执行权限比如脚本那就正常提交这次权限变更。这里还有个细节core.filemode是仓库级配置在 Mac 上 clone 的仓库默认就是true。上面用--global只是给以后新建的仓库设默认值对已有仓库要进去单独配一次或者用git config --local core.filemode false。7. 我平时维护这套环境的一些小习惯配置这东西配一次能用很久但有几个习惯让我少踩了不少坑顺手记一下。第一把~/.gitconfig备份到自己的仓库里。换电脑时git clone下来软链过去就行比重新回忆配了哪些项快得多。注意这个仓库必须是私有的gitconfig里可能有邮箱和工作相关的别名配置。第二升级 Git 之后顺手跑一次git config --list --show-origin。Homebrew 升级偶尔会调整默认路径或配置文件位置看一眼能确认自己那份配置还在生效尤其是credential.helper这类容易被覆盖的项。第三VSCode 的 Git 面板和终端不要两边同时动手。它们共享同一份仓库状态但界面的刷新有延迟。如果你在终端里git stash之后立刻在面板里点提交可能点的是一个已经过时的文件列表。稳妥做法是操作完在终端敲git status确认状态再回面板操作。第四钥匙串里如果存了旧凭据会和新密钥打架。表现是 HTTPS 方式总是认证失败、或者一直用错账号。打开钥匙串访问搜索托管平台域名把旧条目删掉即可。这个排查方向很多人想不到白白折腾半天 SSH 配置。第五多账号场景下判断我现在用的是哪个身份的最快方式是这个组合git config user.email # 当前仓库生效的邮箱 git remote -v # 当前 remote 用的主机别名两行对上就说明身份没错。提交前扫一眼比提交完发现作者错了再改历史省事太多。