1. 环境准备与初始配置
1.1 安装 Git:Windows、macOS、Linux 三平台实操
先说安装。Git 本身是一个命令行工具,无论你用的是 Windows、macOS 还是 Linux,安装方式都不太一样,但核心思路是一样的:装好之后,你只是在本地多了一个"版本管理引擎",它不会主动干扰你的文件,只有你执行git init或git clone之后,它才开始在一个特定目录里接管版本历史。
Windows 上安装
Windows 用户最常遇到的问题是"装哪个版本"。我建议直接去 Git 官网下载 Windows 版本的安装包,也就是Git for Windows。这个东西自带一个模拟 Linux 终端的环境,叫做Git Bash,很多初学者第一次打开它可能会有点懵——它的命令风格和 CMD 不一样,比如路径分隔符是/c/Users/xxx而不是C:\Users\xxx。但别慌,这恰恰是好事,因为 Git 的绝大多数命令和脚本都是基于 Linux 风格设计的,用Git Bash可以避免很多莫名其妙的坑。
安装过程中有几个关键选项需要注意,我列一下我的推荐配置:
- 选择编辑器:如果装了 VS Code,就选 VS Code;如果没装,选 Vim 也行,反正后面可以用
git config --global core.editor随时改。 - 调整 PATH 环境:选"Git from the command line and also from 3rd-party software",这样你可以在 Windows 自带的 CMD 和 PowerShell 里直接敲
git命令,更灵活。 - 换行符处理:这一项很关键,建议选"Checkout as-is, commit as-is",避免 Git 自动帮你把 LF(Unix 换行符)转成 CRLF(Windows 换行符)引发一堆格式问题。团队协作时如果大家系统不一致,换行符问题会搞得非常头疼,后面我会在疑难杂症章节详细说。
macOS 上安装
macOS 用户最简单的方式是通过 Homebrew 安装:brew install git。如果你已经装了 Xcode Command Line Tools,系统可能自带一个旧版 Git,建议还是用 Homebrew 装新版,因为旧版在某些场景下会有兼容性问题。
Linux 上安装
Debian/Ubuntu 系列用sudo apt install git,CentOS/RHEL 系列用sudo yum install git。装完之后先验证一下:git --version,如果能看到版本号,说明安装成功。
1.2 初始化仓库与全局配置:先设置"你是谁"
安装完成后,第一件事不是急着git init,而是先设置你的身份信息。这个步骤经常被忽略,但非常关键,因为 Git 的每一次提交都会记录作者信息,如果你没设置,提交时会报错或者生成一串无意义的默认名称,后续代码审查和贡献统计都会乱套。
git config --global user.name "你的名字" git config --global user.email "你的邮箱"这两条命令是把身份信息写入全局配置文件(Windows 下是C:\Users\你的用户名\.gitconfig,Linux/macOS 下是~/.gitconfig)。所谓"全局",意味着这台机器上所有 Git 仓库默认都用这个身份。如果你在不同的项目里要用不同的身份(比如工作电脑上区分公司和私人项目),可以在具体仓库目录下执行不带--global的同样的命令,覆盖全局设置。
设置完之后,可以执行git config --list查看当前所有配置,确认信息无误。
做完身份配置,就可以初始化一个仓库了:
mkdir my-project cd my-project git init执行完git init后,目录下会生成一个隐藏的.git文件夹,这里存放着仓库的全部元数据、提交历史、分支指针等等。注意,这个文件夹一旦损坏,你的版本历史可能就没了,所以平时不要手动去改里面的文件。
2. 日常核心操作:从add到commit再到log
2.1 基本工作流:status、add、commit、log
当你创建了一个新文件或者修改了某个文件之后,Git 并不会自动记录变化,你需要手动告诉它"我要跟踪哪些变化"。这就是 Git 的阶段(staging area)机制,也是很多新手卡壳的地方。
Git 的日常操作可以理解成三个区域:工作目录(Working Directory)→ 暂存区(Staging Area)→ 版本库(Repository)。你的修改先落在工作目录,然后通过git add把修改放入暂存区,最后通过git commit把暂存区的内容生成一个不可变的版本快照存入版本库。
我先给你一个标准工作流的示例:
# 查看当前仓库状态,它会告诉你哪些文件被修改了、哪些还没被跟踪 git status # 添加指定文件到暂存区 git add src/main.py # 或者添加所有改动(但要注意,这会连同删除和新增一起加进去) git add . # 提交到版本库,并附带提交说明 git commit -m "feat: 新增用户登录接口" # 查看提交历史 git log --oneline --graph --decorate这里有两个我非常想强调的细节。
第一个是git status的重要性。很多人(包括我早期)习惯直接git add . && git commit -m "...",一条龙操作下来感觉很快,但这样很容易把不该提交的文件(比如本地配置文件、密钥文件、临时文件)一起提交进去。我个人建议每次提交前都先看一遍git status,花 10 秒钟确认一下,尤其是团队协作的项目里,这 10 秒能避免很多尴尬。
第二个是 commit message 的规范。我见过太多 "update"、"fix"、"123" 这种毫无信息量的提交说明,三个月后回看历史,根本不知道当时改了什么。推荐使用 Conventional Commits 规范,简单来说就用这几个前缀:
feat:新功能fix:修复 bugdocs:文档调整style:格式调整refactor:重构test:测试相关chore:构建任务或工具变动
一条好的提交信息应该能让人不看代码也能理解这次改动的意图。
2.2 修改提交:git commit --amend的正确打开方式
热词里有git commit --amend怎么使用,这确实是一个高频疑问,因为很多人都在错误地使用它。
git commit --amend的作用是"修改最近一次提交"。它能干两件事:
- 修改最近一次提交的说明信息
- 把当前暂存区的新改动合并进最近一次提交,而不是生成一次新提交
先看修改提交说明的用法。假设你上一次提交信息写错了,或者信息不够完整:
git commit --amend -m "fix: 修复用户模块空指针问题"执行完以后,最近一次提交的 message 会被替换成新的,提交的哈希值(SHA)也会发生变化,因为这个提交的内容变了。
再看合并暂存区改动的用法。假设我刚刚写了一版代码提交了,然后发现漏了一个小文件或忘记加一个关键改动,这时候我只需要:
git add 遗漏的文件 git commit --amend --no-edit--no-edit的意思是:保持现有的提交说明不变,只是把新改动合并进去。这在开发过程中很实用,比如你刚提完"修复某 bug",马上发现代码里还有个注释没改,用这个命令就能让修复本身保持一个干净的单次提交。
但是,这里有一个绝对的红线:不要 amend 已经推送到远程分支的提交。
为什么?因为git commit --amend本质上是"丢弃旧提交、创建新提交"。如果旧的提交已经被别人 pull 下来用了,你这边把历史改写了,对方下次 pull 的时候就会遇到历史分叉甚至冲突。在多人协作的公共分支上执行 amend 和 rebase -i 这类改写历史操作,基本属于"自爆行为"。一旦推送到远程,就老老实实新增一个提交来修复,别想着改历史。
2.3 版本回退:reset与revert怎么选
"要不要回退代码"是每个开发者都会遇到的问题,而git reset和git revert是两种常用的回退方式,选择不对会把你坑惨。
先说git reset,它是把当前分支的 HEAD 指针挪到历史某一次提交上,有三种模式:
--soft:只移动 HEAD 指针,暂存区和工作目录都不动--mixed(默认):移动指针,把回退提交之后的改动放到工作目录,暂存区清空--hard:丢弃所有改动,工作目录、暂存区、指针全部回退到指定提交
比如你连续提交了三次,发现第二次提交引入了 bug,想直接丢弃第二次和第三次提交:
git reset --hard HEAD~2注意,HEAD~2表示当前提交往上数两个提交。--hard比较暴力,回退之后所有未提交的改动都没了,想找回只能靠git reflog(后面讲)。所以执行reset --hard前,我强烈建议先确认有没有没保存的改动。
再说git revert,它的操作不是移动指针,而是生成一次新的提交,反向应用目标提交所引入的改动。举个例子:
git revert 92a3f6d这会把92a3f6d这次提交的改动"撤销"掉,然后生成一个新的提交记录,就像告诉你的队友:我承认之前的改动有问题,现在我用一次新提交把它还原了。
那到底怎么选?我直接给一个简化版的决策表:
| 场景 | 推荐操作 | 原因 |
|---|---|---|
| 本地提交未推送,想回退 | git reset | 干净利落,不会污染历史 |
| 已推送到远程的提交出错 | git revert | 不改写已公开历史,队友不会冲突 |
| 只是想临时试一下旧代码 | git checkout/git switch | 不动当前分支状态 |
| 提交信息写错了、没推送 | git commit --amend | 合并修正,不留多余记录 |
| 分支合并错了、已推送 | git revert -m 1 | 回退合并提交并保留历史 |
git revert -m 1里这个-m 1是针对合并提交(merge commit)的,意思是"保留第一个父分支,撤销合并对它的影响",这个参数在回退合并操作时几乎必用,要记下来。
3. 远程仓库与分支协作
3.1 远程仓库操作:remote、clone、push、pull
本地仓库搞清楚了,下一步就是和远程仓库(比如 Gitee、GitHub 或公司内网的 GitLab)打交道。
首先要把本地仓库关联到远程仓库。如果你是从零开始的本地项目,需要先在远程平台创建一个空仓库(不要勾选"初始化 README"),然后执行:
# 关联远程仓库,origin 是习惯性的默认名字 git remote add origin git@github.com:你的用户名/my-project.git # 推送本地 master 分支,并设置上游关联 git push -u origin master-u参数很重要,它的全称是--set-upstream,意思是建立本地分支和远程分支的追踪关系。设置过之后,后面再执行git push或git pull就不用每次都带完整的分支名了。
如果你是从远程拉取项目开始:
git clone git@github.com:你的用户名/my-project.git注意clone和remote add的区别:clone是完整复制远程仓库到本地,包括分支、标签、历史;remote add只是给本地已有的仓库加一个远程地址引用。
推送和拉取是高频操作,但有几个细节容易出问题:
- 先 pull 再 push:多人协作时养成习惯,push 前先 pull 最新的远程改动。如果你本地的提交和远程提交在同一个位置分叉了,Git 会拒绝 push,要求你先合并最新内容。
- pull 的隐含合并:
git pull等同于是git fetch+git merge。如果你在意合并方式的高效,可以配置git pull --rebase,这种方式会用重新变基的方式把你的本地提交"铺"到远程最新提交之上,历史更线性,但需要注意不能在有冲突未解决时中断 rebase。 - 推送时提示 non-fast-forward:这是最常见的错误之一。意思是远程分支领先于你本地分支,需要先 pull。如果你是唯一开发者且确定要覆盖远程,可以用
git push --force;但在共享分支上,绝对不要对共享分支使用--force,这是最高危操作排行榜前三名。
3.2 分支管理:branch、switch、merge以及热词里的"从 master 剪切到 dev"
分支是 Git 最强大的功能,本质上它只是一条可移动的指针,指向某次提交。创建分支的成本极低,所以推荐的做法是:宁可多建临时分支,也不要所有改动都堆在 master 上。
热词里有一条特别典型的问题:"我在 master 上写的代码怎样剪切到 dev 上?"
这个问题很多人遇到,场景大概是:你在 master 上改了一堆代码,然后发现其实应该在 dev 分支上开发。操作其实很简单,技术上讲就是"把当前未提交的改动带到另一个分支去"。
# 先确定当前改动是已提交还是未提交 git status # 情况一:改动已经提交到 master # 1. 切换到 dev 分支,并把 master 的提交 cherry-pick 过来 git switch dev git cherry-pick master # 或者用具体的提交哈希 # 2. 回到 master 分支,把那个提交移除 git switch master git reset --hard HEAD~1 # 情况二:改动还没有提交 # 直接把工作目录的改动"搬运"到 dev 分支 git stash git switch dev git stash pop这里用到了两个重要的工具:cherry-pick和stash。
git cherry-pick <commit-hash>可以把任意一个提交的改动应用于当前分支,并生成一个新的提交。它是跨分支"提取改动"的利器,但要注意:如果目标改动依赖其他没有带过来的提交,可能会产生冲突。
git stash则是临时把当前工作目录的改动"藏"起来,让目录回到干净状态。稍后你可以切换分支,再用git stash pop恢复改动。这个命令在频繁切换分支时特别实用。
分支合并也是热词里的重点。最标准的分支合并流程是:
# 先切到目标分支(你想把改动合并到的分支) git switch dev # 拉取 dev 最新的远程状态 git pull origin dev # 把 feature 分支合并进来 git merge feature/my-new-feature # 如果有冲突,解决后执行 git add 冲突文件 git commit # 生成合并提交在git merge过程中,如果两个分支改了同一个文件的同一行,Git 会停下来告诉你冲突了。这时候你需要手动编辑文件,Git 会在冲突位置留下类似这样的标记:
<<<<<<< HEAD 当前分支的内容 ======= 被合并分支的内容 >>>>>>> feature/my-new-feature你需要逐个人工决定保留哪边的代码,然后把<<<<<<<、=======、>>>>>>>这些标记删掉,再git add和git commit收尾。新手面对冲突会慌,但说实话,冲突是 Git 里最正常的现象,处理多了以后,你反而会通过冲突位置迅速定位两边的改动逻辑。
3.3fetch与pick:澄清常见的混淆点
热词里有 "git pick和fetch有什么区别"。这里多半是把cherry-pick里的 pickle 和fetch混淆了。
git fetch的作用是:从远程仓库拉取最新的提交、分支和数据,但不会修改你当前的工作目录。换句话说,它只是"下载最新信息到本地远程跟踪分支",你能通过git log origin/master查看远程的新提交,但你自己的分支不会变。
git pull则是fetch+merge的组合命令。所以如果你只想看看远程有什么变化但不想立即合并,用fetch;想立即同步,用pull。
cherry-pick则是"挑选用一个或几个提交"到当前分支。它和 fetch 完全是两码事,一个是拉取远程信息,一个是跨分支精选提交。日常工作中,"先 fetch 看变化,再决定要不要 merge"是很健康的习惯,因为pull有时候会静默地把你不想要的内容合并进来。
4. 进阶操作与疑难杂症排查
4.1.gitignore失效了怎么办?
热词里有一条 "git 的过滤文件 没有作用",这是非常典型的.gitignore陷阱。
.gitignore文件的作用是声明哪些文件或目录不被 Git 跟踪。但它只对"尚未被 Git 跟踪"的文件生效。如果你的文件之前已经被git add或git commit跟踪过,再往.gitignore里添加新的忽略规则,是无效的——因为 Git 已经在它的索引里追踪这个文件了。
举个例子,你的项目里有个config.ini文件,之前不小心提交了,现在你想忽略它,于是在.gitignore里加了config.ini,执行git status,发现它还是显示为已修改。这就是因为该文件已经在 Git 的索引里了。
解决办法是先停止跟踪,再启动忽略:
git rm --cached config.ini--cached参数的意思是:从 Git 索引中移除该文件的跟踪,但保留它在工作目录中的实体。执行完这个命令后,再把config.ini写入.gitignore,以后就不会再被跟踪了。如果是想清空整个目录的缓存跟踪,可以用git rm -r --cached .,然后重建索引。
另一个常见问题是.gitignore规则的语法。比如:
# 忽略所有日志文件 *.log # 忽略 build 目录 build/ # 忽略特定文件 .env # 不忽略某个特定文件(取反) !important.log注意,取反规则!important.log只能在它的父目录没有被忽略的前提下生效。如果整个logs/目录都被忽略了,那么!logs/important.log是不生效的。
4.2 无法提交大文件:Git 的默认上限与 LFS 方案
"git 无法提交大文件"这个热词通常出现在两种情况:一是文件超过 100MB,Git 直接报错;二是团队仓库因为大文件变得臃肿,每次 clone 都是噩梦。
先说 Git 报错的原因。Git 底层是快照式存储,每个提交都保存一份文件的完整副本,大文件频繁改动会急剧膨胀仓库体积。GitHub 的限制是单个文件超过 100MB 会拒绝推送,Gitee 也有类似的限制。而 Git 本身在操作大文件时性能也会大幅下降,因为压缩和 CRC 校验的成本都上去了。
真正合适的解决方案是 Git LFS(Large File Storage),它把大文件的内容替换成一个指针文件,实际内容存在独立的 LFS 存储中。简单用法:
# 安装 LFS 扩展(macOS 用 brew install git-lfs,Windows 安装包自带或单独下) git lfs install # 在仓库里声明要管理的大文件类型 git lfs track "*.psd" git lfs track "*.zip" # 提交 .gitattributes(LFS 跟踪规则会写进这个文件) git add .gitattributes git commit -m "chore: 添加 LFS 跟踪规则"这样以后新增的.psd和.zip文件都会走 LFS 路径,正常提交推送即可。
如果只是偶尔传一个大文件且没有频繁变动,另一个折中方案是调整 Git 的http.postBuffer:
git config --global http.postBuffer 524288000但这只是解决 HTTP 传输层的限制,治标不治本。
顺带提醒一句:不要把 node_modules、dist、target 这类生成目录提交进仓库。如果你发现仓库越来越大,用git count-objects -vH查看仓库体积,再考虑用git filter-repo清理历史。
4.3 目录泄露问题:如何安全下载与保护
"git目录泄露如何下载"这个热词在安全圈里经常出现。它指的场景是:网站部署时把.git目录暴露在了 Web 根目录下,导致任何人都可以通过访问网站域名/.git/获取到你所有源码的版本历史。
我要先说明白一个原则:利用目录泄露去获取别人的源码属于安全攻击行为,我不鼓励也不支持。但从防御角度理解这个问题,对开发者非常必要。
如果你觉得自己项目可能存在这个问题,可以用浏览器直接访问https://你的域名/.git/config试试,如果返回了文件内容,说明你的仓库泄露了。
防御措施很简单:
- 部署时确保
.git目录放在 Web 根目录之外,比如项目代码放在/var/www/app,Web 根目录指向/var/www/app/public。 - 如果必须放在根目录内,在 Web 服务器配置中显式拒绝访问
.git路径。Nginx 可以这样配:
location ~ /\.git { deny all; }Apache 则在.htaccess中加:
RedirectMatch 404 /\.git另外,如果你要清理已泄露到公网的敏感信息,不要把"删除提交"当成方案——因为提交历史里仍然有旧数据。你需要用历史重写工具(比如git filter-repo)彻底抹除,然后强制推送并更换所有密钥。
4.4 SSH 认证失败:从密钥到权限的完整排查
热词里 "ssh认证失败 git" 是一个让人抓狂的问题,因为它报错比较隐晦,常见的情况是:
Permission denied (publickey)还有 Git for Windows 下偶发的:
git open /dev/null or dup failed: no such file or directory先说后者,这个报错在 Windows 平台上出现,通常是因为 SSH 客户端在创建临时文件时出了问题,常见原因是环境变量GIT_SSH指向了一个不存在或损坏的 SSH 程序。解决方式是打开 Git Bash 执行:
unset GIT_SSH或者检查系统环境变量,把GIT_SSH指向正确的ssh.exe路径。
再说Permission denied (publickey),排查顺序应该是:
- 确认你用的是 SSH 地址而不是 HTTPS 地址。
git remote -v查看远程地址,以git@开头的才是 SSH 协议;以https://开头的是 HTTPS 协议,后者用 token 或账号密码认证。 - 确认本地有密钥对。执行
ls ~/.ssh/,看有没有id_rsa和id_rsa.pub;没有就生成:ssh-keygen -t rsa -b 4096 -C "你的邮箱"。 - 确认公钥已添加到代码托管平台。复制
id_rsa.pub的内容,到 Gitee 的"设置→安全设置→SSH 公钥"或 GitHub 的"Settings→SSH and GPG keys"中新增。 - 确认 SSH agent 是否加载了私钥。有时候多密钥情况下,agent 没有选中正确的私钥,可以执行:
ssh-add ~/.ssh/id_rsa- 测试连接。Gitee 执行
ssh -T git@gitee.com,GitHub 执行ssh -T git@github.com,看到成功提示就说明认证通了。
密钥这块还有一个高级配置值得提一下:如果你有多个代码托管平台的账号(公司 GitLab + 个人 Gitee),需要管理多个不同的密钥对,此时光靠默认的id_rsa就不够用了。可以在~/.ssh/config里指定不同域名对应不同私钥:
Host gitee.com HostName gitee.com User git IdentityFile ~/.ssh/id_rsa_gitee Host gitlab.company.com HostName gitlab.company.com User git IdentityFile ~/.ssh/id_rsa_gitlab注意config文件的权限不能太开放,Windows 上要保证只有当前用户可读写。
4.5 子模块 Submodule:复用代码的正确姿势
git submodule是热词之一,也是很多人"用了又恨"的功能。它允许你在一个仓库里引用另一个 Git 仓库的指定版本,常用于把公共库、主题、约定配置嵌入到多个项目中。
添加一个子模块:
git submodule add git@github.com:some-org/some-lib.git libs/some-lib执行完会生成一个.gitmodules文件,记录子模块的路径和远程地址。
克隆一个带子模块的项目,光靠git clone是不够的,子模块目录会是空的,你还需要:
git clone git@github.com:some-org/main-project.git cd main-project git submodule init git submodule update或者用一行命令:
git clone --recurse-submodules git@github.com:some-org/main-project.git更新子模块到远程最新版本:
git submodule update --remote子模块的坑主要有三个:
- 子模块默认停留在"引用时的版本",不会随主仓库的 push 自动更新。需要更新时必须先拉子模块内部的最新代码并提交引用变化。
- 切分支时容易丢引用。在含子模块的仓库里切换分支,可能遇到子模块指针指向不存在的 commit,需要执行
git submodule update --init --recursive。 - 子模块内部的修改容易被忽略。如果子模块里有未提交的改动,主仓库的
git status会提示,但不会自动提交,需要你进入子模块目录单独 commit 和 push。
如果你只是想在多个项目里共用一段代码,并且这段代码演进没有那么频繁,我更推荐用包管理方案(npm、pip、Maven 等)替代 submodule,因为子模块的维护成本确实偏高。
4.6 图解式命令:switch、restore、reflog的实用场景
git switch和git restore是 Git 2.23 之后拆出来的两个更语义化的命令,分别用来替代git checkout的两大职责:切分支和恢复文件。
切分支推荐用:
git switch dev # 切换到已存在的分支 git switch -c feature/xxx # 新建并切换分支恢复文件改动推荐用:
git restore --staged file.txt # 把文件从暂存区移除,但不改工作目录 git restore file.txt # 把工作目录的文件恢复到暂存区或 HEAD 的状态还有一个救命的命令:git reflog。这是你误操作后的最后一条防线。我把它的价值讲明白:reflog记录的是 HEAD 指针的每一次移动历史,也就是说你执行过的 reset、merge、commit、checkout 等操作,都会在这里留下痕迹。哪怕你被git reset --hard打回了几天前的状态,只要 reflog 里还有那个 commit,你就能找回:
git reflog # 找到你要的那个哈希 git reset --hard <哈希>或者单独的 commit hash 存在但不在任何分支引用上,可以用git cherry-pick <哈希>把它捞回来。所以,误操作后别慌,先git reflog看看。
5. 实战流程与习惯养成
5.1 从一个新任务到推送合并的完整流程
讲了这么多命令,我串一个完整的实战流程,覆盖从接需求到最终合并的全过程,你可以直接照着这个流程走。
假设你在团队项目里接到一个新任务:开发一个"用户头像上传"接口。你所在的仓库已经 clone 下来,当前在 master 分支。
# 1. 新建功能分支,并切换过去 git switch -c feature/avatar-upload # 2. 开发代码,期间可以多次查看变更 git status git diff # 查看未暂存的具体改动 # 3. 开发完成后,做一次本地提交(可分多次提交,但每条信息要清晰) git add src/controllers/user.go git add src/services/avatar.go git commit -m "feat: 实现头像上传接口" # 4. 拉取远程 master 最新改动,并变基到你的分支上,确保不落后 git fetch origin git rebase origin/master # 5. 解决冲突(如果有),继续 rebase git add 冲突文件 git rebase --continue # 6. 推送到远程功能分支 git push -u origin feature/avatar-upload # 7. 在代码托管平台创建 Merge Request(或 Pull Request)这个流程里我最想强调第 4 步的rebase。很多人习惯在合并前用git merge origin/master,这会让分支历史出现一个"合并结",如果团队追求线性历史,rebase更合适;但如果你对 rebase 不熟,在共享分支上慎用。
5.2 IDE 集成:IDEA 中创建项目拉取 Git 与合并分支
热词里 "diea创建新项目拉取git" 和 "idea中git如何合并分支" 很有意思,这是从 IDE 视角提出来的问题。IDEA 的 Git 集成做得相当好,新手完全可以在图形界面里完成大部分操作。
新建项目并拉取远程仓库:IDEA 里选 "Get from VCS",粘贴远程仓库的 URL,选择保存目录,点 Clone 即可。如果遇到认证问题,IDEA 会弹出窗口要求输入账号或 token,也可以在 Settings → Version Control → Git 里配置 SSH 密钥路径。
合并分支:IDEA 右下角的分支列表会显示当前分支,点击后选择 "Remote Branches" 里的目标分支,再选择 "Merge into Current"。本地有冲突时,IDEA 会打开冲突解决器,你可以非常直观地选择保留左侧、右侧或两侧的内容。
IDE 虽方便,但我仍然建议你至少能把命令行版本的 merge、revert、stash 搞清楚,因为这三个操作在命令行下的行为更透明,IDE 偶尔会出现"合并按钮灰色"让你无法点的情况,这时候回到命令行反而更快。
5.3 我个人建议的 Git 使用习惯和避坑清单
最后分享一些我在实际项目中积累的经验。这些习惯不是什么高端技巧,但踩过坑之后才明白它们的价值。
第一,提交前看 diff。我见过太多把自己都不想看到的 debug 代码提交上去的情况。git diff花不了 30 秒,但能帮你拦住 "console.log(123)" 这种意外。
第二,不要把敏感信息提交进仓库。数据库密码、API Key、私钥这些,一旦进入 Git 历史,删除也来不及,因为历史记录里还有。所以项目开头就要把.env、*.pem、config.local.js这类文件写进.gitignore。
第三,分支命名要有语义。比如feature/xxx、fix/xxx、refactor/xxx,前缀决定了这个分支的用途。团队规范里加上这条,能省很多"这个分支是干啥的"的追问。
第四,提交信息用动宾短语,说清楚"为什么"。好的提交信息像一段日记:fix: 修复用户登录后偶现 302 跳转问题比fix bug好一百倍。
第五,遇到诡异问题先git status和git log --oneline -5。90% 的"我怎么少了代码""怎么多了一个文件"都能从这里找到线索。
第六,不要用--force推送共享分支。除非你确定自己能承担历史混乱的后果,否则把--force这个习惯彻底戒掉,真遇到特殊情况先用--force-with-lease,至少它会在推送前检查远程分支是否变化,相对安全。
第七,养成定期git fetch --prune的习惯。远程分支被删除后,本地会留下很多 "origin/xxx" 的残留引用,这个命令把它们清理掉,保持仓库整洁。
第八,不要提交无意义的格式化改动。比如某天你换了 IDE,把所有文件的行尾都改了,或者用了不同格式化规则的插件,整个 diff 变得极大且无意义。这种改动会淹没真正的逻辑变更,代码审查时非常痛苦。
以上这些,不是从文档里抄来的,而是我在真实项目里反复吃亏后沉淀下来的。Git 这个东西,命令就那么几十个,真正拉开差距的是习惯和思维方式——你把它当成一个"随时可以回到过去的时光机",还是一个"记录每一次改动的账本",决定了你用得顺不顺手。
我在实际项目里最深的体会是:Git 并不复杂,复杂的是协作中的不确定性。只要提交信息清晰、分支策略简单、回退操作谨慎,这套工具能给你的安全感是巨大的。最后再分享一个小技巧:项目里维护一份CONTRIBUTING.md,把本仓库的分支命名规范、提交格式、合并流程写清楚,新同事看一遍就能上手,这比嘴上讲十遍都管用。