Git 项目管理

Git 项目管理

HCX大约 11 分钟git自用速查,实用

在新公司实习有一段时间了,在大公司里面体验到了 git 的实际应用,有所心得分享一下。 重点讲解仓库方面,分支创建和提交记录整理

Git

一、基础用法

提示

开始之前先来解释下 git 的几个概念

  1. 工作区(Working Directory):工作区是你当前正在修改文件的地方。你可以在工作区添加、修改或删除文件。

  2. 暂存区(Staging Area):暂存区是一个中间区域,用于存储即将提交到版本库的修改。当你完成对文件的修改后,你可以将这些修改添加到暂存区。

  3. 版本库(Repository):版本库是 Git 的核心部分,它包含项目的完整历史记录。它由一系列的提交(commits)组成,每个提交代表了一次文件修改的快照。版本库存储在.git 目录中。

一些常用的 Git 指令:

  • 初始化仓库:

    • git init:在当前目录初始化一个新的 Git 仓库。
    • git clone <url>: 克隆仓库
    • git clone -b <branch_name> <url> 克隆远程仓库上的指定分支
  • 添加和提交文件:

    • git add <file>:将文件添加到暂存区。用 git add ./ 来将所有修改的文件添加到暂存区里
    • git commit -m "<message>":提交暂存区的修改到版本库,并添加提交信息。
  • 分支管理:

    • git branch:列出所有分支。
    • git branch <branch_name>:创建新的分支。
    • git switch <branch_name>: 切换到指定分支,推荐使用。
    • git switch -c <branch_name>: 创建并切换到对应分支,推荐使用。
    • git switch -: 快速切换分支,切换到上一个分支
    • git checkout <branch_name>:切换到指定分支。
    • git checkout -b <branch_name>: 创建并切换到对应分支
    • git merge <branch_name>:合并指定分支到当前分支。
  • 远程仓库:

    • git remote add <remote_name> <remote_url>:添加远程仓库。
    • git remote -v:显示所有远程仓库。
    • git fetch: 获取远程仓库的更新
    • git push <remote_name> <branch_name>:将本地分支推送到远程仓库。
    • git pull <remote_name> <branch_name>:从远程仓库拉取最新代码并合并到当前分支。
  • 查看状态和历史:

    • git status:显示工作区和暂存区的状态。
    • git log:显示提交历史记录。
    • git diff:显示工作区与暂存区的差异。
    • git show <commit_id>:显示指定提交的详细信息和修改内容。

以上是一些基础的指令,也是工作中用得较多的。但是当出现复杂的场景时就不太够看了,往往是需要大费周章上网搜搜才能得到解决。

二、Git 进阶操作

git reset 和 git rebase 一直是一个很困惑作者的点,来到公司后利用空余时间好好恶补了一下。 为什么恶补?因为想要让自己的提交记录更加干净,不想因为 bug 或者漏提而反复提交好几次 🤧

先说结论,reset 没有 rebase 灵活,简单的用 reset,复杂的情况用 rebase 在自己的提交还保留在本地并没有推送到远程仓库时, 更改自己的提交记录(注意是自己的且还没有推送的提交)是比较安全的

警告

修改提交历史可能会影响到其他分支或共享仓库的提交历史。因此,在对已经推送到共享仓库或与他人共享的分支进行 reset 和 rebase 操作时要小心,并确保与团队协商一致。

1、git reset 撤销提交

git reset 是一个用于修改分支指针的命令,它可以用于撤销提交、移动分支指针以及恢复文件到指定的提交状态

以下是 git reset 命令的几种常见用法:

  • 撤销提交并保留更改:
git reset HEAD~ 撤销最近一次的提交,并将更改保留在工作区
git reset HEAD~3 代表着撤销最近三次的更改
  • 撤销提交并丢弃更改:

将撤销最近一次的提交,并丢弃所有更改,包括工作区和暂存区的修改 (别用,除非你真的对这次提交的代码失望透顶,永远不想看见 😠)

git reset --hard HEAD~
  • 移动分支指针到指定的提交:

把当前分支的指针移动到指定的提交,使得该提交成为当前的最新提交。这样做可能会导致分支历史的改变,因此在共享仓库或与他人协作时要小心使用

git reset <commit>
  • 恢复文件到指定的提交状态:

将指定文件恢复到指定提交的状态,丢弃在该提交之后对该文件所做的更改。

git reset <commit> <file>

git reset 后面还可以接各种参数,这些参数代表着不同的意义,默认是--mixed

soft 和 mixed 差别并不大,一般也就用默认够了。重要的是工作区的保存,hard 会直接删掉不留痕迹,其他两个都可以在原有的更改上继续修改

--hard

分支指针移动:将分支指针移动到指定的提交,并将工作区和暂存区完全重置为该提交状态。

影响范围:会丢弃所有未提交的更改,包括工作区和暂存区的修改。这是一个潜在的危险操作,因为它会永久性地丢失你的更改。

示例:`git reset --hard <commit>`

--soft

分支指针移动:将分支指针移动到指定的提交,但不会对工作区和暂存区进行任何修改。

影响范围:保留所有未提交的更改,包括工作区和暂存区的修改。这样,你可以重新提交这些更改或进行其他操作。

示例:`git reset --soft <commit>`

--mixed(默认选项):

分支指针移动:将分支指针移动到指定的提交,并将工作区重置为该提交状态,但保留暂存区的修改 。 影响范围:丢弃暂存区的修改,但保留工作区的修改。这样,你可以重新选择要提交的更改,并进行适当的暂存操作。

示例:`git reset --mixed <commit>`

使用 git reset 命令修改一个分支的历史时,会有以下几种情况:

  • 本地分支:如果你在本地仓库上修改分支的历史,尚未推送到远程仓库,那么只会影响你本地的仓库。其他人在拉取你的修改之前不会看到这些更改。

  • 共享仓库中的分支:如果你在共享仓库中修改分支的历史,并将这些更改推送到共享仓库,那么这些更改将会影响到其他人。这是因为 git reset 会改变提交历史,使得原本的提交不再存在或不可访问。

  • 如果你之后将修改的分支推送到共享仓库,并试图强制推送(例如使用 --force 选项),那么其他人在拉取时可能会遇到冲突,因为他们的本地分支与共享仓库中的历史不一致。

在这种情况下,最好避免在共享仓库中执行 git reset 或其他会修改提交历史的命令,除非你与团队协商一致,并确保其他人能够适应和理解这些更改。

2、git rebase 历史重排

在前面不难看出 git reset 很多时候只能单独处理一个提交记录,又或者是直接回退前几次的顺序提交。而我如果只是想要修改某一次的提交,或者重新组织下提交顺序就会非常麻烦。而 git rebase 是一个用于修改提交历史的命令,它可以将一系列提交应用到另一个分支上,并重新构建提交历史。

3、stash 储存

当需要频繁切换分支处理任务时,这很有用,提供了一种不用提交 commit 而又能存储当前变更的能力

git stash: 用于临时保存当前工作目录中的修改,常用于当前分支的修改不想丢失,又或者想原封不动的移动到另外一个分支上时

git stash pop: 从临时保存的列表中取出最近一条记录

git stash list: 查看暂存列表

4、cherry-pick 选择提交

用于将指定的提交给移植到另外一个分支上,常用于跨分支修复,如在当前的分支上继续开发并且修复了某个问题,可以在新建的 bugfix 分支上使用cherry-pick 指令去获取其他分支的提交记录。相较于 git stash 指令更加强大

三、项目管理

环境与分支

在实际开发中,项目的环境可以被分为 测试环境 -> 预发布环境 -> 正式环境。

相应的在仓库中也会经常看见有多个对应分支,一个主要的开发分支(main),一个专门用于测试的分支(main-test),还有一些其他人创建的单独分支(一般以开发者名字命名)

在根据 main 分支创建自己的分支后,又可以细分自己的分支为 bugFix (为修复 bug 而存在的分支)、feature (开发新功能的分支)

1、提交合并注意项

创建分支

进入公司都会创建自己的分支单独开发,一般选择已经测试过功能正常的稳定分支为基础创建新分支。 切记不要以测试分支为基础创建分支,会带上别人正在测试的不稳定功能!

  1. 提交后推送到自己的远程仓库中,然后发起合并请求到测试分支上 (如果有冲突则在远程解决,也可以本地切到测试分支解决冲突)

  2. 测试无误后,该功能分支处于等待发布中。如果此时手里有新的需求,重新新建分支处理。

  3. 并不是测试无误后就能马上发布,一般一次发布不会只更新一个功能,这时需要与团队成员协商好一起发布,一个大版本的发布往往是好几个功能

  4. 准备发布,将自己的代码合并到 main 分支上。如果是一个大版本的话可能需要拉取上别人的功能进行统一发布。

注意

因为会出现开发完当前需求后但是并不急于发布的情况,如果继续在该分支开发,当需要发布时这个分支会带上不想马上发布的功能。因此最好是一个分支对应着一个需求

2、git 规约

Git commit 规约是一种约定俗成的方式,用于规范化 Git 提交信息的格式和内容,以便更好地描述提交的目的和变更内容。这有助于团队成员更好地理解和追踪代码库的历史记录。

<type>(<scope>): <subject>

<body>

<footer>

<type>(必需):表示提交的类型,常见的类型包括::

  • feat:新功能(feature)
  • fix:修复问题(bug)
  • docs:文档更新
  • style:代码格式、样式调整,不涉及代码逻辑变动
  • refactor:代码重构,不涉及功能新增或修复问题
  • test:添加或修改测试相关的代码
  • chore:构建过程或辅助工具的变动

<scope>(可选):表示提交的范围,例如模块、文件、组件等。可以根据项目的具体需要进行定义。

<subject>(必需):简明扼要地描述提交的目的

<body>(可选):用于详细描述提交的变更内容,可以包含多行

<footer>(可选):用于添加一些额外的信息,例如关联的 Issue 编号、变更的关闭策略等

例如: git commit -m 'fix(index.js): 修复首页按钮点击没有反应'

四、实际场景

1、 提交后发现漏提了或者有 bug

(注意在分支合并前可以这样操作,确保没有人使用自己的分支,如果有的话还是老老实实的新提交一个 commit 吧)

在 Git 中,git commit --amend 是一个用于修改最近一次提交的命令。它可以用于修改提交信息、添加漏掉的文件或修改文件内容

# 修改文件内容
git add modified_file.txt
git commit --amend
git push -f (强制自己的远程仓库和本地提交同步,如果还没有推送则不用)

也可以直接撤回

git reset HEAD~ (回退到上一次提交前,上一次的修改内容依旧存在等待提交)
# 修改文件
git commit -m 'xxx'
git push -f (强制自己的远程仓库和本地提交同步,如果还没有推送则不用)

2、 冲突处理解决

3、 开发过程中需求转换到更紧急的需求上