1. 为什么要写这个系列以及你将会学到什么1.1 每一个开发者都躲不开的两件事Git 和 GitHub先聊点实际的。不管你之后是做前端、后端、移动端还是做数据分析、自动化脚本只要你的工作涉及“写代码”Git 就是一个绕不过去的工具。我自己带过不少新人入职第一天要配置的往往不是开发环境而是 Git 和 GitHub。那时候很多刚毕业的同学还不理解为什么不能直接在文件夹里拷贝一份备份代码非要搞这么一套仓库、提交、推送的概念。其实道理很简单。Git 解决的核心问题不是你一个人怎么管理代码而是一群人在同一份代码上协作时怎么保证不互相覆盖、不丢失历史、还能随时回到任何一天的状态。GitHub 则是建立在 Git 之上的远程托管平台它让团队协作、代码评审、问题追踪都变得可视化。你可以把 Git 理解成你本地的“时间机器”GitHub 就是大家都能同步访问的“公共存档点”。这个系列我会从最基础的内容开始写第一讲专门针对 Mac 用户。因为 Mac 自带了一些工具但还是有几个安装和配置的坑需要注意我会把我在不同 Mac 型号、不同 macOS 版本上踩过的问题一并整理出来保证你照着做就能顺利打通本机和 GitHub 的连接。1.2 这篇教程的定位适合谁、能解决什么问题这篇教程主要面向三类人第一次在 Mac 上接触 Git 的零基础读者、刚从 Windows 切换到 Mac 的开发者以及已经会用git commit但从来没有搞明白 SSH 和远程仓库原理的“半熟手”。我会用一套完整的实操流程带你走完在 Mac 上安装或升级 Git配置用户的姓名和邮箱生成 SSH 密钥并绑定 GitHub 账号然后在本地创建仓库、完成第一次提交推送到 GitHub最后再演示分支操作和冲突处理。整个过程不以命令大全为目标重点是把“每一步在干什么、为什么要这么干”讲清楚让你学完之后不是死记命令而是能自己判断什么时候该用什么操作。提示我假定你的 Mac 是 Apple Silicon 或 Intel 芯片都可以系统版本在 macOS 12 以上。如果你用的是公司发的受限机器可能需要管理员权限这个我在对应小节里也会说明。2. Mac 上 Git 的工具现状与安装姿势2.1 不一定非要用系统自带的 Git但最好统一版本很多第一次在 Mac 上跑git --version的人都会发现系统其实已经给你装了一个 Git。这是因为 macOS 的 Command Line Tools 里面自带了一套 Git 工具通常是 2.30 左右的版本。这些版本不是不能用但问题在于它更新节奏很慢而且你没法单独升级它。为什么我会建议你重新自己装一份主要有三个原因。第一新版本修复了不少历史遗留的 bug比如在某些文件系统下索引损坏的问题。第二新版本的git push、git rebase默认提示更友好对新手更省心。第三如果你之后要装一些基于 Git 的辅助工具它们往往会依赖比较新的 Git 版本系统自带的版本会卡住你。不过我也要说清楚如果你只是临时在终端里跑几个命令不打算长期在 Mac 上做开发那用系统自带的也没问题。但如果你准备认真对待版本控制这件事还是值得自己安装管理的。2.2 用 Homebrew 安装 Git顺便把关联依赖处理齐Mac 上安装开发工具最省心的方式就是通过 Homebrew。没有安装过 Homebrew 的话先到 Homebrew 官网复制那行安装命令在终端里执行。这里要特别提醒一句安装 Homebrew 需要命令行工具这个过程会弹窗提示你安装 Command Line Tools记得点同意不然会卡住很久。安装完 Homebrew 之后依次执行brew update brew install git然后检查安装结果git --version正常情况下你会看到类似git version 2.4x.x的输出。如果你之前用了系统自带的 Git可能需要重新打开一个终端窗口让PATH生效也可以用which git看一下你当前使用的 Git 到底是哪个路径。如果结果依然是/usr/bin/git说明你调用的是系统版本排查一下~/.zshrc或~/.bash_profile里有没有把 Homebrew 路径放对。安装完成后可以看到 Git 已经在/opt/homebrew/bin/gitApple Silicon 上或 /usr/local/bin/gitIntel 或自定义安装时了。注意如果你所在网络环境下访问 Homebrew 仓库不稳定速度很慢可以给终端配置合适的镜像源或者直接在官网通过 pkg 安装包来安装 Git。效果是一样的不用纠结于安装方式。2.3 初始化全局配置姓名、邮箱与换行符处理Git 装好了第一件要做的事就是登记你的身份。这会影响到你每一次提交记录里显示的“作者”是谁非常重要。git config --global user.name 你的名字 git config --global user.email 你的邮箱这里的名字和邮箱建议跟你之后要用的 GitHub 账号保持一致。尤其是邮箱GitHub 会用它来关联你的提交记录和你本人。如果你对隐私比较敏感GitHub 会提供一个类似你的IDusers.noreply.github.com的隐私邮箱你可以在 GitHub 设置里找到用它作为 Git 全局配置的邮箱。接着处理换行符问题。Windows 上文件换行用的是 CRLFMac 和 Linux 上则是 LF。如果你之后会跟 Windows 同事协作这个配置能避免一大堆“整文件被标记为改动”的乌龙git config --global core.autocrlf input意思是提交到仓库时统一转成 LF检出到本地时不做多余转换。如果你完全不跟 Windows 环境打交道这行也可以不设置。到这里环境就算基础就绪了。你可以用git config --list查看当前生效的配置确认没有明显写错的内容。3. 第一次连接 GitHubSSH 密钥是必须的3.1 为什么要用 SSH 而不是 HTTPS连接 GitHub 有两种主流方式HTTPS 和 SSH。如果你用的是 HTTPS每次执行git push的时候都要输入用户名和个人访问令牌Password Token。虽然可以借助系统钥匙串把密码记下来但操作起来麻烦而且在命令行里面出现敏感信息总归不够安全。SSH 的方式则是一次配置长期使用。它通过本地生成的一对密钥公钥和私钥来验证身份公钥放在 GitHub 上私钥留在自己电脑上。只要私钥不泄露连接过程稳定且安全。这也是我们在团队合作时推荐的做法尤其处理多个项目时你不需要每个仓库都去配置一次令牌。还有一点很实际SSH 连接通常比 HTTPS 更稳定在公共网络下不容易被中途打断。特别是当你要推送较大的仓库时SSH 的体验会好很多。3.2 生成密钥、添加公钥到 GitHub打开终端先看一下你是否已经有现成的密钥ls -la ~/.ssh如果这个目录里已经存在id_rsa.pub或id_ed25519.pub说明你之前生成过密钥。想复用的话可以直接跳到添加公钥的步骤不想复用也没关系可以重新生成。我推荐使用更现代、安全性更高的 ed25519 算法ssh-keygen -t ed25519 -C 你的邮箱接下来终端会问你把私钥保存在哪个文件默认是在~/.ssh/id_ed25519直接回车确认。然后会让你设置一个 passphrase也就是私钥的密码。这个密码不是必须的但在安全要求较高的场景我还是建议设一个哪怕简单一点也好。设了之后每次连接可能需要输入一次密码或者你通过把密钥添加到钥匙串来省去重复输入。生成完之后查看公钥内容cat ~/.ssh/id_ed25519.pub复制这串内容打开 GitHub 网站进入 Settings - SSH and GPG keys - New SSH key标题随便写一个方便自己识别的名字比如 “MacBook Pro”把公钥内容粘贴进去保存。3.3 验证连接与常见 SSH 连接问题验证是否成功ssh -T gitgithub.com如果你是第一次连接会看到一个确认提示询问你是否继续连接输入yes回车即可。如果配置正常会返回类似Hi 你的用户名! Youve successfully authenticated, but GitHub does not provide shell access.的提示。看到这行字就说明 SSH 通路已经打通了。如果连接失败大概率是以下几个原因。第一个是私钥权限不正确SSH 对密钥文件权限很敏感可以修复一下chmod 600 ~/.ssh/id_ed25519 chmod 700 ~/.ssh第二个原因是系统没有自动加载你的私钥。如果你设置了 passphrase可以执行ssh-add -K ~/.ssh/id_ed25519第三个原因是公司网络出口限制了对 SSH 协议默认是 22 端口的访问。GitHub 提供了一个用 443 端口的 SSH 方案你可以在~/.ssh/config里加一段配置Host github.com Hostname ssh.github.com Port 443 User git改完之后重新测试连接。如果还是不行就需要检查你所在网络是否允许访问相关域名这部分不是 Git 配置本身的问题可以找网络管理员确认。4. 核心工作流从克隆到推送4.1 从 GitHub 克隆项目之前先看懂远程地址当你把 GitHub 上的仓库复制到本地时用的是git clone。不过这里的地址在复制的时候记得选 SSH 格式而不是 HTTPS 格式。在 GitHub 仓库页面上有一个绿色 Code 按钮点开后可以切换到 SSH 标签地址看起来是这样gitgithub.com:用户名/仓库名.git把它复制下来然后在你想放项目的目录下执行git clone gitgithub.com:用户名/仓库名.git克隆完成之后进入项目目录用git remote -v查看远程仓库关联情况。你会看到两个条目origin对应的就是你的远程仓库地址。origin只是一个约定俗成的名字它代表“主要的远程仓库”后面推送、拉取时都会用到这个名字。4.2 完成一次本地提交git add 与 git commit 的正确打开方式很多新手最容易困惑的就是git add和git commit的区别。我用一个简单的类比解释Git 的提交是由一系列“变更”构成的而变更不会自己进入仓库你需要先把想记录的文件放进一个暂存区然后用commit把这些暂存内容打包成一个不可变的历史节点。实际操作中你可能会看到三种常见命令风格git add 文件名精确添加某个文件。git add .添加当前目录下所有改动但要小心别把不该提交的文件也带进去。git add -u只添加已经被追踪过、现在有改动的文件不影响新增的未追踪文件。一个好的提交习惯是只把逻辑上属于同一次改动的文件放到一起提交不要把十几个互不相关的文件一次性全部add .。这样以后排查历史时每一笔提交都清晰可读。执行提交时一定要写清晰的信息git commit -m 修复登录页在移动端的布局错位问题有的人喜欢把git add和git commit合起来用比如git commit -am 信息注意这个命令只能处理已追踪的文件新文件还是需要先git add。4.3 推送、拉取与远程分支常见误区完成了本地提交之后下一步是把记录推送到 GitHubgit push origin main这里的main是你的当前分支名。Git 最近的默认分支名已经统一为main如果你创建仓库时用的是别的名字以实际分支名为准。推送的前提是你所在分支已经在远程仓库中存在对应的分支。如果这是你第一次推送一个全新分支可以加上-u参数建立关联git push -u origin feature-login-u的意思是设置上游分支之后你在当前分支上再执行git push时就不用再写origin feature-login了。拉取的时候有人会混淆git fetch和git pull。git pull其实是git fetch加git merge的合体。fetch只会把远程最新提交下载到本地但不会自动合并到你当前的工作目录pull会直接合并。结论是如果你只是想看看远程更新了什么可以先用fetch如果确定要同步到本地再pull。4.4 一个完整的例子从零提交一个项目为了让你把这些命令串起来我模拟一个项目场景你刚建了一个my-demo的本地文件夹里面有一个README.md文件想把它传到 GitHub 上一个同名空仓库。第一步在 GitHub 网页上新建一个仓库名字叫my-demo不要勾选初始化 README这样仓库是空的。第二步在本地终端进入该文件夹初始化 Gitcd ~/Projects/my-demo git init git add README.md git commit -m init project git branch -M main git remote add origin gitgithub.com:你的用户名/my-demo.git git push -u origin main刷新 GitHub 页面你就能看到 README 文件出现在仓库里了。从零到推送本质就是这几步。这套流程熟练之后你每天的工作基本都会围绕“改代码 - add - commit - push”循环。5. 分支、合并与冲突处理5.1 理解分支的本质以及保护主干分支是 Git 里最核心也最强大的功能。你可以把它理解成一个平行时空所有人在main分支之外开辟自己的开发线互不影响。开发完成之后再把代码合并回main。分支本质不过是一个指向某个提交的指针创建一个新分支的开销几乎为零。所以完全不需要害怕开分支它不会把仓库搞乱反而能让主线始终保持稳定。常用的基础操作# 查看当前分支 git branch # 创建并切换到新分支 git checkout -b feature/payment # 切换回main分支 git checkout main如果之前你看到别人的教程喜欢用git switch那也正确命令的功能一样只是属于更新的写法。个人建议是只要统一用一种风格就行不要混用减少记忆负担。在多分支协作的仓库中保护好main是很重要的。GitHub 可以通过分支保护规则禁止直接向main推送代码要求必须通过 Pull Request 合并。这样每一位成员都可以在分歧中保持主线稳定。5.2 合并与 rebase 的选择开发分支完成使命后通常需要合回主干。合并有两种主要方式merge和rebase。# 先切回main再合并feature分支 git checkout main git merge feature/paymentmerge会保留分支的历史生成一个合并提交。优点是不改动已有提交缺点是历史看起来会出现分叉可能比较复杂。rebase则是把当前分支的提交“重新应用到”目标分支之上让历史变成一条直线git checkout feature/payment git rebase main对于新手我更推荐先用merge因为它的行为最直接、可预期。当你理解了每次提交是如何被串联的再去尝试rebase会更心里有底。rebase的优点确实是历史干净但如果你不懂原理很容易把本地提交弄乱。5.3 解决合并冲突的完整排查链路冲突是在合并时最令人头疼、但其实最容易解决的问题。先说清楚冲突发生的本质Git 擅长自动合并互不相关的改动但如果你和别人都改了同一个文件的同一行Git 就无法自动判断保留谁的只好把冲突标记出来等人来处理。遇到冲突时执行git status你会看到类似both modified的字样说明该文件有冲突需要手动解决。打开这个文件会看到类似下面的内容 HEAD 这里是当前分支的代码 这里是要合并进来的代码 feature/payment你要做的就是根据实际业务决定留下哪一段或者把两段都修改整合成最终结果。然后删掉、、这些标记保存文件。之后把文件加入暂存区完成提交git add 冲突文件 git commit -m 合并feature/payment并解决冲突我自己处理过很多次冲突有几点体会分享给你。第一出现冲突不是灾难说明 Git 很诚实地告诉你有不明确点总比它偷偷覆盖掉内容要好。第二解决冲突时最好跟改动相关代码的同事确认一下意图尤其是两个人刚改完同一块逻辑时最好的结果往往不是二选一而是双方讨论出一个新的实现方案。第三冲突解决完一定要测试不要看一眼代码没问题就直接提交。注意如果合并过程中操作错了不用慌张。git merge --abort可以让你回到合并前的状态一切从头再来。6. 让 Git 更好用的日常技巧6.1 最有用的别名和配置Git 大部分操作都简单但有些命令很长每天敲下来确实手疼。配置别名是一个很好的优化方式。我自己的.gitconfig里长期放着这些git config --global alias.st status git config --global alias.co checkout git config --global alias.br branch git config --global alias.ci commit git config --global alias.lg log --oneline --graph --all --decorate设置完成之后git st就是git statusgit lg就能看到一个漂亮的提交历史图。尤其是git lg我几乎每天都会用一眼就能看清楚分支分叉情况。如果你想进一步提示自己避免误操作还可以设置提交时用git diff先行检查。不过新手更重要的其实是养成“提交前先看一下改动”的习惯git diff这条命令会显示工作区中尚未暂存的改动。如果你已经git add过了想看暂存区的内容用git diff --staged6.2 git log 的高级查看方式git log是查看提交历史的入口但默认输出很冗长。我推荐几个实用变体# 一行显示一条提交适合快速浏览 git log --oneline # 查看最近5条提交的具体改动 git log -p -5 # 查看某个文件的提交历史 git log -- 文件名 # 在当前分支但不属于main分支的提交 git log main..HEAD尤其是最后一条在准备提 Pull Request 的时候特别好用你能清楚地看到这个分支里到底多了哪些提交避免把自己不小心合并进来的无关改动也一起提交上去。6.3 找回误删除的文件git reflog 的救命用法这是我觉得每个开发者都应该知道但往往没人教你的操作。前一阵我的一个学生误删了本地一个分支吓得不轻以为几天的代码全没了。其实 Git 的恢复能力比想象中强得多。在 Git 里只要你的提交曾经被创建过即使你后来把她reset掉了只要你记得提交编号就可以找回来。问题是如果你忘记了提交编号呢这时候git reflog登场。它会记录你的 HEAD 曾经指向过的所有提交git reflog输出里你能看到类似abc1234 HEAD{2}: commit: 修复xxx的条目找到你想要的提交编号然后用git branch recover-branch abc1234就能把这个提交恢复成一个新分支。可以说只要你不是主动执行了git gc清理残留对象Git 的数据安全性是相当高的。日常操作中不小心用git reset撤错了也可以用这个思路恢复。7. 一些我踩过的坑和建议7.1 查漏补缺Mac 用户最容易犯的几个问题我见过很多次类似的问题归纳出来就这几个第一个是换行符问题导致的“假改动”。如果你在用编辑器的时候发现整个文件都被标记成变更检查一下是不是.gitattributes里没有定义各类文本文件的换行处理规则。可以在仓库根目录加一个.gitattributes文件把常见类型明确指定为textauto或eollf。第二个是提交了不该提交的文件。有人说git add .一时爽不小心把数据库密码或本地构建产物推上去就尴尬了。最好在仓库根目录配置好.gitignore把常见的node_modules、dist、.DS_Store、*.log都排除掉。不要等出了问题才想起它。第三个是拒不提交、堆积大量本地改动。很多新手喜欢攒一大堆代码再一次性提交结果出了问题根本不知道是哪次改动引入的。正确的做法是每完成一个小的功能点就提交一次。提交信息写得稍微具体一点未来排查时你一定会感谢当初的自己。第四个是 Mac 上如果换了电脑一定要记得把旧的 SSH 私钥迁移过去或者在 GitHub 上加入新电脑的新公钥。我见过有人因为换了电脑无法推送折腾一整天才发现是 SSH 没配置。7.2 本地好习惯提交信息的规范与频率不要小看提交信息它代表你代码历史的“可读性”。建议遵循一种类似约定式提交的写法第一行用一个动词开头比如feat:、fix:、docs:、refactor:后面跟一句简洁的中文或英文描述。例子feat: 增加用户注册功能fix: 修复并发支付时的金额重复计算问题docs: 更新README中的安装步骤这种规范的好处是之后如果用工具自动生成变更日志很容易实现。即使项目很小这种习惯也能让你很快定位到具体的改动。关于提交频率我个人的建议是“高频但粒度小”。你可能一天提交 5 到 10 次这完全正常。每个提交都应该是独立且可运行的不要留下“改了一半无法运行”的中间态提交。这样团队其他人想用它来调试或回滚都会很舒服。7.3 下一步继续深入哪些方向这篇教程覆盖的是 Mac 上 Git 和 GitHub 使用的最核心闭环。你掌握了这些已经可以应付绝大多数日常开发场景。接下来如果还想继续深入可以从这几个方向选一个作为切入点。第一件是学习 Pull Request 的工作流。这不是 Git 命令本身而是团队协作的重要方式。你可以尝试在自己或别人的仓库中发一个 PR实践下 code review 流程。第二件是理解.gitignore的那些高级写法比如如何忽略特定目录例外、如何忽略已跟踪文件、全局 gitignore 的配置等。这一块没有太多深奥的规则但非常实用。第三件是探索 GitHub 的 Actions 功能把自动化测试、自动部署跑起来。它们背后依然离不开 Git 的操作逻辑但是把 Git 的能力从“版本管理”延伸到了“协作自动化”。第四件是把目光转向 Git 的高级操作比如revert与reset的差别、cherry-pick的用法、子模块的管理。这些东西不是每天都需要用但一旦遇到就能避免大量返工。一路学下来你会发现Git 不是一门需要背语法、刷题的知识而是一种工作习惯。命令就那么多真正的成长来自于每天使用时的直觉判断什么时候该提交、什么时候该开分支、什么时候该去拉取最新代码。坚持用上两周这些操作就会像呼吸一样自然。
阅读完成 · 觉得有帮助?