git学习笔记整理 | 豆包MarsCode AI刷题

150 阅读18分钟

Git

Git 是目前最流行的分布式版本控制系统,广泛应用于软件开发、团队协作和代码管理。

快速跳转到常用命令总结


一、Git 的主要功能

  1. 版本控制

    • 跟踪文件的历史版本,便于回溯和恢复。
    • 支持对项目的增量式更改进行记录,形成提交(commit)历史。
  2. 分支管理

    • 创建独立的开发分支,便于实现功能开发、Bug 修复等任务。
    • 支持分支合并,简化不同工作流的集成。
  3. 分布式架构

    • 每个开发者的本地仓库都是完整的代码仓库,支持离线操作。
    • 与中央仓库同步时可以实现多人协作。
  4. 代码对比与合并

    • 提供工具对比文件差异。
    • 支持复杂的代码合并操作,避免冲突或解决冲突。
  5. 高效性

    • 操作本地仓库的速度非常快,适用于大规模项目。

二、Git 的基础使用方法

1. Git 的安装与配置

安装 Git 后需进行全局配置:

git config --global user.name "你的名字"
git config --global user.email "你的邮箱"

查看当前配置:

git config --list

2. 基本操作流程

  1. 初始化仓库

    git init
    

    在当前目录下创建一个 Git 仓库。

  2. 查看仓库状态

    git status
    

    检查文件变动和当前分支状态。

  3. 添加文件到暂存区

    git add <文件名>
    

    添加文件或目录到暂存区。

  4. 提交到本地仓库

    git commit -m "提交信息"
    
  5. 查看提交历史

    git log
    

    显示提交历史记录。


三、远程仓库操作

  1. 克隆远程仓库

    git clone <远程仓库地址>
    

    将远程仓库复制到本地。

  2. 推送到远程仓库

    将本地分支的提交推送到远程仓库:

    git push origin <分支名>
    

    首次推送新分支(设置上游分支):

    git push -u origin <分支名>
    
  3. 拉取远程仓库代码

    git pull
    
  4. 关联远程仓库

    git remote add origin <远程仓库地址>
    

    将本地仓库与远程仓库关联。

  5. 查看远程仓库地址

    git remote -v
    

    查看当前关联的远程仓库。

  6. 修改远程仓库地址

    git remote set-url origin <新的远程仓库地址>
    

    如果远程仓库地址发生变化,可以修改。

  7. 删除远程仓库地址

    git remote remove origin
    

    如果不再需要关联某远程仓库,可以删除。


三、分支操作

  1. 创建分支

    git branch <分支名>
    
  2. 切换分支

    git checkout <分支名>
    
  3. 创建并切换到新分支

    git checkout -b <分支名>
    
  4. 合并分支

    • 切换到目标分支(如 main),然后执行:

      git merge <分支名>
      
  5. 删除分支

    git branch -d <分支名>
    

四、团队实践(实战干货)

  1. 代码托管

    • 使用平台如 GitHub、GitLab 或 Gitee 托管代码。
    • 确保每个开发者都克隆远程仓库并保持同步。
  2. 分支策略

    • 主分支(main/master) :稳定分支,仅用于发布或交付。
    • 开发分支(develop) :用于合并功能分支和集成测试。
    • 功能分支(feature/xxx) :单独开发特定功能,完成后合并到开发分支。
    • 修复分支(hotfix/xxx) :紧急 Bug 修复后直接合并到主分支和开发分支。
  3. Pull Request / Merge Request

    • 提交代码前,发起 Pull Request 请求,便于团队成员进行代码评审。
    • 避免直接向主分支推送代码。
  4. 代码合并

    • 优先使用 git merge 合并分支。
    • 对于需要清晰历史的项目,考虑使用 git rebase

    关于 git mergegit rebase 的区别和使用场景,更详细的请看下方八股文部分。 立即跳转

  5. 解决冲突

    • 使用 Git 提供的工具(如 VS Code 或命令行工具)解决冲突。
    • 提交解决冲突后的更改,并与团队成员沟通。
  6. 提交规范

    • 提交信息清晰简洁,包含变更的概要和原因:

      [类型] 功能描述
      

      常见类型包括:

      • feat:新增功能
      • fix:Bug 修复
      • docs:文档修改
      • refactor:代码重构
      • test:测试相关

五、版本控制(实战干货)

  1. 小步提交

    • 每次提交应集中在一个小功能或单一修复上,便于跟踪。
  2. 保持主分支干净

    • 主分支始终保持稳定状态,所有开发任务应基于分支完成。
  3. 定期同步

    • 定期拉取远程仓库更新,避免与团队代码产生冲突。
  4. 标签管理

    • 为里程碑版本打标签,便于版本追踪:

      git tag -a <标签名> -m "标签描述"
      
  5. 备份远程仓库

    • 确保代码定期推送到远程仓库,防止本地损坏导致数据丢失。

六、常用命令总结

常用命令总结

命令功能说明
git init初始化本地仓库
git clone克隆远程仓库到本地
git status查看仓库状态
git add添加文件到暂存区
git commit提交文件到本地仓库
git push推送到远程仓库
git pull拉取远程更新并合并
git branch显示分支列表
git checkout切换分支
git merge合并分支
git log查看提交历史
git tag创建标签

七、Git 与其他版本控制工具(如 SVN、CVS、Mercurial)的异同点

(本节了解即可)

一、相同点
  1. 版本控制的核心功能

    • 记录文件历史,支持回滚到指定版本。
    • 提供分支功能,允许并行开发。
    • 跟踪代码变更,便于协作。
  2. 基本工作流程

    • 都包含添加(add)、提交(commit)、更新(update/pull)等操作。
    • 支持查看历史记录和差异对比。
  3. 用于团队协作

    • 支持多人协作开发,允许同时管理多分支代码。
二、不同点

特性GitSVN/CVS/Mercurial 等传统工具
架构分布式版本控制系统:每个开发者都有完整的代码库,支持离线操作。集中式版本控制系统:依赖中央仓库,离线操作受限。
性能快速:大部分操作在本地完成(如提交、分支操作),网络请求少,速度快。较慢:每次操作都需与中央仓库交互,网络性能影响较大。
分支管理分支开销小,操作灵活(创建、合并快且简单),适合复杂的分支模型(如 Git Flow)。分支开销大,分支操作繁琐,分支数量多时性能下降。
合并冲突提供强大的冲突解决工具,支持三方合并,手动操作也较直观。冲突解决较弱,复杂合并场景下容易出错。
存储方式使用快照模型:记录整个文件系统的快照,存储高效。使用差异模型:记录每次修改的增量,存储效率较低。
工作方式支持本地操作:提交、查看历史、分支切换等都可在本地完成,再与远程仓库同步。必须与中央服务器交互,离线状态下功能受限。
历史操作可通过 git reflog 查看删除分支、撤销提交等的历史,误操作容易恢复。历史操作较难追踪,恢复误操作的成本较高。
工具生态丰富:支持 GitHub、GitLab 等多种平台,集成了代码评审、CI/CD 等功能。生态相对较弱,扩展性不足。

三、总结
  • Git 的优势:

    • 分布式架构适合现代团队协作,特别是跨地域团队。
    • 性能强大,分支管理灵活,适合复杂项目。
    • 支持离线操作和丰富工具生态,提升开发效率。
  • SVN 等工具的优势:

    • 更简单易用,适合小型团队或对分支管理需求较低的项目。
    • 中央化管理更便于权限控制和统一管理。

Git 目前已成为主流选择,尤其在需要快速迭代和分支操作频繁的场景下表现优越,而传统工具仍在某些特定场景(如企业内网开发)具有应用价值。


八、git 面试八股文

在秋招技术面试中,Git 是一个重要且高频考点,尤其是在涉及团队协作、版本控制相关内容时,考察的多为基础知识和实际应用能力。以下是 Git 相关的常见 “八股文” 考点,分为基础知识、实战场景和常见问题解答三大部分。


一、Git 的基础知识

  1. Git 的基本概念

    • 什么是 Git?

      Git 是一种分布式版本控制系统,用于跟踪代码文件的更改,支持多人协作开发。它可以记录项目的整个历史变更,使开发者能够回溯到任何版本、创建和合并分支,从而提高团队开发的效率。

    • Git 与 SVN 的区别?

      特性GitSVN
      架构分布式(每人都有完整的仓库)集中式(依赖中央服务器)
      离线操作支持不支持
      分支管理高效、轻量,操作灵活创建分支耗时,操作复杂
      性能快速,本地完成大多数操作较慢,需频繁与服务器交互
      冲突解决提供强大的工具,三方合并支持解决冲突的功能较弱
    • 什么是分布式版本控制系统?

      分布式版本控制系统是一种版本控制工具,它的核心特点是每个用户的本地仓库都保存了代码的完整历史记录,而不是依赖于单一的中央服务器。这使得用户可以在本地执行提交、查看历史记录等操作,即使没有网络连接也能工作。常见的分布式版本控制工具包括 GitMercurial

      特点:

      1. 去中心化:每个开发者都有完整的代码仓库副本,不依赖单一服务器。
      2. 离线操作:提交、分支管理、查看历史等大部分操作无需联网。
      3. 更安全:中央服务器损坏时可以从其他开发者的仓库中恢复数据。
      4. 灵活性强:支持复杂的分支和协作模型,适合现代团队开发。

      与集中式版本控制(如 SVN)相比,分布式版本控制系统更高效、更灵活,是当前主流的版本控制方式。

    • 工作区、暂存区、版本库的区别?

      Working Directory(工作区) :本地项目目录,存放你正在开发的文件。

      Staging Area(暂存区) :一个临时区域,存放即将提交的文件快照。

      Repository(版本库) :保存所有提交的历史记录,分为本地和远程版本库。

  2. Git 的三种状态

    • 什么是 modifiedstagedcommitted 状态?

      modified(已修改) :文件在工作区中被编辑,但尚未添加到暂存区。

      staged(已暂存) :文件的修改已被记录到暂存区,准备提交到版本库。

      committed(已提交) :文件的修改已提交到本地版本库,保存到 Git 的历史中

    • 文件从工作区提交到版本库的完整流程是什么?

      • 修改文件(状态为 modified)。

      • 添加文件到暂存区:

        git add <文件名>
        

        (状态变为 staged)。

      • 提交文件到本地版本库:

        git commit -m "提交信息"
        

        (状态变为 committed)。

      • 推送到远程仓库:

        git push origin <分支名>
        
  3. 常用命令

    • 初始化仓库、克隆远程仓库:git initgit clone
    • 提交流程:git addgit commitgit push
    • 拉取远程代码:git pullgit fetch
    • 分支操作:git branchgit checkoutgit merge
    • 查看历史:git loggit reflog
    • 文件差异:git diff

二、实战场景常见考点

1. 分支管理
  • 如何创建一个新分支?命令是什么?

    git branch <分支名>
    
  • 切换分支后,修改的代码会影响原分支吗?

    • 未暂存的修改:会保留在当前工作区,切换分支时可能导致冲突。

    • 已暂存的修改:切换分支会提示错误,要求清理暂存区。

    • 已提交的修改:只会影响当前分支,切换到其他分支后不会看到这些修改。

2. 代码冲突的解决
  • 什么时候会发生冲突?

    • 两个分支修改了同一文件的同一部分。

    • 合并分支时,文件内容不一致。

    • 拉取远程代码时,本地的未提交更改与远程版本冲突。

  • 解决冲突的具体步骤?

    • 使用 git status 确认冲突文件。

    • 手动修改冲突文件,删除冲突标记。

    • 添加到暂存区:

      git add <文件名>
      
    • 提交解决后的文件:

      git commit -m "解决冲突"
      
  • Git 提供哪些工具来帮助解决冲突?

    • 命令行工具git statusgit diff

    • 图形化工具:如 GitHub Desktop、VS Code、SourceTree。

    • 合并工具:如 Meld、P4Merge。

3. 代码回退
  • 如何撤销一次 commit?

    • 撤销最近一次提交但保留修改:

      git reset --soft HEAD~1
      
    • 撤销最近一次提交并删除修改:

      git reset --hard HEAD~1
      
  • git resetgit revert 的区别?

特性git resetgit revert
回退方式修改历史,回退到指定版本创建新提交,撤销指定版本的更改
影响范围改变本地提交历史,可能需要强推不改变历史,适合共享仓库操作
使用场景修正本地错误提交安全地在远程仓库中撤销变更
  • HEAD 指针是什么?如何使用它定位到某个版本?

    • HEAD 是指向当前分支最新提交的指针。

    • 定位到指定版本

      git checkout <提交ID>
      
    • 恢复到最新版本

      git checkout main
      
4. 远程仓库的协作
  • 如何关联远程仓库?

    使用 git remote 关联远程仓库:

    git remote add origin <远程仓库地址>
    
  • 什么是 origin?什么是 upstream

    • origin:默认远程仓库名,通常是你克隆的仓库。

    • upstream:指向主项目的远程仓库,常用于 fork 项目。

  • 如果远程仓库更新了代码,如何与本地同步?

    • 拉取远程更新并自动合并:

      git pull origin <分支名>
      
    • 手动拉取和合并:

      git fetch origin
      git merge origin/<分支名>
      

    从效果上,pull = fetch + merge


三、八股文经典问题集锦

以下是面试中可能会被问到的经典问题,建议在学习 Git 时熟悉这些问题并有自己的答案。

基础类问题
  1. Git 的优点是什么?为什么选择 Git?

    • Git 的分布式设计,支持离线操作。
    • 高效的分支管理,方便多人协作。
    • 丰富的工具生态(如 GitHub、GitLab)。
  2. Git 的核心对象有哪些?

    • Blob:存储文件内容。
    • Tree:描述文件和目录的层级结构。
    • Commit:记录提交信息。
  3. 如何查看某个文件的修改记录?

    • 使用 git log <文件名> 查看文件的提交历史。
    • 使用 git blame <文件名> 查看每行代码的修改者。
  4. Git 中的 HEAD 是什么?

    • HEAD 是一个指向当前分支最新提交的指针。
场景类问题
  1. 如何恢复误删除的分支?

    • 使用 git reflog 找到被删除分支的最新提交 ID,然后用 git checkout -b <分支名> <提交ID> 恢复。
  2. 如何删除本地和远程分支?

    • 删除本地分支:git branch -d <分支名>
    • 删除远程分支:git push origin --delete <分支名>
  3. 如何撤销已经 push 的提交?

    • 如果想回退版本并删除远程记录,使用:

      git reset --hard <提交ID>
      git push --force
      
    • 如果想回退版本但不删除远程记录,使用:

      git reset --soft <提交ID>
      git push --force
      
    • 创建反向提交(推荐方式,避免破坏历史)

      如果你已经共享了提交(如其他人也在使用该分支),强制推送会破坏远程分支历史。此时,使用 git revert 是更安全的选择。

      步骤:

      1. 撤销指定提交

        git revert <提交ID>
        

        这会创建一个新的提交,内容是对指定提交的反向更改。

      2. 推送到远程仓库

        git push origin <分支名>
        
    • 回退最近一次推送的提交

      如果只是撤销最近一次的提交,可以直接使用快捷操作(git reset):

      完全撤销最近的提交并删除更改

      git reset --hard HEAD~1
      git push origin <分支名> --force
      

      撤销最近的提交但保留更改

      git reset --soft HEAD~1
      git push origin <分支名> --force
      

      撤销最近的提交并使用反向提交

      git revert HEAD
      git push origin <分支名>
      
进阶类问题
  1. git mergegit rebase 的区别?什么时候使用?

    • 简单回答:

      • git merge:合并分支后会保留分支历史,适合团队协作。
      • git rebase:将分支变基到目标分支,历史更加线性,适合个人开发。
    • 详细分析:

    git merge 和 git rebase 的区别

    Git 提供两种方式来将分支的修改合并到当前分支:git mergegit rebase。它们的功能都是整合代码变更,但实现方式和适用场景有所不同。

    1. git merge

    功能

    git merge 会将两个分支的最新提交合并,并保留两条分支的独立提交历史。

    实现方式

    1. merge 操作会生成一个新的 合并提交(merge commit) ,表示两条分支的历史已经整合。
    2. 分支历史保留完整,包括分支的分叉点和合并点。

    优点

    • 历史完整,保留了分支的独立开发记录。
    • 更适合团队协作,便于追踪每个分支的来源和合并过程。

    缺点

    • 提交历史可能显得冗长,分支多时会产生很多合并提交。

    命令

    # 切换到主分支
    git checkout main
    
    # 合并 feature 分支到 main
    git merge feature
    

    示例

    假设有两个分支 mainfeature,提交历史如下:

    main 分支:

    A---B---C
    

    feature 分支:

           D---E
    

    执行 git merge 后的历史:

    A---B---C---F
            \   /
             D---E
    

    这里的 F 是合并提交。


    2. git rebase

    功能

    git rebase 会将目标分支的提交整合到当前分支的基础之上,生成一个线性的提交历史。

    实现方式

    1. 通过将目标分支的提交 复制 到当前分支,并重新应用当前分支的提交。
    2. 不生成合并提交,历史看起来更加整洁。

    优点

    • 提交历史线性化,更加清晰。
    • 避免多余的合并提交,便于查看代码演变过程。

    缺点

    • 重写历史,如果已经推送到远程仓库,需要谨慎操作。
    • 不适合多人协作时使用,可能导致冲突或代码丢失。

    命令

    # 切换到 feature 分支
    git checkout feature
    
    # 将 feature 分支变基到 main 分支
    git rebase main
    

    示例

    同样的例子,执行 git rebase 后的历史:

    main 分支:

    A---B---C
    

    feature 分支:

           D---E
    

    执行 git rebase 后的历史:

    A---B---C---D'---E'
    

    注意,DE 被重新生成为 D'E',历史变为线性。


    3. 区别总结

    特性git mergegit rebase
    提交历史保留分支的独立历史,并生成合并提交提交历史线性化,不保留分支的独立性
    合并方式创建一个合并提交重新应用提交,重写历史
    历史完整性历史完整,显示所有分支分叉点和合并点历史简洁,只显示线性提交
    冲突解决在合并时处理冲突在变基时处理冲突
    适用场景团队协作,保留分支开发记录单人开发或整理历史,保持历史清晰
    远程仓库安全不会重写历史,适合远程协作会重写历史,需谨慎使用

    4. 使用场景

    git merge 的使用场景

    1. 团队协作:

      • 多人同时开发时,merge 更安全,能清楚地看到分支的合并记录。
    2. 频繁分支切换:

      • 保留分支的独立性和开发过程,便于追踪问题。
    3. 需要保留分支上下文:

      • 例如 Bug 修复分支,合并后想保留修复过程。

    git rebase 的使用场景

    1. 个人开发:

      • 整理提交历史,确保主分支历史清晰,提交有意义。
    2. 临时分支开发:

      • 在主分支基础上临时开发的功能分支,变基后直接推送到主分支。
    3. 代码审查:

      • 提交给他人审查前,使用 rebase 整理历史,使提交更易读。
  2. 如何保存当前开发进度以便切换到其他分支?

    • 使用 git stash 保存工作区变更:

      git stash
      
    • 切换回来后恢复变更:

      git stash pop
      
  3. 如何查看两次提交之间的差异?

    • 使用 git diff 对比:

      git diff <提交ID1> <提交ID2>
      
  4. 如何排查某次提交引入的 Bug?

    • 使用 git bisect 进行二分查找:

      git bisect start
      git bisect bad <坏的提交>
      git bisect good <好的提交>
      

四、团队协作场景问题

  1. 多人同时开发时如何防止冲突?

    • 每个人基于最新的 develop 分支拉取代码。
    • 任务完成后,通过 pull request 进行代码评审和合并。
    • 定期同步远程仓库,及时解决冲突。
  2. 如何提高 Git 的使用效率?

    • 编写清晰规范的提交信息。

    • 使用 Git 的别名功能优化命令,如:

      git config --global alias.st status
      
  3. 如何确保代码质量?

    • 使用代码检查工具(如 pre-commit hook)。
    • 强制使用分支保护策略和代码评审。