Git 的正确使用姿势与最佳实践| 青训营

48 阅读11分钟

引言

Git 是一种分布式版本控制系统,它可以帮助开发者在团队协作中有效地管理代码,追踪变更,解决冲突,回退错误,创建分支和合并等。Git 的使用姿势和最佳实践有很多,本文将从以下几个方面进行介绍:

  • Git 的基本概念和工作流程
  • Git 的常用命令和参数
  • Git 的分支管理和合并策略
  • Git 的远程仓库和协作模式
  • Git 的日志和撤销操作
  • Git 的配置和忽略文件

Git 的基本概念和工作流程

Git 的核心概念是快照,即每次提交(commit)时,Git 会保存一个当前项目状态的快照,并用一个 40 位的哈希值(SHA-1)来标识。Git 会根据这些快照构建一个有向无环图(DAG),表示项目的历史变化。

Git 的工作流程主要涉及三个区域:工作区(working directory),暂存区(staging area)和版本库(repository)。工作区是开发者编辑代码的地方,暂存区是存放待提交的变更的地方,版本库是存放已提交的快照的地方。Git 的工作流程如下:

  • 在工作区修改或创建文件
  • 使用 git add 命令将文件添加到暂存区
  • 使用 git commit 命令将暂存区的文件提交到版本库,生成一个新的快照
  • 使用 git push 命令将版本库的变更推送到远程仓库(如果有)
  • 使用 git pull 命令将远程仓库的变更拉取到本地版本库(如果有)

Git 的常用命令和参数

Git 提供了很多命令和参数来执行各种操作,这里只介绍一些常用的:

  • git init:初始化一个空的 Git 仓库

  • git clone:克隆一个远程仓库到本地

  • git status:查看工作区和暂存区的状态

  • git diff:查看工作区和暂存区或版本库之间的差异

  • git add:将文件或目录添加到暂存区

    • -A 或 --all:添加所有变更的文件
    • -u 或 --update:添加已跟踪的变更的文件
    • -N 或 --intent-to-add:添加新创建的文件,但不添加内容
    • -p 或 --patch:交互式地选择要添加的变更
  • git commit:将暂存区的文件提交到版本库

    • -m "message":指定提交信息
    • -a 或 --all:跳过暂存区,直接提交所有已跟踪的变更的文件
    • -amend:修改上一次提交信息或内容
    • -p 或 --patch:交互式地选择要提交的变更
  • git log:查看提交日志

    • -n <number>:显示最近 n 次提交
    • --oneline:显示简洁的日志信息
    • --graph:显示分支图形
    • --decorate:显示分支和标签名称
    • <file>:显示指定文件的日志
    • <branch>:显示指定分支的日志
    • <commit1>..<commit2>:显示两个提交之间的日志
  • git show:查看某次提交的详细信息

    • <commit>:指定要查看的提交,可以是哈希值或分支名
  • git branch:管理分支

    • -a 或 --all:显示所有本地和远程分支
    • -v 或 --verbose:显示每个分支的最后一次提交信息
    • -d 或 --delete:删除指定分支
    • -D:强制删除指定分支,即使它没有合并
    • -m 或 --move:重命名指定分支
    • <branch>:创建一个新分支
  • git checkout:切换分支或恢复文件

    • -b <branch>:创建并切换到一个新分支
    • -B <branch>:强制创建或重置一个分支
    • <branch>:切换到指定分支
    • <commit>:切换到指定提交,进入分离头指针状态(detached HEAD)
    • <file>:恢复指定文件到最近一次提交的状态
  • git merge:合并两个分支

    • --no-ff:禁用快进模式,强制创建一个合并提交
    • --squash:将要合并的分支的所有提交压缩为一个变更,但不创建合并提交
    • --abort:取消当前的合并操作,恢复到合并前的状态
    • <branch>:将指定分支合并到当前分支
  • git rebase:变基两个分支

    • -i <commit> 或 --interactive <commit>:交互式地选择要变基的提交
    • --onto <newbase>:指定新的基点
    • --continue:继续当前的变基操作
    • --abort:取消当前的变基操作,恢复到变基前的状态
    • <branch>:将当前分支变基到指定分支
  • git remote:管理远程仓库

    • -v 或 --verbose:显示远程仓库的详细信息
    • add <name> <url>:添加一个远程仓库,指定名称和地址
    • rename <oldname> <newname>:重命名一个远程仓库
    • remove <name> 或 rm <name>:删除一个远程仓库
  • git fetch:从远程仓库获取最新的变更,但不合并到本地版本库

  • git pull:从远程仓库获取最新的变更,并合并到本地版本库

  • git push:将本地版本库的变更推送到远程仓库

    • -u <remote> <branch> 或 --set-upstream <remote> <branch>:推送当前分支,并设置为跟踪远程分支
    • -f 或 --force:强制推送,覆盖远程仓库的历史(慎用)
    • <remote> <branch>:推送指定分支到指定远程仓库

Git 的分支管理和合并策略

Git 的分支是一种轻量级的指针,它可以随时创建、切换、删除和合并。Git 的分支管理和合并策略有很多种,这里只介绍一些常见的:

  • 主干(master)和开发(develop)分支模式。这是一种简单而有效的模式,它只有两个长期存在的分支,即主干(master)和开发(develop)。主干(master)分支用于存放稳定的发布版本,开发(develop)分支用于存放最新的开发版本。开发者可以在开发(develop)分支上进行日常的开发工作,当开发(develop)分支达到一个稳定的状态时,可以合并到主干(master)分支,并打上一个版本标签(tag)。这样,主干(master)分支上的每个提交都对应一个可发布的版本。
  • 功能(feature)、发布(release)和修复(hotfix)分支模式。这是一种更复杂但也更灵活的模式,它除了有主干(master)和开发(develop)分支外,还有三种短期存在的分支,即功能(feature)、发布(release)和修复(hotfix)。功能(feature)分支用于开发某个特定的功能或需求,它通常从开发(develop)分支创建,并最终合并回开发(develop)分支。发布(release)分支用于准备一个即将发布的版本,它通常从开发(develop)分支创建,并最终合并到主干(master)和开发(develop)分支,并打上一个版本标签(tag)。修复(hotfix)分支用于紧急修复一个已发布版本的 bug,它通常从主干(master)分支创建,并最终合并到主干(master)和开发(develop)分支,并打上一个新的版本标签(tag)。这样,每种分支都有明确的用途和生命周期,可以保证代码的质量和稳定性。
  • 合并请求(merge request)或拉取请求(pull request)协作模式。这是一种基于远程仓库的协作模式,它可以让开发者在合并代码之前进行代码审查和讨论。合并请求(merge request)或拉取请求(pull request)是指开发者向远程仓库提交一个请求,要求将自己的分支合并到另一个分支。通常,这个请求会包含源分支和目标分支的信息,以及提交的变更和描述。其他开发者可以在请求中查看变更的内容和效果,提出意见或建议,甚至进行修改或测试。当请求得到足够的赞同或通过后,才能进行合并操作。这样,可以提高代码的可读性和可维护性,避免不必要的错误和冲突。

Git 的远程仓库和协作模式

Git 的远程仓库是指存放在网络上的 Git 仓库,它可以让多个开发者在不同的地点协作开发同一个项目。Git 的远程仓库和协作模式有很多种,这里只介绍一些常见的:

  • 中央仓库模式。这是一种最简单也最常用的模式,它只有一个中央仓库,所有开发者都从中央仓库克隆项目到本地,并将本地的变更推送回中央仓库。这种模式适合小型或中型团队协作,但也存在一些缺点,如需要网络连接才能进行操作,容易产生冲突和覆盖等。
  • 集成管理者模式。这是一种稍微复杂一些的模式,它除了有一个中央仓库外,还有一个或多个集成管理者。集成管理者是指负责将其他开发者的变更合并到中央仓库的人员。其他开发者不能直接推送变更到中央仓库,而是需要向集成管理者发送合并请求或拉取请求。集成管理者在审查和测试通过后,才能将变更合并到中央仓库。这种模式适合大型或复杂团队协作,但也增加了沟通和协调的成本和难度。
  • 司令官和副官模式。这是一种更复杂也更灵活的模式,它除了有一个中央仓库外,还有一个或多个司令官和副官。司令官是指负责整个项目的人员,副官是指负责某个子项目或模块的人员。其他开发者不能直接推送变更到中央仓库,而是需要向副官发送合并请求或拉取请求。副官在审查和测试通过后,才能将变更推送到自己的远程仓库,并向司令官发送合并请求或拉取请求。司令官在审查和测试通过后,才能将变更合并到中央仓库。这种模式适合非常大型或非常复杂团队协作,但也需要非常高的组织和管理能力。

Git 的日志和撤销操作

Git 的日志是指记录项目历史变化的信息,它可以帮助开发者查看、分析、比较和回溯项目的状态。Git 的撤销操作是指取消或修改已经执行的操作,它可以帮助开发者修复错误或改变决策。Git 的日志和撤销操作有很多种,这里只介绍一些常用的:

  • git log:查看提交日志,可以使用各种参数来过滤、排序、格式化输出

  • git show:查看某次提交的详细信息,包括变更的内容和效果

  • git reflog:查看引用日志,即记录每次移动 HEAD 指针的操作

  • git reset:重置 HEAD 指针到指定的状态,可以选择保留或丢弃工作区或暂存区的变更

    • --soft:只重置 HEAD 指针,保留工作区和暂存区的变更
    • --mixed:重置 HEAD 指针和暂存区,保留工作区的变更(默认选项)
    • --hard:重置 HEAD 指针、暂存区和工作区,丢弃所有的变更
  • git revert:创建一个新的提交,用于撤销指定提交的效果,不影响项目的历史

  • git commit --amend:修改上一次提交的信息或内容,会改变项目的历史

  • git rebase -i:交互式地选择要变基的提交,可以进行修改、删除、合并、重排等操作,会改变项目的历史

Git 的配置和忽略文件

Git 的配置是指设置 Git 的行为和属性,如用户名、邮箱、编辑器、颜色等。Git 的忽略文件是指指定 Git 忽略某些文件或目录,不将它们纳入版本控制。Git 的配置和忽略文件有以下几个层次:

  • 系统级(system):适用于系统上所有用户和所有仓库,配置文件位于 /etc/gitconfig

  • 全局级(global):适用于系统上当前用户和所有仓库,配置文件位于 ~/.gitconfig

  • 本地级(local):适用于当前仓库,配置文件位于 .git/config

  • 工作区级(worktree):适用于当前工作区(如果有多个),配置文件位于 .git/config.worktree

  • 文件级(file):适用于当前文件或目录,忽略文件位于 .gitignore Git 的配置和忽略文件可以使用以下命令进行管理:

  • git config:查看或设置配置项

  • -l 或 --list:列出所有配置项

  • --global:设置全局级的配置项

  • --local:设置本地级的配置项(默认选项)

  • --worktree:设置工作区级的配置项

  • --system:设置系统级的配置项

  • <key>:指定要查看或设置的配置项的名称,如 user.name

  • <value>:指定要设置的配置项的值,如 Alice

  • git ignore:查看或编辑忽略文件

    • -l 或 --list:列出所有忽略文件
    • -e 或 --edit:编辑当前层次的忽略文件
    • -g <name> 或 --global <name>:编辑全局级的忽略文件,可以指定名称
    • <pattern>:指定要忽略的文件或目录的模式,如 *.log