topic: beginner

高效掌握 Git:最常用命令与面试高频问题总结

写在前面:Git这门技术吧,说简单也简单,说复杂也复杂。简单是因为日常操作就那么几个命令,复杂是因为背后涉及的概念和工作流可以很深。这篇文章咱们不整虚的,就聊聊实际工作中真正能用到的干货,以及面试中容易被问到的高频问题。


topic: beginner

一、实际工作中最常用的 Git 命令

兄弟们,日常开发其实用不了那么多花里胡哨的命令。下面这些命令能覆盖90%以上的场景,剩下那10%用到的时候再查文档也来得及。

入门级:代码同步三板斧

1
2
3
4
5
6
7
8
# 克隆远程仓库 - 第一次拿到项目时用
git clone https://github.com/username/project.git

# 拉取最新代码 - 每天上班第一件事
git pull

# 推送本地提交 - 每天下班前最后一件事
git push

这三板斧记住了,你已经可以安全地在Git仓库里混日子了(不是)。

进阶级:查看状态和历史

1
2
3
4
5
6
7
8
9
10
11
# 查看当前状态 - 不知道自己改了什么时就用它
git status

# 查看文件变更 - 比status更详细,可以看到具体改了哪行
git diff
git diff README.md #只看某个文件

# 查看提交历史 - 项目debug时经常会看
git log
git log --oneline # 简洁版,一行显示一个提交
git log --graph --oneline # 带分支图的版本

实战级:分支操作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 查看分支
git branch

# 创建新分支(但不切换)
git branch feature/new-login

# 创建并切换到新分支 - 这个更常用
git switch -c feature/new-login
# 或者老派写法
git checkout -b feature/new-login

# 切换分支
git switch main
git checkout main

# 删除本地分支
git branch -d feature/old-feature

# 删除远程分支
git push origin --delete feature/old-feature

核心级:提交操作

1
2
3
4
5
6
7
8
9
10
# 添加文件到暂存区
git add filename.md # 单个文件
git add . # 所有文件
git add -p # 交互式添加,可以选择性地添加每一处修改

# 提交
git commit -m "修复了登录页面的样式问题"

# 一步到位(不推荐新手使用,容易出错)
git commit -am "修复bug" # 只能提交已跟踪文件的修改

骚操作级:撤销和修改

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 撤销工作区的修改(危险!不可恢复)
git checkout -- filename.md

# 撤销暂存区的文件(回到工作区)
git reset HEAD filename.md

# 撤销提交(但保留修改在工作区)- 软撤销
git reset --soft HEAD~1

# 撤销提交(不留任何痕迹)- 硬撤销,慎用!
git reset --hard HEAD~1

# 创建一个新提交来“撤销”之前的提交(安全版本)
git revert HEAD
git revert abc1234

远程操作高级玩家

1
2
3
4
5
6
7
8
9
10
11
# 只下载,不合并 - 适合想先看看有什么变化的情况
git fetch origin

# 查看远程分支
git remote -v

# 添加另一个远程仓库
git remote add upstream https://github.com/original/repo.git

# 拉取并rebase(保持提交历史线性)
git pull --rebase origin main

topic: beginner

二、分支管理策略:没有规矩不成方圆

光会命令不行,你还得知道怎么组织代码。不同团队可能用不同的工作流,给你介绍几种最常见的:

1. Git Flow:老牌稳重型

这个应该是最经典的了,适合有固定发布周期的项目。

1
2
3
4
5
6
7
8
# 主要分支
main/master # 生产环境代码
develop # 开发主分支

# 辅助分支
feature/* # 功能分支,从develop拉
release/* # 发布分支,从develop拉
hotfix/* # 紧急修复,从main拉

优点:流程清晰,适合大团队
缺点:分支太多,显得有点重

2. GitHub Flow:轻量级

1
2
3
4
5
6
# 永远从main拉分支
git switch -c feature/my-awesome-feature

# 开发完成后发PR
# 代码审查通过后合并到main
# 自动部署

优点:简单粗暴,适合小团队和持续部署的项目
缺点:没有release分支,不太适合有固定发版周期的项目

3. Trunk-Based Development:激进派

1
2
3
# 开发者直接往main/trunk提交
# 依靠特性开关(Feature Flags)控制功能上线
# 适合大规模团队协作

这个比较极端,一般团队hold不住,了解一下就行。


topic: beginner

三、面试中最常见的 Git 问题与高分答案

Q1: 什么是 Git?与 SVN 有何区别?

考察点: 分布式 vs 集中式版本控制系统的核心区别

答:
Git 是分布式版本控制系统(DVCS)。每个开发者本地都有一份完整的仓库历史,这意味着你可以离线查看所有提交记录、创建分支、提交代码。SVN 是集中式版本控制系统,所有操作都依赖中心服务器,服务器挂了大家就都歇菜了。

核心区别:

  • 分布式:本地即完整仓库,断网也能工作,分支操作轻量级
  • 集中式:依赖服务器,网络不好的时候很难受,分支往往意味着完整拷贝

从实际开发角度,Git 的分支创建和切换几乎是瞬时的,而 SVN 的分支操作要慢得多。


topic: beginner

Q2: Git 的三个核心区域是什么?

考察点: 理解 Git 的工作原理

答:
Git 有三个核心区域:

  1. 工作区(Working Directory):就是你本地正在编辑文件的地方,肉眼可见的那个文件夹
  2. 暂存区(Staging Area / Index):这是一个“准备提交”的缓冲区,你用 git add 就是把文件从工作区放到这里
  3. 仓库(Repository).git 目录,存放所有的提交历史和版本信息

它们的关系是这样的:

1
工作区 → git add → 暂存区 → git commit → 仓库

理解这个很重要,因为它直接影响你能不能精确控制每次提交的内容。


topic: beginner

Q3: 什么是 Commit?如何写好 Commit Message?

考察点: 代码规范意识

答:
Commit 是代码仓库的一个快照,包含作者、时间戳、提交信息,当然还有实际的代码变更。

好的 Commit Message 应该:

  • 首行简洁明了,控制在50字符以内,说明你这次提交做了什么
  • 如果有必要,空一行后写详细说明,解释为什么这么做
  • 使用祈使句,比如 “Add user login” 而不是 “Added user login” 或 “adding user login”

实际例子:

1
2
3
4
5
Add user authentication flow

Implement login/logout with JWT tokens.
Store refresh token in httpOnly cookie.
Fixes #123

topic: beginner

Q4: 为什么要用分支(Branch)?

考察点: 并行开发能力理解

答:
分支的主要作用是:

  1. 隔离开发任务:新功能开发、Bug修复、实验性功能互不影响
  2. 保持主分支稳定:生产环境的代码应该是稳定可用的
  3. 支持并行开发:多个开发者可以同时在不同的分支上工作
  4. 便于代码审查:通过 Pull Request/Merge Request 进行Code Review

简单说,分支让你可以在不影响别人的情况下“大展拳脚”。


topic: beginner

Q5: git fetch 和 git pull 有什么区别?

考察点: 对 Git 工作原理的理解深度

答:

  • git fetch:相当于“只下载,不安装”。它会从远程仓库拉取最新的提交和分支信息,但不会自动合并或修改你当前的代码。你 fetch 完之后,可以用 git diff 看看有什么变化,再决定要不要合并。
  • git pull:相当于 git fetch + git merge。它不仅下载远程更新,还会自动合并到当前分支。

我的习惯是:如果是多人协作的分支,我会先用 git fetch,看看有什么变化,再决定用 merge 还是 rebase。直接 git pull 有时候会引入不必要的合并提交。


topic: beginner

Q6: .gitignore 有什么作用?应忽略哪些文件?

考察点: 项目整洁意识

答:
.gitignore 指定哪些文件不应该纳入版本控制。

应该忽略的文件类型:

  • 依赖目录node_modules/, vendor/, venv/
  • 构建输出dist/, build/, out/
  • 临时文件*.log, *.tmp, .DS_Store
  • 敏感信息.env(包含API密钥、数据库密码等)
  • IDE配置*.iml, .idea/, .vscode/(可选)
1
2
3
4
5
6
# .gitignore 示例
node_modules/
dist/
.env
*.log
.DS_Store

topic: beginner

Q7: 合并冲突(Conflict)如何解决?

考察点: 实际动手能力

答:
合并冲突一般发生在两个分支修改了同一文件的同一部分,Git不知道该保留哪个。

解决步骤:

  1. 打开冲突文件,会看到类似这样的标记:
    1
    2
    3
    4
    5
    <<<<<<< HEAD
    const a = 1;
    =======
    const a = 2;
    >>>>>>> feature-branch
  2. 手动编辑,保留你需要的代码,删除 <<<<<<<=======>>>>>>> 这些标记
  3. git add 解决后的文件
  4. git commit 完成合并

小技巧:用 VS Code 或其他IDE,它们有很好的冲突解决UI,会让你选择保留哪一边的修改,或者两边都保留。


topic: beginner

Q8: 如何撤销提交?git reset 和 git revert 区别?

考察点: 对Git历史的理解

答:
这两个命令都可以“撤销”,但方式完全不同:

git reset:回到过去的某个状态

  • --soft:回到暂存区,修改保留
  • --mixed(默认):回到工作区,修改保留
  • --hard:直接丢弃修改,危险!
1
2
3
4
5
# 撤销最后一次提交,但保留修改在本地
git reset --soft HEAD~1

# 撤销最后三次提交,完全丢弃
git reset --hard HEAD~3

git revert:创建一个新提交来“反做”某个提交

1
2
# 撤销指定的提交,会生成一个新的提交
git revert abc1234

怎么选:

  • 如果是本地未推送的提交,用 reset 没问题
  • 如果是已经推送到远程的公共分支,必须用 revert,因为 reset 会修改历史,可能影响别人

topic: beginner

Q9: 暂存区(Staging Area)为什么重要?

考察点: 对Git工作流的理解

答:
暂存区是 Git 最强大的特性之一,它让你可以:

  1. 精确控制提交内容:你可以只提交部分修改,而不是把所有改动一次性交出去
  2. 分步提交:一个功能分多次提交,每次提交都有清晰的意义
  3. 代码审查准备:在提交前可以仔细检查暂存区的内容

举例:

1
2
3
4
5
# 你修改了两个文件,但只想提交其中一个
git add login.js
git commit -m "修复登录bug"

# 另一个文件的修改还在工作区,下次再提交

topic: beginner

Q10: 你常用的 Git 工作流?

考察点: 团队协作经验

答:
一般是这样的:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 1. 每天早上先同步主分支
git checkout main
git pull

# 2. 从主分支创建自己的功能分支
git switch -c feature/user-profile

# 3. 开发过程中,定期同步主分支的更新
git fetch origin
git rebase origin/main # 用rebase保持历史线性

# 4. 功能开发完成
git push -u origin feature/user-profile

# 5. 在GitHub/GitLab创建Pull Request
# 6. 代码审查通过后,合并到主分支

topic: beginner

四、实战技巧:工作中非常好用的Git技能

技巧1:交互式变基(Interactive Rebase)

这个技能堪称“后悔药”,可以修改提交历史:

1
2
# 修改最近3个提交
git rebase -i HEAD~3

在打开的编辑器里,你可以:

  • pick - 保留这个提交
  • reword - 修改提交信息
  • edit - 暂停在这个提交,可以修改文件
  • squash - 将这个提交合并到前一个提交
  • drop - 删除这个提交

技巧2:Cherry-Pick:挑拣提交

有时候你只需要某个分支上的某一个提交,而不是整个分支:

1
2
3
4
5
# 把某个提交应用到当前分支
git cherry-pick abc1234

# 挑拣多个提交
git cherry-pick abc1234 def5678

技巧3:Stash:临时保存工作区

正在改代码,突然要切换分支做紧急修复,但不想提交:

1
2
3
4
5
6
7
8
9
10
11
# 保存当前工作区
git stash

# 切换分支干完活回来
git stash pop

# 查看 stash 列表
git stash list

# 指定恢复某个 stash
git stash apply stash@{2}

技巧4:Reflog:恢复“丢失”的提交

不小心 reset –hard 了?或者删错了分支?别慌:

1
2
3
4
5
6
# 查看所有操作历史
git reflog

# 恢复到这个提交
git checkout HEAD@{2}
git branch recovered-branch HEAD@{2}

技巧5:Bisect:二分查找问题提交

项目突然出bug了,但不知道是哪次提交导致的?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 开始二分查找
git bisect start

# 标记当前版本是有问题的
git bisect bad

# 标记一个正常的版本
git bisect good v1.0.0

# Git会自动checkout中间的提交
# 测试一下有没有问题
git bisect good # 或者 git bisect bad

# 重复这个过程,直到找到问题提交
# 完成后
git bisect reset

topic: beginner

五、常见陷阱和如何避免

陷阱1:提交了敏感信息到远程

1
2
3
4
# 如果你刚提交就发现了,立刻撤销
git reset --hard HEAD~1

# 然后修改 .gitignore,确保下次不会再提交

如果已经推送到远程了:

1
2
# 只能使用 git filter-branch 或者 git rebase 来重写历史
# 这是个危险操作,建议搜索专业教程

陷阱2:在错误的分支上开发

1
2
3
4
5
6
# 刚提交了一个commit,才发现切错分支了
# 很简单,把 commit 移到正确的分支
git branch feature-correct
git reset --hard main
git checkout feature-correct
# 那个 commit 还在你的 reflog 里

陷阱3:合并时丢失代码

1
2
3
4
5
# 合并后如果发现有问题,可以中止合并
git merge --abort

# 如果已经提交了合并,可以用 revert 撤销
git revert -m 1 HEAD

topic: beginner

总结

  • 命令要精:上面列出的常用命令,足够你应对日常开发和面试了
  • 理解原理:知道三个区域、分支策略、撤销的区别,比背命令更重要
  • 多用多练:Git 是那种“看一百遍不如动手一遍”的技术
  • 注意安全:push 之前多看几眼,reset –hard 之前多确认几遍

希望这篇文章能帮你在 Git 学习和面试中少走弯路。如果觉得有用,点个赞、在看、打赏(不是)都可以,咱们下期再见!


topic: beginner

参考资料:

  • [1] Pro Git Book(免费电子书的)
  • [2] 猴子都能懂的Git入门
  • [3] Git官方文档
  • [5] 深入理解Git子模块
  • [6] Git分支管理策略
  • [7] 分布式版本控制系统详解
  • [8] Commit Message最佳实践
  • [9] git reset vs git revert 详解
  • [10] Git工作流与协作模式