ARTICLE DETAIL

资讯详情

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

Git高频命令实战手册:从环境配置到分支管理的完整指南

Git高频命令实战手册:从环境配置到分支管理的完整指南 干这行久了你会发现Git这东西很少有人系统学过一遍。git常用命令说起来就是几个单词但大多数人的状态是能用就行clone、add、commit、push这四板斧走天下一旦遇到分支合并、撤销提交、过滤文件失效这类问题就得现查现搜查完还不敢确定会不会把代码弄丢。我从写第一行代码到现在Git仓库操作过不下上千次踩过不少坑也帮同事救回过不少被reset掉的提交所以这篇文章不打算做官方文档的翻译而是把我日常真正高频使用的命令按场景重新整理一遍讲清楚每条命令为什么要这么用。无论你是刚接触Git的初学者还是用了好几年命令行但没系统梳理过的老手挑需要的部分看就行。1. 先把环境搞定安装、身份配置与SSH免密日常用Git第一步不是敲命令而是把环境收拾利索。我见过太多人在Windows上装了Git之后直接用默认配置结果提交代码时发现提交人信息全是乱码或者每次push都要输密码输到怀疑人生。这些问题源头都在最开始的十分钟配置上。1.1 三大平台的安装方式先说安装。Windows用户推荐去Git官网下载安装包一路Next安装完就自带Git Bash终端了。Mac用户最简单的方式是brew install git或者装上Xcode Command Line Tools之后系统也会有自带Git版本不过自带的版本通常偏老建议还是用brew装新版。Linux用户根据发行版不同Ubuntu/Debian用sudo apt install gitCentOS/RHEL系列用sudo yum install git。版本这个事我一直很在意。有人觉得Git版本无所谓能跑就行但实际不是这样。老版本对新SSH算法支持不好Submodule的很多修复也只在较新版本里Git LFS偶尔的诡异问题升级版本之后就直接消失了。所以我的习惯是装好之后先跑一条git --version确认版本号Windows和macOS上的话尽量保持在2.30以上。1.2 第一次clone前必须做的两件事装好Git第一件事是配置你的身份信息。Git的每次提交都会记录作者和邮箱这个信息不是随便填的git config --global user.name 你的名字 git config --global user.email 你的邮箱--global表示全局生效作用于这台机器上你的所有仓库。如果你不清楚当前配了什么用git config --list查看全部配置。这里有个实际教训如果忘了配置user.email就提交代码Git会在提交记录里嵌一个默认生成的邮箱后期再想改就非常麻烦。所以入职新公司、换了新电脑第一步永远是配这个不是急着clone代码。除了身份还有一个很多人没注意的配置项是提交时的默认编辑器。Git在需要你填写多行提交说明、或者执行git merge碰上冲突时会自动打开一个文本编辑器默认可能是Vi/Vim。老手无所谓新手一进去就是两眼一抹黑不知道怎么退出。建议先改成自己熟悉的编辑器git config --global core.editor code --wait # VSCode git config --global core.editor nanoGit的配置分成三个作用域system系统级、global用户级、local仓库级。优先级是local大于global大于system。同一个配置项在不同层级出现时越具体的越先生效。如果你想临时在某一个仓库用不同的邮箱提交不要改全局配置直接在这个仓库里执行git config user.email xxx即可只影响当前仓库。1.3 配置SSH密钥告别每次输密码代码托管平台支持HTTPS和SSH两种协议。HTTPS简单但每次push都要输账号密码即便有credential helper缓存也总有意外情况。SSH配置好之后一劳永逸强烈推荐。生成密钥的命令ssh-keygen -t ed25519 -C 你的邮箱一路回车就能在~/.ssh/id_ed25519.pub生成公钥文件。如果平台不支持ed25519算法改用ssh-keygen -t rsa -b 4096 -C 你的邮箱也行。然后把.pub文件里的内容复制到GitHub/Gitee/GitLab的SSH Keys设置页面里保存之后本机验证ssh -T gitgithub.com看到类似Hi xxx! Youve successfully authenticated的输出说明配置成功。之后clone仓库时记得选SSH地址也就是形如gitgithub.com:user/repo.git那种而不是https://github.com/user/repo.git。这里有个多账号场景如果你的机器同时要访问公司和个人的GitHub账号可以在~/.ssh/config文件里配置多个Host每个Host对应一个HostName、User和IdentityFile然后在不同目录的仓库里把remote地址写成对应Host名。这套配置我用了很久稳定可靠但属于进阶玩法新手暂时用不上。1.4 换行符与git bash的小坑Windows用户还有个必经的坑就是换行符。Windows的文本文件默认用CRLF回车加换行结尾而Linux/macOS用LF仅换行。Git为了兼容有个core.autocrlf配置项Windows上建议设置git config --global core.autocrlf truemacOS/Linux上建议设置git config --global core.autocrlf input这个配置的意思是Windows上检出代码时自动把LF转成CRLF提交时自动把CRLF转回LFmacOS/Linux上提交时把CRLF转成LF但不主动转检出。这样能最大限度避免因为换行符差异导致整个文件被标记为改动。这个坑我放到疑难杂症章节再展开先埋个伏笔。另外提一句Git BashWindows下装了Git之后自带的Bash终端日常跑Linux命令会很顺手。但有个细节在Git Bash里执行命令时路径分隔符和Windows资源管理器看到的路径略有差异比如C:\Users\xxx在Git Bash里要写成/c/Users/xxx。刚上手的人容易在这上面绕弯知道有这回事就好。2. 每天都要走的提交链路add、commit、push、log环境配置完之后就是最核心的日常操作链路了。我统计过自己一天敲得最多的命令无非就是那几个clone、status、diff、add、commit、push、log。但每一个命令其实都有一些容易被忽略的细节。2.1 clone之后先看remote拿到一个项目第一件事通常是git clone 地址。如果仓库很大可以加--depth 1只拉最近一次提交速度会快很多这叫浅克隆。不过浅克隆之后要注意这个仓库没有完整历史git log里看不到旧提交一些依赖完整历史的操作也会受限。克隆完成后我习惯先看一眼远程配置git remote -v这条命令显示当前仓库配置的所有远程仓库地址。正常情况下你会看到origin对应你clone时的地址。如果你拿到的是别人发给你的压缩包而不是clone的需要手动把远程仓库地址加进去git remote add origin gitgithub.com:user/repo.git这个场景在接手同事项目或者公司内部分发代码时很常见我看到很多新人拿到压缩包后不知道怎么配remotepush的时候直接报错No remote configured。知道这个就够了。2.2 status与diff提交前最后的检查改完代码之后先不急着git add而是用git status查看当前工作区状态。这条命令会告诉你哪些文件被修改了、哪些是新文件未跟踪、哪些已经进了暂存区。状态清楚了再决定下一步。然后推荐一条我几乎每日必用的命令git diff它显示的是工作区里还没有暂存的改动逐行对比。提交前扫一遍diff能避免很多低级错误比如不小心把调试用的console.log、临时代码、密钥文件混进提交里。想查看已经暂存内容的差异用git diff --cached。有个针对新手的提醒git diff默认只看已跟踪文件的改动不显示未跟踪的新文件。新文件要先git add才会出现在暂存区也才会被git diff --cached看到。这条逻辑搞明白了再看Git的三个区概念就不晕了工作区、暂存区、本地仓库区Git的所有命令都是在这三个区域之间搬运内容。2.3 commit与commit messagegit add 文件把文件加入暂存区git commit -m 提交说明把它固化成本地提交。这里是两个我踩出来的经验。第一git add .要慎用。它会一股脑把所有改动都加进暂存区包括你可能不想提交的临时文件。我见过有人不小心把密钥文件、几百MB的日志文件提交进仓库然后整个团队都跟着遭殃。建议还是有明确意图地git add 具体文件或者先git status看清楚再决定。git add .要慎用——它会一股脑把所有改动都加进暂存区包括你可能不想提交的临时文件。我见过有人不小心把密钥文件提交进仓库整个团队都跟着遭殃。第二commit message不是随便写的。写update、fix这种含混信息三个月后你自己都看不懂。约定俗成的做法是类型: 简要描述比如fix: 修复用户登录时token过期问题、feat: 新增导出功能。团队有规范就按团队规范来没有的话起码做到能让人不看代码也大概知道这次改了什么。如果需要提交的文件比较多可以用git commit -am 说明它的作用是跳过暂存区直接把所有已跟踪文件的改动一起提交。注意新文件不在其中必须显式add。2.4 push与log推送到远程与查看历史git push origin 分支名把本地提交推送到远程仓库。如果远程设置了上游追踪直接git push即可。第一次推送新分支时命令会提示加-ugit push -u origin feature/xxx-u是把本地分支和远程分支绑定之后git push和git pull就可以直接输不用每次带远程名和分支名。查看提交历史我常用的组合git log --oneline --graph --decorate --all这个命令用一行显示一个提交用图形展示分支结构非常直观。--oneline精简输出--graph画分支线--decorate标注标签和分支指向--all显示所有分支历史。看团队协作的提交脉络这一条就够了。如果只是快速看最近几条git log --oneline -5更轻量。想查某个文件的历史变动用git log -- 文件名单独过滤。3. 分支实战创建、切换、合并与清理分支是Git最核心、也最有价值的能力。我见过太多人在分支管理上全凭记忆和勇气直接在master上改合并一出问题就整个人都不好了。分支操作弄明白日常开发效率能提升一个档次。3.1 创建与切换分支创建分支通常两种写法git branch feature/login # 创建分支但不切换 git checkout -b feature/login # 创建分支并切换过去新版Git还推荐用git switch替代checkout相关功能git switch -c feature/login创建并切换git switch feature/login切换到已有分支。switch语义更单纯只负责分支切换不容易像checkout那样让人迷惑。毕竟checkout还要兼顾还原文件的职能这是历史包袱。我的习惯是每次开发新功能一定新建分支绝不在master上直接改。有人觉得项目小、就自己一个人无所谓。但真实项目中主分支往往承担发布职责任何人直接往主分支上堆未验证代码都会让能不能发布变成一个黑盒。哪怕只有两三个人协作也建议遵守功能分支开发合并后删除分支保持主分支干净。3.2 分支合并merge与rebase怎么选把一个分支的改动合并到另一个分支最基础的操作是git merge 分支名比如当前在develop分支上想把feature分支合并进来git checkout develop git merge feature/loginGit默认会走Fast-forward合并如果有共同祖先且可以线性推进Git会直接移动指针如果两边都有分叉提交也会自动生成一个合并提交。如果你想强制保留分支合并的痕迹加--no-ff参数不希望生成合并提交的加--ff-only。还有一条路是rebasegit checkout feature/login git rebase developrebase和merge的区别在于提交历史形态。merge保留真实的合并结构历史看起来像带分岔的河流rebase会把当前分支的提交重放到目标分支顶端历史变成干净的直线。我个人的观点是提交历史是给后人看的如果不是必须尽量让历史清晰。团队协作时用merge保留合并点单个功能分支在合并前用rebase整理自己的提交这两种组合是我觉得比较健康的平衡。千万别在主分支上rebase也千万不要rebase别人已经push到远端的提交。rebase会重写提交哈希如果别人的提交已经被拉取过强制推送rebase结果会导致大家的分叉历史非常难收拾。3.3 冲突解决的完整链路合并时出现冲突conflict是最常见的Git把自己绕晕的时刻。实际原因是两个分支修改了同一段内容Git不知道怎么选。文件里会标着、、把冲突区域圈出来。我的处理流程是这样先跑git status看哪些文件冲突逐个打开冲突文件Git会把冲突区域标记出来手动确认保留哪边内容或者两边都保留修改完成后git add 冲突文件告诉Git这个冲突你处理好了继续git commitGit会自动生成一个合并提交。这里有个新手容易犯的错解决冲突时只想着把爆红删掉删了标记符号但内容选得不对。冲突解决的核心是你要理解这个文件的两个版本各自想表达什么而不是躲避警告。如果真的不确定最好和改动这两个分支的人沟通一下我帮同事解决过的绝大多数冲突都是因为两边各自改动同一处而没有对齐预期。3.4 分支删除与清理功能开发完、合并完了本地分支可以删git branch -d feature/login如果分支还没有合并过普通删除会报错这时要么确认真的不要了强制删git branch -D feature/login要么老老实实先把该合的内容合掉。-D是--delete --force目的是防止手滑丢掉未合并的工作。远程分支的删除命令是git push origin --delete feature/login如果本地有一堆已经合并过、早就该删的分支可以用git branch --merged查看哪些能删再配合批量操作清理。保持分支列表干净长期来看非常值。4. 撤销操作给你一颗后悔药写代码不可能永远一次到位撤销和改错是日常。但Git的撤销命令特别容易让新手吓得不敢动手因为reset、revert、checkout、amend这几个词长得太像了。我拆开来讲。4.1 commit --amend修改最近一次提交如果你刚git commit完马上发现漏了一个文件、或者message写错了这时候不用新建一个提交直接git commit --amend -m 新的提交说明它的逻辑是用一个新的提交替换最近一次提交。如果只是修改messagegit commit --amend后重新填说明即可如果还要补充文件先git add再git commit --amend。但这里有个重要提醒--amend会改写提交哈希所以如果这个提交已经push到远端且别人可能已经基于它工作了就不要amend了否则push时会冲突还得force push给别人造成困扰。理想的使用场景是提交还在本地、还没push随便改。4.2 reset与revert别再傻傻分不清git reset是把当前分支的HEAD指针往回移。配合不同参数影响范围不同git reset --soft HEAD~1 # 回到上次提交但改动留在暂存区 git reset --mixed HEAD~1 # 默认参数改动留到工作区 git reset --hard HEAD~1 # 改动直接丢弃危险操作要三思--soft常用于提交信息写错了想重新来一次提交--mixed常用于不想分成那么多次提交想合并成一次--hard是把代码彻底恢复到之前的状态本地所有改动都不要了。HEAD~1表示前一个提交~2表示前两个也可以直接写提交哈希。git revert则是完全不同的思路它不是把历史抹掉而是生成一个新的提交把某个旧提交的改动反向应用回去。比如git revert abc123会创建一个撤销了abc123这个提交的新提交。这样历史是完整的适合已经push到远端的提交、或者多人协作的分支上做撤销。我个人的铁律是还没push的提交用reset已push的提交用revert。4.3 手滑reset之后reflog怎么捞git reset --hard误操作之后代码丢了吗绝大多数情况没有。Git有个日志叫reflog记录了所有HEAD移动的痕迹git refloggit reset --hard并不是真的删除提交对象只是让HEAD不再指向它。只要这个提交还没被Git的垃圾回收机制清理通常至少在90天内你就能从reflog里找到它当时的位置然后git reset --hard 哈希或者git cherry-pick 哈希把它救回来。我有一次搞砸了整天的改动经理在旁边看着我心都凉了结果跑了一下git reflog发现之前的提交都还在一条一条捞回来那是Git第一次让我觉得这工具靠谱。这个习惯我一直保持着越慌越要看reflog乱输入只会更糟。4.4 撤销场景速查表下面这个表是我贴在自己工作文档里的遇到不确定直接查场景推荐命令注意事项提交说明写错了未pushgit commit --amend -m 新说明仅限未推送的提交漏提交了一个文件未pushgit add 文件 git commit --amend会改写哈希想撤掉已push的提交git revert 哈希保留历史推荐想彻底放弃本地改动git checkout -- 文件或git restore 文件丢弃工作区改动想回退本地多次提交未pushgit reset --hard HEAD~n确认无可挽回再操作误reset后找回git reflog先看再动5. 那些让你抓狂的Git疑难杂症最后这部分我专门聊几个高频出现的诡异问题。这些问题不是命令不会用而是对Git的运行机制理解有偏差或者说环境坑太深。5.1 .gitignore不生效不是它没生效是文件已经被追踪有个问题我收到过好多次求助明明在.gitignore里加了某个文件它还是出现在git status里。原因很简单——.gitignore只管尚未被Git跟踪的文件。如果这个文件之前已经被git add或者提交过它就在Git的追踪名单里.gitignore对已追踪文件是不生效的。解决办法是先从追踪名单里移除再补上.gitignore规则git rm --cached 文件--cached表示只把文件从暂存区/追踪名单里移除不动本地实际文件。如果是一整个目录用git rm -r --cached 目录。执行完之后提交一次后续该文件才会被ignore规则正确忽略。还有一个隐藏很深的情况.gitignore规则本身写得不匹配。比如你写了*.log但实际文件是logs/debug.txt那就根本不在匹配范围。Git的忽略规则支持/开头表示目录级别**表示任意中间层目录具体写法值得花十分钟看一下官方文档。在生产环境部署时也要注意别把.git目录暴露到Web根目录这个目录里存着完整历史泄露出去等于把源码奉上。5.2 Git LFS安装、track与clone卡住的排查仓库里有大文件比如设计稿、二进制模型、数据集直接用Git托管会撑爆仓库这时候需要Git LFSLarge File Storage。这套机制把大文件替换成指针真正的文件内容存到远端LFS服务上本地工作区在需要时才拉取。安装使用的基本流程git lfs install git lfs track *.psd git add .gitattributes # track规则会写进这个文件 git add 大文件 git commit -m add big file git push我实际遇到过的LFS问题主要有两个。一是clone大仓库卡住大概率是因为仓库里LFS文件数量多、体积大建议用git lfs pull或先设置GIT_LFS_SKIP_SMUDGE1跳过自动下载只拉指针文件用到时再按需git lfs pull --include取特定文件。二是某些历史版本LFS和Git版本不兼容升级Git版本后莫名解决。如果你在配置里看到git config --global --unset lfs.fetchexclude这类命令它通常用于清除以前设置过的LFS拉取排除规则比如某个目录被配置为不自动拉取后来想恢复就unset掉。这类命令按实际情况调整即可不必背。5.3 CRLF与换行符团队协作的隐性大坑前面安装部分埋了换行符的伏笔这里展开。Windows上开发的同事提交代码时Git把CRLF转成了LF没问题。但有人没有配core.autocrlf把CRLF原样提交了然后Linux同事拉下来整个文件的每一行都会被标记为改动实际上内容一模一样只是换行符不同。处理这类问题的正规武器是.gitattributes文件在仓库根目录写* textauto *.bat text eolcrlf *.sh text eollf这比每个人改自己的全局配置要靠谱因为规则是跟着仓库走的全团队生效。我在维护的仓库里都会放一个.gitattributes避免换行符问题反复出现。已经混入历史的错误换行符可以用git config --global core.autocrlf true配合重新检出处理但如果仓库历史已经乱掉往往需要一次性重新归一化操作前一定要备份。5.4 SSH认证失败与提交账户错误ssh: connect to host github.com port 22: Connection timed out或者Permission denied (publickey)这类报错多数是密钥没配好或SSH端口不通。几个排查步骤按顺序ssh -T gitgithub.com看具体报错确认~/.ssh/id_ed25519.pub内容是否已经贴到平台检查~/.ssh/config里有没有多余配置干扰端口不通的可以试试改用443端口。提交账户错误的问题我也遇到过本来该用公司邮箱提交结果用的是个人GitHub的全局配置历史记录里身份信息全串掉。解决办法是对特定仓库单独设置local配置git config user.name 公司名 git config user.email 公司邮箱如果历史提交已经暴露可以配合git filter-branch或git rebase -i改写但这是个危险操作强烈建议先备份仓库再说。6. 一点个人使用习惯的分享写到这里分享几个我长期坚持的小习惯算不上教程就是实在好用。6.1 我从上班到下班的工作流每天早上到工位第一件事git status看看昨天有没有留尾巴然后git fetch --prune把远端分支变化同步下来。接着git log --oneline --graph -15快速扫一眼项目动向看看同事有没有合入什么重要改动。一天开发结束前git diff检查自己今天所有改动确认没有测试代码、密钥等漏网之鱼后再add和commit最后git push。这样做的好处是每天早上和晚上各看一次全局提交历史不会出现我昨天改啥了的失忆状态。尤其是git fetch --prune这条命令它只更新远程跟踪引用不影响工作区代码比git pull安全得多适合随时查看远端最新状态。6.2 stash临时切换场景的保命技能开发到一半被叫去处理另一个紧急bug或者切换分支的时候发现工作区有未提交的改动导致切换报错这时候git stash把当前改动暂存起来工作区就干净了。处理完紧急事项后git stash pop恢复。git stash默认只暂存已跟踪文件的改动如果要连新文件一并暂存得用git stash -u。查看stash列表用git stash list。遇到多个stash堆叠恢复指定条目用git stash apply stash{1}然后手动清理git stash drop stash{1}。注意apply和pop的区别pop是取出并从列表删除apply是取出但保留列表项。6.3 配置alias让高频命令再短一点每天敲几十遍的命令值得用alias缩短git config --global alias.st status git config --global alias.co checkout git config --global alias.br branch git config --global alias.lg log --oneline --graph --decorate --all配完之后git st、git lg就直接可用了。我自己的alias清单里还有一个git ci对应commit、git pl对应pull。需要注意的是alias只是方便别配一些自己都记不住的花哨缩写团队协作时尽量输出原始命令给别人看减少沟通成本。另外几个长期习惯主分支从来不直接rebase和强推紧急情况先stash再行动绝不慌着乱敲命令每接手一个新仓库先看分支图和README再动手。Git命令看着多但真正高频的来回就那一二十条。把这二十条的逻辑彻底搞明白剩下的都是查表题。用好Git的关键不在背命令而在理解它那套工作区—暂存区—本地仓库—远程仓库的流动模型理解了模型命令只是顺手的工具。
返回列表