大家好,我是老王。一个在代码世界里摸爬滚打了快十年的个人开发者。平时主要写后端,前端也折腾过几年。这些年代码写了不少,坑也踩了一堆。其中,有一个工具,几乎每天都在用,那就是Git。今天我想以一个过来人的身份,跟大家聊聊Git,从最初的理解到现在的日常使用,最后整理一下那些我最常用的命令。这篇文章不是什么官方文档,也不是教科书,就是老王我这些年用下来的一些真实体会和总结,希望能对大家有点帮助。
先说说为什么我要聊Git。记得大学刚开始写代码那会儿,还是手动复制文件夹来备份代码。比如今天写了个功能,怕改坏,就复制一份叫“项目_v1”,明天再改,再复制一份叫“项目_v2”。这么搞文件夹一堆,找起来麻烦不说,还经常弄混。后来毕业后这种原始方法彻底不行了。这时候,版本控制工具就进入了我的视野。一开始用过SVN,但自从接触了Git,感觉打开了新世界的大门。Git是分布式版本控制,每个人本地都有完整的仓库,离线也能干活,分支管理又灵活,这些特性让我很快就爱上了它。
所以Git到底是什么?简单说,它就是一个帮你管理代码历史记录的工具。你可以随时保存代码的某个状态,以后任何时候都能回退回去。多人协作时,大家可以并行开发,最后合并代码。其实Git的核心概念是仓库、提交、分支和远程仓库。仓库就是存放项目所有历史记录的地方;提交是你的每一次代码改动记录;分支是开发线的隔离,比如你可以在一个分支上修bug,在另一个分支上加功能;远程仓库是大家共享代码的地方,比如GitHub或GitLab。
刚开始学Git的时候,我也觉得命令多,记不住。但用多了就发现,核心命令就那几个,日常开发基本够用。剩下的遇到具体问题再查就行。老王我在这里不打算从零开始讲Git的安装,因为网上教程太多,而且不同系统安装方法不一样。我假设大家已经装好了Git,准备开始一个新项目。
第一步先初始化一个仓库。在你的项目文件夹里,终端输入git init。这个命令会创建一个隐藏的.git文件夹,里面存放了所有版本历史。从此,这个文件夹就受Git管理了。如果你是从别人那里拿到的项目,可能用的是git clone命令,从远程仓库复制一份到本地。比如git clone https://github.com/username/repo.git,这样你就有了一个完整的本地副本。
初始化之后,Git会告诉你当前在“master”分支(新版本Git默认叫“main”)。你可以用git status看看当前仓库的状态。这个命令老王我几乎每天都用,它会告诉你哪些文件被修改了,哪些还没被跟踪。比如,你加了个新文件,Git会提示它未被跟踪;你改了已有文件,Git会提示它被修改但未暂存。这个命令是理解Git工作流程的起点。
Git的工作流程有三个核心区域:工作目录、暂存区和仓库。工作目录就是你实际编辑文件的地方。
暂存区(也叫索引)是你准备下次提交的内容;仓库是永久保存的历史。你修改文件后,用git add把改动加到暂存区,然后用git commit提交到仓库。这个设计很巧妙,允许你精确控制每次提交包含什么内容,避免一次性提交所有改动导致混乱。
说到git add,这个命令使用频率很高。最简单的用法是git add 文件名,把指定文件加到暂存区。但老王我更常用git add .,加当前目录所有改动。不过要注意,如果项目里有敏感文件或临时文件,最好先配置.gitignore,避免误提交。.gitignore文件可以指定哪些文件或文件夹Git应该忽略,比如编译产物、日志文件、IDE配置等。参考Git官方文档,这个文件写法很灵活,可以用通配符匹配。
暂存区准备好后,就该提交了。git commit -m "提交信息"是最基本的提交命令。提交信息很重要,老王我见过太多提交信息写“update”或“fix bug”的,过几个月自己都看不懂改了啥。好的提交信息应该简明扼要,说明为什么改和改了什么。比如“修复用户登录时的空指针异常”比“fix bug”强多了。如果改动很多,可以用git commit -a -m直接提交所有已跟踪文件的改动,跳过暂存区。但老王我建议还是用git add精细控制,尤其在大项目中。
提交完,可以用git log查看历史记录。这个命令输出一堆提交哈希、作者、日期和提交信息。老王我常用git log --oneline简化输出,只显示哈希前几位和提交信息,便于快速浏览。如果想看图形化分支历史,git log --graph --oneline --all很实用,尤其在分支多的时候。Git还允许你查看特定提交的详细改动,用git show 提交哈希或git diff 提交1 提交2比较两次提交的差异。
分支是Git的强项。老王我开发新功能时,总是新建一个分支,避免影响主分支。创建分支用git branch 分支名,切换分支用git checkout 分支名(新版本Git推荐用git switch 分支名)。更常用的是git checkout -b 分支名,创建并切换。比如git checkout -b feature-user-auth,就新建了一个用户认证的功能分支。在分支上开发完,合并回主分支。合并用git merge 分支名,比如在主分支上执行git merge feature-user-auth,就把功能分支的改动合并过来了。
合并时可能会遇到冲突,这是Git学习曲线的痛点。冲突发生时,Git会标记冲突文件,你需要手动编辑解决,然后重新提交。老王我的经验是,频繁合并主分支到自己的功能分支,减少冲突规模。另外,Git提供了git rebase命令,用于变基操作,可以把你的分支改动应用到另一个分支上,保持历史线性。但rebase有风险,因为它重写历史,所以只在个人分支或明确知道后果时使用。官方文档强调,已经推送的提交不要轻易rebase。
日常开发中,远程仓库是协作的核心。用git remote -v查看已配置的远程仓库。添加远程仓库用git remote add origin 远程URL。推送代码到远程用git push origin 分支名,比如git push origin main。拉取远程更新用git pull origin 分支名,这实际上是git fetch(下载远程改动)和git merge的组合。老王我习惯先git fetch查看远程改动,再决定是否合并,避免意外冲突。
如果远程仓库有更新,但你本地有改动,Git会拒绝推送,除非你先拉取。这时,可以用git pull --rebase试试,用rebase方式合并,保持历史干净。但最稳妥的还是先提交本地改动,再拉取合并。
另一个常用命令是git stash,用于临时保存工作目录的改动。比如你正在开发功能,突然要切分支修紧急bug,可以用git stash保存当前进度,修完bug再git stash pop恢复。这比提交一个半成品 commit 再回退要干净。
标签(tag)用于标记重要版本,比如发布版本。用git tag 标签名创建轻量标签,或git tag -a 标签名 -m "信息"创建附注标签。推送标签到远程用git push origin 标签名。老王我在发布PHP项目时,总是打标签,方便回滚。
Git还有一些撤销和恢复的命令。git checkout -- 文件名可以丢弃工作目录的改动,恢复到上次提交状态。如果想撤销暂存区的改动,用git reset HEAD 文件名。更彻底的,git reset --hard 提交哈希会回退到指定提交,丢弃之后的所有改动,一定要慎用!如果想撤销一个已推送的提交,但保留历史,用git revert 提交哈希,它会生成一个新的反向提交。
还有在特定语言的项目中,Git的使用可能存在些细微差别。比如PHP项目通常有composer依赖,我总把vendor目录加到.gitignore,避免提交庞大依赖。在比如Go项目则要忽略bin和pkg目录。还有前端Vue、React等项目,node_modules绝对不能提交。
文章写的我手都累了,老王我再总结一些主流的命令吧:
1. 基础配置与初始化
#配置用户信息(全局生效)git config --global user.name "Your Name"git config --global user.email "your.email@example.com"# 初始化本地仓库git init# 克隆远程仓库git clone https://github.com/user/repo.git# 查看当前仓库配置git config --list
2. 分支管理
# 查看分支(本地+远程)git branch -a# 创建新分支git branch feature-login# 切换分支git checkout feature-login# 创建并切换分支(推荐)git checkout -b feature-login# 删除已合并的分支git branch -d feature-login# 强制删除未合并分支(谨慎使用)git branch -D feature-login# 重命名当前分支git branch -m new-name
3. 暂存区与提交
# 查看工作区状态git status# 查看详细变更(含增删改)git diff# 添加指定文件到暂存区git add filename# 添加所有变更(新文件、修改、删除)git add .# 提交暂存区内容到本地仓库git commit -m "feat: 添加登录功能"# 提交并跳过暂存区(仅限已跟踪文件)git commit -am "fix: 修复登录bug"# 修改最后一次提交(不生成新commit)git commit --amend -m "修正提交信息"
4. 远程仓库操作
# 查看远程仓库地址git remote -v# 添加远程仓库git remote add origin https://github.com/user/repo.git# 推送本地分支到远程git push -u origin main # -u 设置上游,后续可直接git push# 拉取远程变更到本地(合并到当前分支)git pull origin main# 抓取远程变更(不自动合并)git fetch origin# 查看远程分支状态git remote show origin
5. 历史记录与版本回退
# 查看提交历史(简洁)git log --oneline# 查看图形化分支历史git log --graph --oneline --all# 查看指定文件的修改历史git log -p filename# 回退到指定提交(工作区内容会保留)git reset --soft commit_id# 回退到指定提交(暂存区同步回退)git reset --mixed commit_id # 默认模式# 回退到指定提交(工作区内容也会被覆盖,谨慎!)git reset --hard commit_id# 撤销工作区修改(未add的文件)git checkout -- filename# 撤销暂存区文件(回到工作区)git reset HEAD filename# 查看某次提交的详细内容git show commit_id
6. 标签管理
# 创建轻量标签git tag v1.0.0# 创建带注释的标签git tag -a v1.0.0 -m "正式版发布"# 查看所有标签git tag# 推送标签到远程git push origin v1.0.0# 删除本地标签git tag -d v1.0.0# 删除远程标签git push origin --delete v1.0.0
7. 团队协作与冲突处理
# 合并指定分支到当前分支git merge feature-branch# 变基当前分支到目标分支(保持线性历史)git rebase main# 变基时遇到冲突,手动解决后继续git rebase --continue# 放弃变基并回到变基前状态git rebase --abort# 查看冲突文件git status# 冲突解决后标记为已解决git add resolved-file# 暂存当前工作(临时切换分支时使用)git stash# 恢复暂存的工作git stash pop# 查看所有暂存记录git stash list
8. 进阶与清理
# 查看仓库大小git count-objects -vH# 清理未被引用的对象(已删除分支的残留)git gc --prune=now# 查看文件忽略规则git check-ignore -v filename# 查看当前分支与远程分支差异git diff main origin/main# 查看当前分支领先/落后远程多少提交git status -b
9. 实用技巧
# 交互式暂存(选择性提交部分修改)git add -p# 交互式变基(修改、合并、删除提交)git rebase -i HEAD~5# 查看某行代码的最后修改者git blame filename# 快速定位引入bug的提交(二分查找)git bisect startgit bisect badgit bisect good <good-commit>
这些命令基本能覆盖90%的日常需求。剩下的,遇到问题查文档或用git help就行。Git官方文档很全面,老王我建议大家至少通读一遍基础部分。
总之Git不只是工具,更是开发习惯。它让你敢于尝试,因为知道可以回退。它促进团队协作,因为历史透明。这篇文章纯属老王个人经验,希望能帮到大家。如果有疑问,欢迎在评论区讨论。记住,实践出真知,多敲命令,少看理论。好了,老王我去写代码了,下次再聊。

(感谢您的点赞!关注这个公众号,一起来探索编程的意义)