ARTICLE DETAIL

资讯详情

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

Git实战手册:安装配置、分支管理与高频命令详解

Git实战手册:安装配置、分支管理与高频命令详解 1. 从“看着眼熟”到“随手就用”Git的安装与初始化配置Git这个东西说起来真是又爱又恨。爱它是因为分布式版本管理确实好用恨它是因为刚开始接触的时候命令又多又杂稍不留神就commit错了分支或者push上了不该push的东西。但不管怎么说只要是写代码的Git基本是绕不开的一道坎。这篇东西不打算讲那些底层对象模型和原理推导就从一个实际干活的人角度把常用命令捋一遍顺便把那些踩过的坑、翻过的车一并交代清楚。先说版本选择。Windows用户直接去Git官网下载安装包就行注意选64-bit版本安装的时候一路Next基本没问题。但有几个选项值得留个心眼安装过程中会让你选默认编辑器新手用Notepad就够了Adjusting your PATH environment那一步建议选“Use Git from the command line and also from 3rd-party software”这样在CMD和PowerShell里都能直接用git命令。Linux用户就简单了Debian系执行apt install gitRedHat系执行yum install gitMac用户建议用Homebrew装最新版别用系统自带的旧版。装完第一件事就是配置身份信息这一步经常被跳过结果后面commit的时候弹出一串莫名其妙的报错。配置分全局和局部两层全局配置写在用户目录下的.gitconfig文件里局部配置写在每个仓库的.git/config里。建议全局配置一份通用的name和email然后特定项目需要不同身份时再用局部配置覆盖git config --global user.name yourname git config --global user.email youremailexample.com git config --list还有一个很多人不知道的小细节git config --global core.autocrlf这个配置在不同系统上表现差异很大。Windows上建议设成true让Git自动把CRLF转成LF存储检出时再转回CRLFLinux和Mac上建议设成input只转换提交时的换行符不做检出转换。我之前在Windows上写脚本、在Linux服务器上运行因为换行符问题排查了整整半天最后发现就是autocrlf没配好。这类看似不起眼的全局配置在跨平台协作时特别容易埋坑越早处理越好。配置完可以用git config --list检查一下全部设置没问题就算准备就绪。接下来进入实战环节先过一遍日常开发最常用的三个命令——add、commit、push。2. 日常三连add、commit、push的底层逻辑2.1 add到commit之间的状态流转很多教程会告诉你“git add把文件加入暂存区git commit把暂存区的内容提交到本地仓库”这话没错但不够直观。我习惯用生活类比add就像把东西从抽屉里拿出来放到购物车里commit才是到收银台结账push是派快递送货。还没结账之前随时可以调整购物车里的商品不想买了直接清空也没事。理解了这一层你就明白为什么鼓励频繁commit——结账记录越细后面追溯每个商品代码改动的来龙去脉就越方便。日常开发里最经典的三连操作长这样git status # 查看当前工作区状态 git add filename # 添加单个文件 git add . # 添加所有改动 git diff # 查看未暂存的具体变化 git commit -m feat: add login API git push origin main推荐在add之前先跑一次git diff看清楚自己到底改了什么。别小看这个习惯我见过太多次git add .把所有临时文件、调试日志一起提交上去的场面。git status会显示未跟踪文件红色和已暂存文件绿色一目了然。如果只想添加某个目录下的改动git add src/这种路径写法很好用比git add .可控得多。commit的消息规范也很重要团队里最好统一格式。现在比较流行的是Conventional Commits风格大概长这样feat: 新功能、fix: 修复bug、docs: 文档变更、refactor: 重构、style: 格式调整。好处是后面看git log能快速定位每一次提交的目的配合git log --oneline看历史时特别清晰。2.2 commit信息写错了怎么办commit之后发现信息写错了或者少提交了一个文件千万别慌git commit --amend就是干这个的。这个命令会把最近一次commit替换掉相当于“后悔药”git commit --amend -m 正确的提交信息 # 或者只补充文件沿用原来的提交信息 git add forgotten_file.py git commit --amend --no-edit注意一个关键点--amend会生成新的commit哈希所以只适合处理还未push到远程的提交。如果已经push上去了而队友又已经拉取了那个commit这时候强行amend再强推force push会造成别人的本地历史和远程不一致协作时很容易出乱子。实际操作中我自己的经验是本地commit后发现小问题改amend没问题一旦push过了再有问题就用新commit去修正不要轻易用amend加上force push的组合。3. 分支管理从创建到合并的完整路径3.1 分支的日常操作分支是Git最灵活的设计之一团队协作全靠它并行推进。分支的完整生命周期包括创建、切换、提交、合并、删除。git branch # 列出本地分支 git branch new-feature # 创建新分支 git checkout new-feature # 切换到新分支 git checkout -b new-feature # 创建并切换最常用 git switch new-feature # Git 2.23 新语法语义更清晰 git switch -c new-feature # 创建并切换的新写法git switch是后来推出的新命令和checkout功能重叠但语义更明确。checkout这个名字历史包袱太重既管分支切换又管文件恢复容易让人混淆。建议新项目直接用switch和restore一个只管分支一个只管文件。合并分支时merge和rebase的选择是个老话题。git merge会创建一个新的merge commit保留两个分支的完整历史优点是不会动已有commit缺点就是历史图会复杂出现“分叉再合并”的痕迹。git rebase则是把当前分支的提交“移植”到目标分支顶部让历史线变成一条直线看起来干净清爽但它会重写commit哈希。实操中我的建议自己开的功能分支合并回主干时用rebase保持历史整洁多人协作的公共分支比如main用merge --no-ff保留合并信息。关键红线绝不要对自己的主干分支执行rebase更不要把已经push到远程的分支做rebase后再强推。rebase违背了“已发布历史不可变”的原则强推会覆盖队友已有的提交这种事故我亲眼见过好几回每次都是一片哀嚎。3.2 冲突解决的正确姿势合并过程中最常见的问题就是冲突。比如你和同事同时改了同一个文件的同一段代码Git没办法自动判断该用哪边就会标记冲突git merge feature/test冲突文件里会出现类似这样的标记 HEAD 这里是你当前分支的内容 这里是待合并分支的内容 feature/test手动修改成想要的结果后删掉标记行重新add和commit即可。这里有个小技巧冲突文件多的时候先用git status列出所有冲突文件逐个解决每解决一个就git add一个。别一次性add全部避免漏掉和误改。还有一类冲突是删除冲突一边删了文件另一边改了文件。这种处理起来更小心需要沟通确认是保留删除还是保留修改。所以团队协作时改动公共模块前先pull最新代码尽量减小冲突范围这比什么技巧都管用。4. 远程仓库与协作clone、push、pull的进阶细节4.1 远程仓库的增删改查本地仓库往往需要和远程仓库打交道最常见的远端类型就是GitHub、GitLab或自建的Gitea。git remote -v可以查看所有远程仓库地址。新项目关联远端用git remote add origin url修改地址用git remote set-url origin new-url。git clone是从远端复制仓库到本地的入口。默认会克隆所有分支的历史但只检出默认分支通常是main或master。如果只想克隆指定分支可以这样git clone -b dev --single-branch repo-url--single-branch可以只拉取指定分支能显著减少克隆时间。仓库特别大比如历史好几GB的项目这个选项非常实用。但也要注意如果后面需要其他分支clone之后再fetch会很慢所以只在确定只用某个分支时才推荐用。push的时候有个细节容易忽略就是指定远程分支名git push origin main # push本地main到远程main git push origin dev:release # push本地dev到远程release git push -u origin feature/test # -u建立tracking关系-u参数也叫--set-upstream会建立本地分支和远程分支的追踪关系之后在本地分支直接git push或git pull就能少打很多字。初次push新分支时建议加上-u不然Git会提示你“没有上游分支”然后报错。4.2 fetch、pull和push的完整链路很多人搞不清git fetch和git pull的区别。简单说fetch只是把远程最新状态下载下来更新远程追踪分支的引用不会动你当前的工作区pull则相当于fetch加merge直接拉取并合并到当前分支。实际操作中如果当前分支有未提交的改动直接git pull可能会报冲突但git fetch不会影响任何东西。推荐一个日常操作顺序先git fetch看看远程发生了什么变化用git log origin/main --oneline比较自己和远程差异再决定merge还是rebase或者直接pull。这样可以明确远程的变化内容避免pull下来一堆意外的改动把工作区搞乱。git pull --rebase也是一个常用选项拉取时用rebase代替merge保持提交历史的线性。但前提还是那句老话当前分支的提交没有被人共享过才适合这么玩。tag标签也是远程协作的重要环节。打标签用于标记特定版本比如发布v1.0.0git tag v1.0.0 git push origin v1.0.0 git tag -d v1.0.0 # 删除本地标签 git push origin :v1.0.0 # 删除远程标签不推荐但有时需要我习惯在每次发版后打一个tag配合CHANGELOG使用后面要回溯某个版本git checkout v1.0.0比在那堆commit哈希里翻找省事一万倍。5. 进阶技巧stash、cherry-pick、lfs与子模块5.1 临时保存现场git stash开发中经常遇到“手头活没干完但有个紧急bug要先修”的情况。这时候把东西提交了吧又不想留下半截子的commit不提交吧又怕把当前状态搞乱。git stash就是解决这个场景的利器git stash # 保存当前改动到堆栈 git stash list # 查看所有stash记录 git stash apply # 恢复最近的stash但不删除记录 git stash pop # 恢复最近的stash并删除记录 git stash branch new-branch # 基于stash创建分支并恢复stash默认只保存tracked文件的改动新创建但未被跟踪的文件需要加-u参数才会被一起保存git stash -u坑点在于stash恢复时如果当前分支和之前差异较大也会报冲突。所以尽可能在同一个分支上stash并恢复。我个人的习惯是手头工作不完整但又必须被打断时先写个简短的commit说明“wip”然后切换分支处理紧急任务后面用git rebase -i把这些wip提交合并成完整的功能提交。这样比stash更可控因为commit有上下文记录stash多了容易糊涂。5.2 挑一个commit过来git cherry-pickgit cherry-pick能把某个分支上的特定commit“复制”到另一个分支。比如develop分支上已经修复了一个bug但那边还没合并到release分支你不想把develop整个合并过去只想拿这一个修复git cherry-pick commit-hashcherry-pick会生成一个新的commit哈希和原commit不同但内容一致。多commit连续挑选也支持git cherry-pick A^..B这条命令会把A到B之间的所有commit应用到当前分支。实战中需要注意的一点如果两个分支的代码差异比较大cherry-pick也可能产生冲突解决方式跟merge冲突一模一样。我在跨版本修复时经常用它比如线上版本是v1.0dev分支提交了好几个修复需要把其中两个挑到hotfix分支这个命令是唯一合理的方式。5.3 大文件管理Git LFSGit对仓库大小很敏感单个文件超过100MB时普通push基本就会开始警告了超过1GB更是直接不行。LFSLarge File Storage是GitHub推出的大文件追踪方案原理是把大文件替换成一个指针文件存到Git里真正的文件内容存在LFS服务器上这样Git仓库里始终只有小小的文本引用不会膨胀。安装和启用流程git lfs install git lfs track *.mp4 *.zip *.pkl git add .gitattributes git add bigfile.mp4 git commit -m add big file with lfs git push origin main注意LFS对GitHub免费仓库的容量是有限额的存储1GB、流量1GB每月超出要付费。自建GitLab也支持LFS在仓库设置里打开即可。常见问题git lfs clone卡住多半是网络问题导致连接LFS服务器不畅。另外如果拉取别人的LFS仓库时没有任何报错但文件打不开先检查一下本机有没有执行过git lfs install——没安装LFS环境的话拉下来的文件会是那个指针文本不是真实内容。5.4 子模块git submodule项目里引用其他项目作为依赖而且需要指定版本git submodule是好选择。比如你的项目要内嵌一个公共组件库git submodule add https://github.com/example/lib.git libs/lib git submodule update --init --recursive子模块在Git里只是一个commit引用gitlink主仓库只记录子模块的提交哈希。常见的坑clone主仓库后子模块目录是空的必须执行git submodule update --init才能拉取子模块内部有自己的分支状态切分支时容易忘掉更新。设计上子模块适合引用比较稳定的依赖库如果是频繁变动的内部组件我更推荐用包管理工具比如npm、Maven、pip来管理版本依赖省心得多。6. 疑难杂症排查clone失败、免密配置与CRLF问题6.1 clone失败的常见原因与排查路径Git报错五花八门但很多问题归根结底是网络或认证。比如经典的Failed to connect to 127.0.0.1 port 7890这通常是因为系统配置了代理或者某软件比如代理类工具残留了环境变量把Git的网络请求转发到了本地不存在的端口上。排查思路也很固定检查环境变量Windows下执行echo %HTTP_PROXY%和echo %HTTPS_PROXY%Linux/mac执行echo $HTTP_PROXY。如果确实有但有问题的代理值用unset HTTP_PROXY HTTPS_PROXY临时清掉或者去系统设置里永久改。查看Git内建代理配置git config --global --get http.proxy如果发现代理值不对劲用git config --global --unset http.proxy清掉。另一个高频问题ssh: connect to host github.com port 22: Connection timed out。这种情况多是网络限制SSH端口。临时或替代方案是改用HTTPS方式clone或者把SSH协议换成443端口。6.2 SSH密钥配置与免密登录说到SSH认证失败首先要知道Git支持两种远程协议HTTPS和SSH。SSH方式配置好密钥后可以完全免密操作比HTTPS每次输密码效率高太多。配置流程ssh-keygen -t ed25519 -C youremailexample.com一路回车生成密钥对然后查看公钥内容cat ~/.ssh/id_ed25519.pub复制到GitHub/GitLab的SSH Keys设置里。测试连接ssh -T gitgithub.com常见故障提示Permission denied (publickey)排查顺序如下先把ssh-add -l看下私钥有没有加载进ssh-agentWindows一般在“服务”里把OpenSSH Authentication Agent设为自动启动macOS上加ssh-add ~/.ssh/id_ed25519确认当前使用的key路径对不对。还有个容易忽略的点多个Git服务商同时用的时候需要配置~/.ssh/config给不同主机指定不同的私钥Host github.com HostName github.com User git IdentityFile ~/.ssh/id_ed25519_github配置完记得chmod 600 ~/.ssh/config权限不对的话ssh会直接忽略配置文件。6.3 文件被忽略却不生效.gitignore排查.gitignore写好了但文件还是被跟踪这基本上是Git新手必踩的坑。原因是.gitignore只对“未跟踪”文件生效已经被纳入版本控制的文件之后再加进.gitignore是不会自动解除跟踪的。正确做法是先从Git中移除缓存git rm -r --cached . # 清除所有缓存索引不会删除本地文件 git add . git commit -m update .gitignore这个命令的本质是让Git重新构建索引把那些已被跟踪但不该进仓库的文件从索引中剔除。实测有效但别在多人共享分支上频繁用因为会导致大量文件的索引重写其他人pull下来会有很多文件变成deleted状态需要重新add。7. 命令行之外的效率工具Git命令行本身足够强大但用好辅助工具能大幅提高效率。Linux/Mac环境可以用tig来可视化浏览历史tig它会打开一个类似文本界面的Git历史浏览界面分支图、diff、log一线搞定。Windows上我推荐GitHub Desktop或者Fork图形界面直观特别适合分支管理和冲突解决的可视化操作。IDE方面VS Code自带的Git插件就很好用Source Control面板可以完成绝大多数操作暂存、提交、推送、分支切换、冲突解决。JetBrains系列IntelliJ/PyCharm等内置Git工具也相当完善左边点击右键就能执行所有Git操作。不过我个人的习惯一直是理解底层用命令行日常操作也用命令行为主。图形界面虽然有辅助优势但如果不懂命令行的底层逻辑很多复杂的合并、rebase、cherry-pick操作根本无从下手出问题更不知道怎么排查。命令行是根图形界面是枝叶两者结合才是王道。8. 命令速查表整理一份高频命令速查方便直接抄作业功能命令查看状态git status查看diffgit diff已暂存用git diff --cached添加文件git add filename/git add .提交git commit -m message修改提交git commit --amend推送git push/git push origin branch拉取git pull/git pull --rebase抓取git fetch创建切换分支git checkout -b branch合并分支git merge branch变基git rebase branch暂存改动git stash查看历史git log --oneline --graph --all寻找bug引入人git blame filename丢弃工作区改动git restore filename删除分支git branch -d branch删除远程分支git push origin --delete branch最后再分享一个实用小技巧git log --oneline --graph --all建议设个别名git config --global alias.tree log --oneline --graph --all以后敲git tree就能看到所有分支的提交树帮你在复杂的仓库里快速找到自己的位置。我个人在实际使用中最大的感受是Git命令多但真正高频的其实就那么二三十个。把这些命令的使用场景、参数含义、常见坑都搞透日常开发基本上就无往不利了。真正困难的不是记住命令而是理解每个命令背后的操作对象——工作区、暂存区、本地仓库、远程仓库这四者之间的关系想明白了Git的大门才算真正推开。
返回列表