ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Git从安装到实战:版本控制原理、分支合并与SSH配置全攻略

Git从安装到实战:版本控制原理、分支合并与SSH配置全攻略 如果你搜到这里大概率不是想听“Git是一个分布式版本控制系统”这种教科书定义而是遇到了具体问题git安装不上、装上了系统不识别、提交代码报错、分支合并搞出冲突或者单纯想把日常工作里反复敲的那几条命令真正搞明白。我最初用Git的时候也踩过不少坑最离谱的一次是把整个项目文件夹复制了一份当“手动版本回退”后来才老老实实把Git的基础链路吃透。这篇文章没有太多高深理论就是从零开始把Git的安装、配置、日常命令、分支操作、远程仓库对接以及高频报错的排查思路完整串一遍。不管你是Windows、macOS还是Ubuntu用户刚接触Git的初学者还是已经被工作蹂躏了一阵子的“熟练工”只要按着这篇文章走一遍大概率能把Git从“只会敲命令”提升到“知道为什么这么敲”。文里涉及的所有操作我都实测过版本号、报错信息、解决方案都是真实碰到的可以直接照抄。1. 从“版本”到“仓库”Git到底在做一件什么事先别急着装软件把Git的底层逻辑搞清楚后面所有命令你都不需要死记硬背。1.1 版本管理解决的核心问题假设你正在写一份文档改到第三版后觉得第二版更好又没有备份怎么办以前的做法是手动存好几个副本“论文_最终版.doc”“论文_终稿_不改版.doc”“论文_打死也不改版.doc”。项目代码比文档复杂得多多人协作时你改你的、我改我的最后还得手动合并文件这在现代软件开发里根本不可行。版本控制工具就是来解决这个问题的给文件系统装一台“时间机器”。每一次提交commit都像给当前项目拍一张快照任何时候都能回到任意一次快照的状态。Git只是众多版本控制工具中的一种但它的设计思路和早期的SVN、CVS有根本区别理解了这些区别你就理解了Git设计命令时的出发点。1.2 快照存储与差异存储的本质区别SVN这类集中式版本控制工具存的是“文件变化前后的差异”每次历史版本都记录“这个文件在这个版本里改了哪几行”。好处是省存储空间坏处是历史越长回溯一次版本就越慢而且一旦中央服务器挂了本地基本就废了。Git不一样它采用“快照流”的方式。每次提交时Git把当前所有文件的状态整体拍一张照如果有文件没变就直接引用上一个版本的相同文件只有变化的文件才新增存储。你可以把Git仓库想象成一个不断增长的相册每张相册对应一次提交每张照片都完整记录当前所有文件的状态。相同内容的照片不重复洗印只挂一个索引指向旧照片。这样做的结果是回溯历史极快因为每张快照都是完整的存储效率也没有想象中那么低因为相同文件被复用了。1.3 分布式架构到底“分布”了什么SVN是集中式的代码只存在中央服务器上所有人提交都打到同一台机器。Git是分布式的每个开发者的本地目录都包含一份完整的仓库包括全部历史记录。这意味着没网也能提交代码提交操作完全在本地完成本地就是完整的备份服务器挂了也能从任何一台开发机恢复各人可以在本地大规模修改、试验再决定要不要推到远端。我第一次体会到这个优势是出差坐高铁笔记本没网但手里的代码照常提交了十几个版本到酒店再一次性推到远程仓库过程毫无压力。换成SVN离线状态下连提交都做不到。1.4 分支为什么“便宜”用过SVN的人应该都有印象创建分支通常是“复制一组完整代码到另一个目录”又慢又占用空间所以大家轻易不敢开分支。Git的分支本质上只是一个指向某次提交的指针创建分支就是在仓库里新建一个41字节的指针文件成本几乎为零这也是Git工作流鼓励“多开分支、频繁开分支”的根本原因。仓库根目录下的.git文件夹就是这个项目的所有“时间机器照片”和指针信息。你平时看到的文件目录叫“工作区”.git文件夹里存的是“版本库”。后续几乎所有Git操作本质都是在工作区和这个.git版本库之间搬运数据。2. Windows下的安装与配置镜像下载、PATH选项、Git Bash与全局设置Git装起来不复杂但安装选项里有个坑直接影响后面能不能被IDEA、VSCode这类工具识别。搜“git安装教程”的人很多其实卡点就那么两三个我逐个说清楚。2.1 下载渠道官网慢就用国内镜像Git官网的Windows安装包下载速度不稳定尤其几十上百MB的安装包挂半天下不动是常事。国内镜像速度快得多我用得比较多的是两个淘宝npm镜像https://npm.taobao.org/mirrors/git-for-windows/华为云镜像https://mirrors.huaweicloud.com/git-for-windows/打开后选择对应版本Windows用户下载类似Git-2.xx.x-64-bit.exe的文件。注意区分64位和32位现在新电脑基本都是64位。macOS用户可以用brew install gitUbuntu用户直接sudo apt install git网络干净利落反而没有Windows这么折腾。2.2 安装过程中最关键的三个选项安装包一路Next会出现几个决定命运的选项别只顾点“下一步”第一个是Select Components选择组件默认选项基本够用但建议额外勾选“Git Bash Here”和“Git GUI Here”右键菜单里直接打开Git Bash后面操作方便很多。第二个是Choosing the default editor默认编辑器默认是Vim。如果你没学过Vim在Git里提交代码时不小心进入了Vim界面会懵住。建议选“Use the Nano editor”或者直接选择你常用的编辑器我用的是VS Code提交信息时直接用VS Code编辑体验好得多。第三个是决定成败的PATH环境变量选项它有三个选择第一个“Use Git from Git Bash only”只在Git Bash里能用git命令第二个“Git from the command line and also from 3rd-party software”把Git加入系统PATHCMD、PowerShell、IDEA、VSCode都能直接调用第三个“Use Git and optional Unix tools from Command Prompt”会在PATH里加入一堆Unix命令某些情况下会跟Windows自带命令冲突不建议。很多人装完Git在CMD窗口敲git提示“不是内部或外部命令”就是选了第一个选项或者安装组件时有遗漏。选第二个问题直接消失。IDEA、VSCode这些工具搜索不到Git路径也是因为没选这个选项。2.3 验证安装与Git Bash的妙用安装完成后打开CMD或PowerShell输入git --version正常会输出类似git version 2.40.0.windows.1的版本信息。如果提示git : 无法将“git”项识别为 cmdlet、函数、脚本文件或可运行程序的名称基本就是PATH配置问题。解决方法重新运行安装包选择“Modify”把刚才的PATH选项改成第二个或者手动把C:\Program Files\Git\cmd加进系统环境变量。改完重启终端再试。Git Bash是跟随Git一起安装的轻量级Unix模拟环境它的价值超出很多人的认知。Windows的CMD对Linux风格的路径、命令支持很差脚本写起来也麻烦Git Bash能让你在Windows上使用Linux风格的命令比如ls、grep、sed、ssh。我日常所有Git操作和轻量脚本都优先用Git Bash而不是CMD或PowerShell少踩很多路径分隔符的坑。2.4 全局配置提交者的名片Git每次提交都必须知道“是谁提交的”这靠用户名和邮箱标识。安装完成后第一件事就是配置全局用户信息git config --global user.name 你的名字 git config --global user.email 你的邮箱可以用git config --list查看所有配置确认是否设置成功。--global表示对当前系统当前用户生效所有仓库共用这套身份。如果单个项目需要不同身份比如工作仓库用公司邮箱、个人仓库用私人邮箱可以进入仓库目录后去掉--global重新配置只对当前仓库生效。还有一个容易被忽略的配置中文文件名乱码问题。Windows下终端用GBK编码而Git内部用UTF-8解决方法git config --global core.quotepath false配完后中文文件名不再显示成八进制转义序列“\346\265\213”直接显示正常中文。3. 从空目录到第一次提交add/commit/log/diff 的完整链路安装好、配置好之后进入Git日常使用的主战场。这条链路是从零到一的核心几乎每天都要走一遍。3.1 初始化仓库与第一次提交进入项目目录执行git init当前目录就变成了一个Git仓库master或main分支会随之诞生。之后用git status查看当前仓库状态会看到一堆未跟踪文件说明这些文件还没进入Git的版本管理体系。把文件加入版本管理需要两步git add . # 把所有改动加入暂存区 git commit -m 初始化提交 # 把暂存区内容生成一个版本快照新手最容易困惑的是add和commit为什么要分开直接提交不好吗这里涉及Git特有的“暂存区”设计。add是把文件放进一个叫“暂存区”的中间地带commit才真正把暂存区的内容拍成快照存入版本库。为什么要设置中间地带因为真实工作中经常会出现“这个版本只提这3个文件另外两个文件还在改不想一起打包”的场景。暂存区允许你精细控制一次提交到底包含哪些改动。类比一下add是把菜装进购物车commit是结账买单你可以在结账前随时把某些菜放回货架。3.2 status 和 diff先搞清楚发生了什么再动手git status是我个人使用频率最高的命令没有之一。每次操作前看一眼状态能避免90%的误操作。它告诉你三个信息哪些文件改动了、哪些已经暂存、哪些还未跟踪。git diff负责查看具体改动内容git diff # 工作区与暂存区的差异 git diff --cached # 暂存区与上一次提交的差异我习惯在add之前用git diff检查自己改了哪些内容确认无误后再addadd之后再用git diff --cached复查一遍即将提交的内容。这个习惯帮我挡掉了无数次“把调试日志提交上去了”的尴尬。3.3 log查看历史提交的几种姿势提交后想查看历史基础用法是git log默认输出很冗长我常用的精简版本git log --oneline # 每行只显示提交号缩写和提交信息 git log --oneline --graph # 显示分支历史图谱 git log -n 5 # 只看最近5条--graph配合--oneline能直观看到分支合并的历史走向排查问题时非常有用。3.4 git commit --amend修改最后一次提交的正确姿势热搜词里出现“git commit --amend怎么使用”说明这是很多人实际想搞明白的功能。amend英文是“修订”的意思作用就是把上一次提交替换掉。使用场景主要有两种场景一提交信息写错了。git commit --amend -m 正确提交信息执行后上一次提交的信息被替换成新信息提交号也会变化。场景二提交完发现漏掉了一个文件。git add 漏掉的文件 git commit --amend --no-edit--no-edit表示沿用原提交信息不弹编辑器。相当于把新改动并入了上一次提交。使用amend有一个必须注意的红线只适用于“尚未推送到远程分支”的本地提交。如果上一次提交已经推到远端并且别人可能已经基于它开发此时amend会改写历史导致其他人的仓库历史错乱。对于已经共享的提交正确做法是再新建一次普通提交来修正而不是amend。3.5 撤销操作全家桶restore、reset、reflog撤销是另一个高频需求但很多人搞不清三个命令的区别。我整理一个最小实用的对照表操作目标命令含义丢弃工作区未暂存的改动git restore 文件名让文件回到上次暂存/提交的状态把已暂存的文件取消暂存git restore --staged 文件名文件保留改动但退出购物车重置提交记录到某版本git reset --hard 提交号工作区和暂存区全部回到指定提交状态查看所有历史操作git reflog包括已经“被撤回”的提交记录git reset --hard很危险因为会彻底丢弃工作区未提交的改动。执行前我用git stash或者手动复制备份的习惯已经根深蒂固。万一真的误删了还有最后一根救命稻草git reflog。这个命令记录了你本地所有引用变更历史包括那些已经“消失”的提交找到对应提交号后可恢复。我的亲身体会reflog救回过我一个改了三天的文件从那以后再也不敢说Git里有什么是“永久删除”的。4. 分支操作从图片思维开始创建、切换、合并与worktree实操分支是Git最强大的设计也是新手最容易翻车的地方。先打破一个思维惯性分支不是文件夹复制而是一枚贴在提交记录上的书签。4.1 分支的底层认知与常用操作回过头看1.4节说的分支本质上是一个指向提交的指针。当前分支的指针随新提交向前移动其他分支的指针原地不动这就是“各改各的”这一说法的底层原理。常用分支操作命令git branch # 查看本地分支加 -a 可查看远距分支 git branch feature-login # 创建新分支 git switch feature-login # 切换到已存在的分支 git switch -c feature-login # 创建并切换到新分支最常用的组合 git branch -d feature-login # 删除已合并的分支 git branch -D feature-login # 强制删除未合并分支慎用注意我写的是git switch而不是老命令git checkout。switch是Git 2.23引入的新命令语义更清晰切换分支用switch恢复文件用restore职责划分清楚不容易“切分支却把文件搞丢”。不过老文档里到处是checkout见到时能认识就行。4.2 合并的两种模式快进合并与三方合并当你把分支合并回主干时git switch main git merge feature-login如果目标分支没有新提交Git会用“快进合并”fast-forward直接把main的指针挪向feature-login历史是一条直线合并非常干净。如果两个分支各有过新提交Git就会进行真正的三方合并把两个分支的最新状态加上“共同祖先”版本做合并生成一个全新的合并提交历史图谱上能看到交汇点。初学者不必把这两者创建得那么深但要知道一件事合并操作本身不产生网络传输所有人都在本地完成所以合并成本也不高这也是Git鼓励“多开分支、频繁合并”的原因。4.3 合并冲突最吓人但必须学会面对的场景两个分支都修改了同一个文件的同一行代码Git不知道到底该保留谁的内容就会报冲突。看到那种红色“CONFLICT”提示第一次经历的人很容易懵其实处理方式非常固定。冲突发生时用git status会看到“Unmerged paths”业务被打断到了both modified状态。打开冲突文件里面会出现类似这样的段落 HEAD 这是main分支的改动 这是feature-login分支的改动 feature-login处理原则极简单把不需要的行删除把、、这三行标记行全部删除只保留想要的最终代码。然后git add 冲突文件 git commit -m 合并分支解决冲突冲突不可怕它只是Git向你抛出的一道取舍题你自己决定留哪边就好。真正的教训是两点第一解决冲突时要全局搜索一遍“”以免漏掉某个没处理完的文件第二多人协作的公共仓库每次干活前先拉取最新代码可以大幅减少冲突概率。那“我们的”和“他们的”到底分别代表谁不同场景下含义完全不同看 HEAD上面的内容不靠谱最可靠的方式是看git status中标注的分支名再结合提交情况判断。4.4 git worktree同时处理多个分支的并发利器搜“git worktree”的人越来越多说明很多人已经意识到“一个工作区切来切去”效率太差的问题。常规做法是改分支A做到一半突然要去分支B修个紧急bug先stash当前改动切到B修完再切回Apop回来。切换频繁时光stash和pop就要花不少心思。git worktree允许你在另一个目录同时检出另一个分支相当于“一个仓库多个工作区”各分支同时打开、同时编辑、互不干扰git worktree add ../my-project-hotfix hotfix-branch这会在上级目录的my-project-hotfix目录里检出一个新的工作区分支是hotfix-branch。你可以在原目录继续改功能A在新目录专注修紧急bug两者都是同一个仓库的不同工作区commit提交共享同一套历史。我实际用下来的感受是处理“多版本并行维护”场景时worktree比频繁切分支高效太多。用完不用时执行git worktree remove ../my-project-hotfix清理掉即可。5. 远程仓库、SSH密钥与认证失败排查手册本地操作熟练之后就要跟远程仓库打交道了。热搜词里“git配置gitee密钥”“ssh认证失败”“git免密”“git清除账号密码”全是这一块的痛点。集中串一遍。5.1 HTTPS还是SSH两种协议怎么选远程仓库地址有两种形式HTTPS方式https://github.com/xxxx/xxx.gitSSH方式gitgithub.com:xxxx/xxx.git两者的区别在于认证方式。HTTPS每次push都要输账号密码或依赖凭据管理器SSH通过密钥对认证配置一次之后永久免密。我所有项目都优先用SSH方式原因就是一个字省事。尤其是长时间使用服务器或者经常写脚本拉代码的场景下SSH免密的价值会无限放大。5.2 生成密钥并添加到Gitee生成密钥的命令ssh-keygen -t ed25519 -C 你的邮箱example.com连续按三次回车使用默认路径和空口令即可。如果平台相对古老不支持ed25519退而求其次用ssh-keygen -t rsa -b 4096。生成的公钥位于~/.ssh/id_ed25519.pub用文本编辑器打开并复制全部内容。进入Gitee或GitHub的设置页面找到“SSH公钥”菜单标题随便填把公钥内容粘贴进去保存。添加完用一条命令验证ssh -T gitgitee.com首次连接时会有“Are you sure you want to continue connecting”的提示输入yes看到“Hi 用户名”之类的欢迎提示就说明已配置成功。5.3 ssh认证失败的常见原因和排查顺序项目上遇到“ssh认证失败”报错通常是Permission denied (publickey)。按以下顺序排查大部分问题都能定位第一步确认公钥是否真的添加到平台了。这一步查操作遗漏的最多。检查公钥内容是否复制完整有没有多复制空格或丢失尾部换行。第二步确认本地使用的是哪个密钥文件。如果你生成密钥时自定义过文件名SSH默认不会读取这个文件需要在~/.ssh/config里显式指定Host gitee.com HostName gitee.com User git IdentityFile ~/.ssh/id_ed25519第三步确认是否配置过多个密钥、默认用了错误的那个。机器上如果有多个私钥SSH默认从~/.ssh/id_ed25519或~/.ssh/id_rsa里找。解决方式是把不同平台的密钥在主配置里分别指定不同的Host条目。第四步检查网络可达性。执行ping gitee.com或者直接浏览器访问远程仓库地址确认网络环境能正常访问。公司内网或代理环境需要额外配置~/.ssh/config里的ProxyCommand等参数。第五步确认Git用户身份设置正确。git config --list看到邮箱是否跟你平台注册邮箱一致。有些平台在公钥无法识别时会退回检查邮箱邮箱不匹配也报错。有一个细节容易被忽略Windows用户升级Git后~/.ssh目录可能不在预期路径使用ssh -v加verbose参数能看到具体读的密钥文件位置排查时这条信息最有用。5.4 HTTPS账号密码的缓存与清除如果你用HTTPS克隆的项目第一次push时会弹出窗口输入账号密码Git会把凭据交给Windows凭据管理器保存之后就不再询问。问题来了平台密码改了git push就一直报认证失败因为还在用旧缓存。清除缓存的姿势分版本区别# Windows下通过凭据管理器删 # 控制面板 → 凭据管理器 → Windows凭据 → 找到 git:https://xxx 项 → 删除 # 或使用git命令查看当前credential配置 git config --global credential.helper # macOS下直接用系统钥匙串访问程序删掉对应项还有一个通用做法是git credential-manager erase按提示输入协议和主机名即可清除对应凭据。下次push时会重新要求输入账号密码同时也写入新凭据。5.5 绕开“每次输密码”的终极方案为了不再被密码和缓存问题困扰我的建议非常简单一律用SSH不用HTTPS。克隆时不要复制HTTPS地址点仓库页面的“克隆/下载”按钮后选择SSH地址。旧仓库可以通过改remote地址切换git remote set-url origin gitgitee.com:用户名/仓库名.git改完后git remote -v确认一下远程地址是否为SSH格式。再push一次感受一下不用输password的快乐就再也不想切回HTTPS了。6. 高频报错与图形化工具集成从fatal提示到IDEA、VSCode、TortoiseGit最后把日常碰到的几个高频问题集中说一下包括fatal: not a git repository这个让无数人搜索过的报错、IDE集成和一些额外的小工具。6.1 “fatal: not a git repository”到底怎么回事这个报错的完整形式是fatal: not a git repository (or any of the parent directories): .git大意是“当前目录不是Git仓库往上层找了也没有找到仓库”。产生原因通常是这三种第一种当前目录真的没有初始化过仓库。解决方式最简单git init初始化即可。第二种你身处仓库的子目录深处而子目录里没有.git文件夹。向上层的仓库目录执行git status即可正常。这个报错之所以带(or any of the parent directories)就是因为Git本来会自动向上层目录寻找仓库如果一直找到根目录都没有才报这个错。第三种在Git Bash里用错了工作路径。打开Git Bash后默认位置是C:/Users/你的用户名执行cd进入实际项目目录再操作。我的建议是先执行pwd看自己在哪个目录再ls -a看看有没有.git目录思路清晰了再处理一般一分钟内能解决。6.2 IDEA创建新项目并拉取Git仓库IntelliJ IDEA的Git集成体验是几大IDE里做得最好的。拉取已有仓库的路径选择File → New → Project from Version Control…在弹出的对话框里填入Repository URL和本地目录点击Clone即可。IDEA会自动识别SSH密钥前提是你用的是“Git from the command line and also from 3rd-party software”那个安装选项否则IDE可能找不到Git执行文件。如果IDEA提示找不到Git手动配置路径Settings → Version Control → Git在“Path to Git executable”里指定C:\Program Files\Git\bin\git.exe点击Test确认版本显示正常。IDEA里拉代码和推代码也很直观右上角的绿色向下箭头拉取向上箭头推送快捷键CtrlT和CtrlShiftK可以记一下效率高很多。6.3 VSCode中配置Git账号密码的思路VSCode本身不自带Git它只是调用系统的Git命令所以“VSCode配置Git账号密码”这个热搜词本质上还是在配Git本身。在VSCode里第一次push时会弹窗要求输入账号密码凭据管理器的界面输入后由系统保存之后不会再问。改密码后反复提示认证失败的处理用前面说到的“凭据管理器删除旧凭据”方案即可。另外VSCode左下角的源代码管理面板可以直接看到所有文件变更比敲命令直观很多但初始化仓库、设置remote这类操作我仍然习惯在终端里完成。大概原因是前端工具的重构操作做得再好终端里的Git命令毕竟才是最终解释标准。6.4 TortoiseGitWindows上的“小乌龟”搜“git 小乌龟下载”的人通常是第一次接触Windows图形化Git。TortoiseGit是一套集成到Windows右键菜单的Git客户端图标是一只小乌龟。它的优势在于完全不用记命令右键就能看到“Commit...”“Pull...”“Push...”“Merge...”等等所有操作都有图形化界面。但实际用过一段时间我的体会是小乌龟适合刚开始接触Git、对命令行有恐惧感的用户一旦日常流程稍微复杂一点rebase、worktree、批量revert小乌龟反而束手束脚。更建议的做法是先用小乌龟把“add、commit、push、pull、merge”这些核心动作的心智模型建立起来然后马上转向Git Bash命令行。命令行才是走遍各大平台都通用的基本功。6.5 顺手提一句不要让 .git 目录暴露在“不该出现”的地方最后提醒一点。.git目录里包含了项目全部历史记录、分支信息、甚至可能包含一些敏感信息。在部署项目、打包上传的时候务必确认.git目录不会被一并暴露出去。正确做法是把它加入部署的忽略清单同时切忌在公开场合随意上传包含.git目录的项目压缩包。这是很多初入行的人不太注意但在实际工作中极其重要的一条习惯。从安装配置到每天都要走的add/commit/push链路再到分支合并和SSH认证这篇文章覆盖了Git使用中最基础也最高频的完整闭环。工具终究是服务于工作的把底层的“快照、指针、暂存区”这三件事理解透你会发现Git的命令永远不需要背因为你已经知道它为什么要这样设计。你先去配好SSH免密再把每天提交前看一眼git status和git diff的习惯养成Git这一关就算真正过了。
返回列表