☰
Mac下Git与GitHub入门:安装配置到日常使用的完整教程
2026/10/20 21:05:34 网站建设 项目流程

开篇先交代一下背景。我在 Mac 上第一次正经用 Git,不是自己主动学的,而是被一个改了三天的 bug 逼的。那会儿项目代码全在一个压缩包里传来传去,某同学改完丢回来,我解压一看,函数名变了,逻辑改了一半,注释也没了。来回折腾一星期,我连谁改的、改了什么都说不清。后来被逼着用了 Git,才发现版本管理这件事,解决的不是"存代码",而是"让团队协作不打架"以及"让每一个改动都有据可查"。

这个标题写的是"MAC下Git和Github的使用",看起来是个入门题,但实际踩过坑的人都知道,Mac 环境下 Git 的坑一点不比 Windows 少:终端命令不兼容、换行符问题、SSH 密钥加载失败、Homebrew 安装路径找不到……每一件都能让人卡半小时。这篇教程我不打算讲空泛的理论,就按"装好→配好→推上去→日常用→踩坑排查"这条线一路走下来,把我自己的操作过程和踩过的坑原样写出来。适合刚接触 Git 的新手,也适合那些"用过但从来没搞懂自己在干嘛"的同学。

1. 为什么在 Mac 上要专门聊聊 Git

先强调一个很多人混淆的概念:Git 和 GitHub 是两个东西。Git 是一个分布式版本控制系统,是你电脑上的一个工具,负责记录代码的快照、追踪每一行改动、管理分支合并。GitHub 是建立在 Git 之上的远程代码托管平台,你可以把本地仓库推上去,当作云端的备份,也可以和别人协作。类比一下,Git 是本地游戏存档系统,GitHub 是云端同步盘,两者配合使用,缺一不可。

那为什么标题要专门强调 Mac?因为 Mac 的底层是类 Unix 系统,终端默认是 zsh/bash,很多命令行为习惯跟 Windows 的 PowerShell 完全不是一个路子。比如换行符,Windows 默认是 CRLF,Mac 和 Linux 是 LF,如果两边不加配置直接互推代码,你会发现 Git 认为每一行都被修改了,diff 里全是红的。再比如 SSH 密钥,Mac 有单独的 keychain(钥匙串)机制,配置不好经常会出现连接时明明密钥存在却报 Permission denied。网页上的教程大多数以 Windows 为例,很多命令在 Mac 上要么参数不同,要么根本不存在,照着抄很容易翻车。

另外还有一个现实因素:不少做前端、iOS、后端开发的同学,公司发的电脑就是 MacBook。你在终端里敲的每一条命令,将来都要用在真实项目上。所以用 Mac 学 Git,不光是"能跑通",更要理解每一步在干什么,尤其是和系统相关的配置,才不至于换个机器就抓瞎。

这篇教程默认你已经有一个 GitHub 账号,不涉及注册流程,如果还没有,先去注册一个,免费版够用了。下面所有命令,我建议你一边看一边打开终端跟着敲,光看是学不会的,这是我最真实的体会。

2. 在 Mac 上安装 Git:三种方式,我推荐这么选

Mac 上安装 Git 不是只有一个途径,我试过好几种,各有各的坑。这里把常见的三种方式都列出来,附带对比,你自己按情况挑。

2.1 方式一:Xcode Command Line Tools,最省事但不一定最新

如果你只是偶尔用一下 Git,最简单的方式是安装 Xcode Command Line Tools。打开终端,输入:

xcode-select --install

系统会弹出一个图形界面,点击安装就行。这个工具包不光带 Git,还带 gcc、make 等一堆编译器工具,很多开发环境都会依赖它。安装完 Git 就能用了:

git --version

这种方式的好处是零成本、跟系统集成度高,不需要额外维护。缺点是版本固定,除非你升级 macOS 或者单独更新 Command Line Tools,否则 Git 可能一直停留在某个旧版本。旧版本本身也能用,但如果你需要体验新特性,或者遇到某些和版本相关的 bug,就有点尴尬了。

2.2 方式二:Homebrew 安装,我最推荐的方式

Homebrew 是 Mac 上的包管理器,官方叫法"macOS 缺失的包管理器"。如果你之前装过 Node、Python 之类的开发环境,大概率已经装了 Homebrew。确认一下:

brew --version

没装的话,去官网复制安装命令,或者在终端执行(注意,这个命令会要求你输入密码):

/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"

然后安装 Git:

brew install git

安装完成后额外执行一句:

brew link --force git

我推荐 Homebrew 的核心原因是版本新、更新方便。以后想升级,一句brew upgrade git就解决了。对于开发频繁、需要和团队保持同一 Git 版本行为的场景,这个优势很明显。缺点是要先装 Homebrew,多一层依赖,但 Homebrew 本身也是 Mac 开发者的标配工具,装了不亏。

2.3 方式三:官网下载安装包,不推荐但有存在价值

Git 官网提供 Mac 版安装包(dmg 格式),下载、双击、安装,和装普通软件一样。这种方式适合不想碰命令行的纯新手,但你迟早要面对终端,还不如一开始就适应。它的缺点比较突出:升级要重新下载安装包,安装路径和 Homebrew 版本可能冲突,which git出来的路径不直观,时间一长版本就落后了。

三种方式简单做个对比:

安装方式难度版本新鲜度升级方式适用人群
Xcode Command Line Tools最简单较旧随系统/手动偶尔使用、已装Xcode
Homebrew中等最新brew upgrade git常规开发者,推荐
官网dmg安装包简单中等手动下载重新安装不碰命令行的新手

安装完成后,验证一下:

git --version which git

which git可以看 Git 实际装在哪。这里提醒一个坑:如果你之前用 dmg 装过 Git,又用 Homebrew 装了一次,git --version显示的可能是旧的那个。这时候用brew link --overwrite git强制替换,或者检查 PATH 的顺序,别让两个版本同时存在,否则后面会出现一些莫名其妙的问题。

3. 第一次使用 Git 前,必须配置的三件套

很多新手装完 Git 就直接git add、git commit,结果 commit 报错,名字邮箱没配置。或者配置了,但名字是乱打的,到团队协作时别人根本不知道这段代码是谁写的。这一节讲的配置,属于"一次配置,终身受益"的事情,我建议你花两分钟全部做好。

3.1 用户名和邮箱:提交记录里的身份证明

先说我见过的一个真实场景:某同学提交代码时,GitHub 头像一直不显示,提交记录里显示的是"yourname",团队里所有人都不知道那是谁。查了半天,发现他当时图省事,随便输了一个用户名。版本控制里,每一个 commit 都绑定一个身份,这个身份就是user.name和user.email,不是你注册 GitHub 时的登录邮箱,而是你希望展示在提交记录里的身份。

设置命令:

git config --global user.name "你的名字" git config --global user.email "你的邮箱"

--global表示全局配置,对当前用户的所有仓库生效。如果你针对某个项目想用不同的身份,在该项目目录下执行同样的命令,去掉--global即可,局部配置会覆盖全局配置。

验证配置:

git config --list

这里有个非常重要的细节:user.email最好用注册 GitHub 的那个邮箱,这样提交记录能正确关联到你的 GitHub 账号。否则代码推上去,你的 commit 在 GitHub 上显示为一个灰色的小人,没有头像,没有主页链接,强迫症表示很难受。

3.2 SSH 密钥:和 GitHub 之间的安全通道

Git 和 GitHub 之间有两种传输协议,HTTPS 和 SSH。HTTPS 每次操作都要输入账号密码,现在 GitHub 出于安全考虑,已经不允许直接用密码操作了,要用 Personal Access Token,挺麻烦的。SSH 则是一种公钥加密认证方式,配置一次之后,连接时不需要输密码,而且更安全。

生成密钥的命令:

ssh-keygen -t ed25519 -C "你的邮箱"

这个命令会在~/.ssh/目录下生成一对密钥:id_ed25519(私钥,自己留着,千万别给别人)和id_ed25519.pub(公钥,可以添加到 GitHub)。中间会提示你设置密码短语(passphrase),我建议设置一个,虽然每次连接时要输一次,但私钥安全性大幅提升。担心麻烦、只是个人学习使用的话,也可以直接回车留空。

然后查看公钥内容:

cat ~/.ssh/id_ed25519.pub

复制输出的那一串以ssh-ed25519开头的字符串,打开 GitHub 网站,进入 Settings → SSH and GPG keys → New SSH key,粘贴保存。

测试是否配置成功:

ssh -T git@github.com

如果看到类似Hi 你的用户名! You've successfully authenticated...的输出,就说明通了。我第一次测试时看到这个提示,瞬间觉得仪式感拉满,后面凡是遇到连接问题,第一反应就是先跑这个命令。

3.3 换行符:Mac 和 Windows 协作最容易踩的隐形坑

换行符这个问题,不遇到则已,遇到就非常头大。Windows 的换行符是CRLF(回车+换行,\r\n),而 Mac 和 Linux 是LF(换行,\n)。如果你在一个 Windows 同事和 Mac 同事混合的团队工作,没有统一换行符规则,Git 会认为每一行代码都变了,diff 结果惨不忍睹,merge 时冲突乱成一锅粥。

Mac 下的推荐配置:

git config --global core.autocrlf input

这个配置的含义是:提交代码时把CRLF转换成LF,拉取代码时不做转换,保持仓库内统一使用LF。因为仓库本身推荐用LF,Mac 本地也不需要CRLF,所以设置为input就够了。

如果你是新项目,我更建议直接在仓库根目录加一个.gitattributes文件,这是更彻底的解决方案:

* text=auto *.sh text eol=lf *.bat text eol=crlf

.gitattributes是仓库级的规则声明,比个人配置更权威,团队每个人都生效,不管他是什么系统。这个文件加入版本控制之后,Windows 同事、Mac 同事、Linux 同事都不用额外配置,换行符问题从源头解决。

4. 和 GitHub 建立连接:HTTPS 和 SSH 怎么选

连接 GitHub 的方式,本质上是在解决"每次 push 要不要输密码"的问题。很多教程一上来就让你用 HTTPS,然后告诉你输了密码之后 Git 会记住,但实际体验往往没那么顺利,尤其是 GitHub 开始强制使用 token 之后,HTTPS 的操作路径变得很繁琐。

先看对比:

连接方式首次配置日常操作安全性适合场景
HTTPS + Token需要生成token每次输token/缓存较高临时贡献、偶尔提交
SSH配置密钥一次无需密码高日常开发、长期使用

我的建议很明确:日常开发一律用 SSH。理由不只是不用输密码,而是 SSH 的密钥机制在团队中更可控。你在某个公司工作,离职时只需要从 GitHub 删掉对应密钥,就不用担心之前授权过的 token 还留在旧电脑上。而 HTTPS token 如果泄漏,对方可以用它推送恶意代码,很长一段时间你都发现不了。

如果你确实想用 HTTPS,记住现在的"密码"不是你的登录密码,而是 Personal Access Token。生成路径:GitHub Settings → Developer settings → Personal access tokens → Tokens (classic) → Generate new token。然后配置 Git 记住这个 token:

git config --global credential.helper osxkeychain

这个配置会把凭证存进 Mac 的钥匙串,第一次输入之后后续自动填充。但坦白讲,如果你已经走了 SSH 这条路,根本不需要这么麻烦。

SSH 建立连接的关键步骤前面已经写过,这里补充两个容易忽略的点。第一个,如果之前生成过密钥,但换了新电脑,新的公钥要重新加到 GitHub,旧电脑的私钥不能再当免死金牌。第二个,ssh -T git@github.com时如果遇到 host key 验证提示,输入yes确认即可,不要手滑输入no,否则连接会被拒绝。

5. 把本地项目推到 GitHub:一次完整的实操演示

理论讲再多,不如完整走一遍流程。这一节我用一个模拟项目 X 来演示,从 GitHub 建仓库开始,到最后本地代码成功推上去。

5.1 在 GitHub 上创建一个仓库

登录 GitHub,点击右上角加号 → New repository。仓库名建议全小写英文,用连字符分隔单词,比如my-blog,不要用中文,不要有空格,否则后面 URL 一堆转义编码根本没法看。可以加一个简单的 Description(描述),帮助你以后快速识别这个仓库是干嘛的。

关于初始化选项,我建议把 "Add a README file" 勾上。README 是仓库的门面,别人的项目首页展示的就是它。很多新手图省事不勾,推送代码后发现仓库空空如也,也没有说明文字,观感上是扣分的。.gitignore模板也顺手选一下,比如你用的是 Node.js,GitHub 会根据模板自动生成忽略node_modules等目录的规则,这一步能帮你避免把依赖目录推上去的悲剧。

5.2 本地初始化并关联远程仓库

打开终端,进入你的项目目录:

cd /path/to/your/project

然后初始化 Git 仓库:

git init git add . git commit -m "Initial commit"

git init会在当前目录生成一个隐藏的.git文件夹,Git 的版本记录全部存在这里面。注意,如果你项目目录已经处于某个 Git 仓库里,git init是不必要的,你先用git status看看再决定。git add .是把当前目录的所有改动加入暂存区,git commit则是把这批改动固化成一个版本快照。这两个命令的顺序很重要,你要理解它们是两个不同的动作,add 是"把东西装进篮子",commit 是"把篮子封箱存档",不要混着说。

5.3 添加远程地址并推送

在 GitHub 仓库页面,会看到远程地址。选择 SSH 格式,一般是:

git@github.com:你的用户名/仓库名.git

本地执行:

git remote add origin git@github.com:你的用户名/仓库名.git git branch -M main git push -u origin main

解释一下这三条命令。git remote add origin是给远程仓库起一个别名,约定俗成叫origin,以后你就不用记那串长长的 SSH 地址,直接说origin就行。git branch -M main是把当前分支重命名为main,GitHub 默认主分支叫main,而你本地默认可能是master,不统一的话推送分支会不一致。git push -u origin main第一次推送时需要-u参数,它建立本地分支和远程分支的追踪关系,以后直接敲git push就能推送,不用再带分支名。

完整流程跑完之后,刷新 GitHub 仓库页面,代码应该已经躺在上面了。

5.4 推送失败的常见场景:本地和远程历史不一致

第一次推送最常见的报错长这样:

error: failed to push some refs to 'git@github.com:...' hint: Updates were rejected because the remote contains work that you do not have locally.

原因是远程仓库里有你本地没有的提交,比如你在 GitHub 网页上勾选了 README 和 .gitignore,又在本地的第一次 commit 创建了项目文件,两边各自有了独立的提交记录。Git 拒绝直接推送,是怕你覆盖掉远程的历史。解决方案是先把远程历史拉到本地合并:

git pull origin main --allow-unrelated-histories

--allow-unrelated-histories这个参数允许两个没有共同祖先的分支合并,典型场景就是本地仓库和远程空仓库里各自有初始提交。合并之后如果有冲突,解决冲突然后 commit,再 push 就行。我个人经验是,最简单的办法其实是在 GitHub 建仓库时啥都不勾选,建一个空仓库,然后本地推送,就不会有这个问题。但 README 和 .gitignore 确实有存在价值,所以要么仓库建好后再去本地 pull 一次,要么就接受第一次推送需要处理合并的事实,看你怎么取舍。

6. 日常开发中最高频的 10 个 Git 命令

这一节是把你从"会用 Git"推向"用 Git 干活"的过渡。这里不追求完整语法,覆盖日常开发里 90% 的场景就够了。每个命令我都配了适用场景和我的使用习惯。

git status

查看当前工作区的状态:哪些文件被修改了、哪些文件还没被跟踪。我几乎每次操作前都会跑一遍,它只需要 0.1 秒,但帮你避免了很多"我明明改了为什么没提交"的疑问。

git log --oneline --graph

查看提交历史,--oneline让每条记录只显示一行摘要,--graph用字符画展示分支合并路线。看这个输出你就能了解项目的演进脉络。新的 Git 版本还支持git log --all --decorate --graph --oneline,信息更全。

git add -A

把工作区所有改动加入暂存区。相比git add .,-A还会处理文件删除的情况,更省心。使用习惯上,我喜欢在提交前git status看一眼,确认没有意外文件被加进去,再执行最终 add 和 commit。

git commit -m "描述这次改动的目的"

提交要遵循一个原则:每个 commit 只做一件事,描述要能让人看懂。比如"修复登录页在Safari下样式错乱"就很好,"update"就属于无效信息。团队协作时,commit message 是别人理解你思路的最快路径。

git branch

查看当前仓库所有分支,当前所在分支前会有一个星号。分支是 Git 最强大的功能,相当于平行时空,你可以在不同的分支上开发互不影响。

git checkout branch-name # 或者新版写法 git switch branch-name

切换分支。新版 Git 推荐git switch,语义更清晰。切换前留意工作区有没有未提交的改动,否则可能把未完成的修改带到另一个分支上。

git merge branch-name

把某个分支的提交合并到当前分支。这是团队协作中最常用的合并方式,实际使用时经常要先git switch main切回主分支,再执行 merge。

git pull

拉取远程仓库的更新并自动合并到当前分支。它相当于git fetch+git merge的组合。要特别注意的是,如果有未提交的本地改动,pull 时可能产生冲突或拒绝操作,重要工作前建议先 commit 或 stash。

git push

推送本地提交到远程。如果你设置了-u追踪关系,不带参数也能推。推送之前先git pull同步一下别人的改动,能显著减少冲突。

git stash

暂存当前未提交的改动,把工作区临时恢复到干净状态。这个命令在紧急切换分支时是救命的:你正在 A 分支开发一半,突然要去 B 分支修一个线上 bug,又不想提交半成品,直接在 A 分支git stash,切到 B 分支修完,再切回来git stash pop恢复。我用这个命令的次数可能比我用git merge还多。

7. 我踩过的坑:常见问题排查实录

最后一个部分,也是我觉得这篇最有价值的部分。这些问题不全是我一个人的经历,有的是帮同事排查时遇见的,但都很典型,列成一份速查表,你以后遇到了按图索骥就行。

7.1 每次 push 都提示输入用户名密码

如果你用的是 HTTPS 地址,又没配置凭证缓存,那每次 push 都输一遍纯粹是浪费时间。解决思路有两个:一是改用 SSH 方式,重新添加origin远程地址;二是配置 macOS 钥匙串缓存凭证:

git config --global credential.helper osxkeychain

我个人推荐前者,一劳永逸。如果你项目里已经用 HTTPS 克隆的,可以这样切换:

git remote set-url origin git@github.com:用户名/仓库名.git

7.2 连接时报 Permission denied (publickey)

这是 SSH 配置里最常见的错误。排查顺序是这样的:先测连通性ssh -T git@github.com,看到 Permission denied 说明密钥没配对。然后确认本地密钥是否加载:

ssh-add -l

如果输出The agent has no identities.,说明密钥没加入 SSH agent,执行:

ssh-add ~/.ssh/id_ed25519

最后确认公钥是否真的添加到了 GitHub。一个很容易被忽略的细节:你之前添加公钥的时候,可能不小心复制了私钥内容,或者复制的时候漏了几个字符,都会导致认证失败。重新复制公钥、重新添加一次,往往能解决。另外别忘记检查文件权限,~/.ssh目录权限不能太开放,否则系统会拒绝使用密钥:

chmod 700 ~/.ssh chmod 600 ~/.ssh/id_ed25519

7.3 中文文件名显示成八进制乱码

Mac 终端默认拿 UTF-8 显示中文,但 Git 出于兼容性考虑,默认会把中文文件名的非 ASCII 字符转义成\346\226\207\344\273\266之类的乱码。解决办法:

git config --global core.quotepath false

配置之后,git status就能正常显示中文文件名了。

7.4 不小心把 .env 或 node_modules 推上去了

这是新手最容易犯的错误,也是后果比较严重的错误。.env里通常有数据库密码、API 密钥,推上去等于公开了。如果你已经推送过,马上处理:先把这个文件加进.gitignore,然后从 Git 历史中彻底移除。比较简单的做法:

git rm --cached .env

这个命令会把文件从 Git 追踪中移除,但保留本地文件。加上 .gitignore 规则后 commit 并 push。注意,你之前推送过的历史记录里还躺着这份文件的内容,如果没有敏感信息泄露的风险,仅仅删除后续版本可能就够了;如果里面真有密钥,更妥当的做法是立刻去对应平台改掉密码、换掉密钥,因为历史记录里的内容已经很难彻底抹除。这就是为什么我反复强调,git add之前一定git status,看清楚每个进入暂存区的文件。

7.5 合并分支时的冲突

冲突是 Git 使用中最让人抓狂的场景,但也是完全正常的现象。冲突发生时,Git 会在冲突文件里插入标记:

<<<<<<< HEAD 当前分支的内容 ======= 合并进来的分支的内容 >>>>>>> feature-branch

你需要手动打开文件,把不需要的内容删掉,保留需要的,删掉那些<<<<<<<、=======、>>>>>>>标记,然后重新 add 和 commit。很多初学者看到冲突第一反应是退回去,其实冲突的本质是两个人改了同一块代码,只要你不是覆盖了别人的逻辑,解决起来并不难。我的建议是:多和对方沟通,确认哪段代码是最终的逻辑,别擅自决定、把别人的功能删了还不吭声。

最后整理一份常见问题速查表,方便你以后查阅:

问题现象优先排查点解决方案
每次push都要密码远程是HTTPS地址改用SSH或配置凭证缓存
Permission denied (publickey)密钥是否加载、公钥是否已添加ssh-add、重新添加公钥
pull时不想提交当前改动工作区有未保存修改git stash / git stash pop
中文文件名乱码转义显示core.quotepath false
误提交敏感文件.gitignore未生效git rm --cached、更新.gitignore
本地和远程历史不一致双方均有commitgit pull --allow-unrelated-histories
合并冲突双方改了同一区域手动解决冲突后commit

写在最后

我在实际使用中最大的体会是,Git 不是拿来"学"的,是拿来"用"的。你不需要把每个底层原理都搞清楚才能开始,我一开始连暂存区和工作区的区别都说不明白,照样把代码推上去了。真正让我成长的,是每天在终端里反复敲那几条命令,遇到报错就搜索、就排查、就记录,犯了几个"把敏感文件推上去"和"merge 时把别人代码覆盖掉"的错误之后,才开始慢慢理解版本管理的核心逻辑:可追溯、可回退、可协作,这六个字比任何命令都重要。Mac 环境的特殊性主要集中在前面的安装、换行符、SSH 这几个点上,把这些配置一次搞定,后面的体验并没有想象中那么困难。这篇是系列第一篇,之后我计划继续写分支管理和团队协作中的 Git 策略,比如 Git Flow 的实际落地、rebase 和 merge 的取舍、以及如何写好 commit message,希望这些内容能对你有所帮助。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询