导读

事实上,无论是分布式还是集中式,两者都有其门面解决方案,即 Git 和 SVN。
那么,为什么选择了 Git ,Git 又有什么优势?
现今,虽然 Git 大行其道,但不意味着 SVN 就无人问津,二者都是优秀的解决方案,无意对技术做任何评判。

这篇指令居多,略显枯燥。


1. 为什么选择 Git

这个问题可以抽象的延伸为:为什么选择分布式版本控制?

  1. 在分布式管理控制理念中,由于遵守的是分布式的管理理念,Git 会在最开始把需要的内容下载下来。我们就能够在本地上完成大部分操作而不需要联网。
  2. Git 提供了完整性校验。

    • 即是 Hash 校验,通过 Hash 校验来判断文件是否变动。
  3. Git 会尽可能的添加数据,而非删除或修改数据。
  4. 分支操作快捷流畅。这也是选择快照来进行版本管理的优势。
  5. 全面兼容 Linux 命令。

2. Git 结构及其工作方式

2.1. Git 的工作区域

在 Git 中,共有三个工作区域:

  1. 工作区(Workspace)

    • 平常存放项目代码,也就是我们写代码的地方。
  2. 暂存区(Index / Stage)

    • 临时存储数据的地方,也就是中间层。
    • 实质上只是一个文件,或者称为列表,用来保存即将提交的文件信息。
  3. 版本库(Repository)

    • 存储历史版本的地方。
    • 也称仓库区。其 HEAD 指针将会指向最新放入仓库的版本。

一般的工作流程为:在工作区修改好文件后,通过 git add 将文件添加到暂存区。
接着,通过 git commit 将文件上存到版本库中。

2.2. 代码托管中心

所谓的代码托管中心,实质上是用来帮我们来维护远程库的。

远程库(Remote),是一个托管代码的服务器,可以简单的理解为就是你项目组中放在远端的电脑。

常见的托管中心有局域网环境下的 GitLab,和互联网环境下的 码云GitHub 等。

2.3. 本地库和远程库

本地库:最简单的理解,三个工作区域的合称,也可特指版本库。

2.3.1. 团队内的场景

  1. 通过 推送(push) 操作来将本地库的内容推送到远程库中。
  2. 通过 克隆(clone) 操作来将远程库的内容克隆岛本地库中。

    • 还记得上一篇提到的权限管理吗?如果你不是团队内的成员,clone 下来的内容是不能直接 push 到远程库中的。此时有两种解决方案:加入团队,或是 2.3.2 提到的跨团队协作。
  3. 通过 拉取(pull) 操作来讲远程库的修改拉取到本地库中。

    • 也就是说,你克隆下来的版本可能是 1.1.0,然后团队成员可能将版本推进到了 1.1.1,这时候就要通过 pull 操作来将本地库的内容更新到与远程库同步。

2.3.2. 跨团队的场景

  1. 通过 复制(fork) 操作来复制一个远程库——即复制一个远程库 B,内容和远程库 A 的内容一样。
  2. 另一个团队在远程库 B 修改了代码后,通过 pull request 的操作申请将远程库 B 的修改同步到远程库 A 中。
  3. 远程库 A 的创建人对该 pull request 审核通过后,将远程库 B 的修改 合并(marge) 到远程库 A 中。

2.4. Git 基本操作

  1. 初始本地库操作

    • git init
    • 万事之首,当然 fork 到本地除外(别告诉我你忘了 fork 是什么)。
    • 该命令用于在当前文件夹下初始化一个本地仓库:
    • 初始化完成后,该文件夹下会生成一个一个 .git 的隐藏文件夹,里面存放了本地库相关的子目录和文件,不能删除,且一般情况下都不需要修改。
  2. 设置签名

    • 这一步将会告诉别人,到底是谁进行了这一次修改(区分不同的开发人员)。
    • 需要注意,这一步设置签名和登录远程库(代码托管中心)的账号、密码无任何关系。
    1. 项目级别 / 仓库级别

      • 仅对当前的项目(本地仓库)范围内有效,去到另一个项目时该签名就不生效了:
      • 昵称:git config user.name yuuki
      • 邮箱:git config user.email [email protected]
      • 以上命令会将用户信息(签名)保存在当前项目的 .git 目录中的 config 文件内。
    2. 系统用户级别 / 全局级别

      • 也就是当前的系统账户级别:
      • 昵称:git config --global user.name yuuki
      • 邮箱:git config --global user.email [email protected]
      • 对于 Unix 来说,存储在家目录下

        • cd ~ 下的 .gitconfig 文件内
    • 优先级:就近原则,也就是项目级别大于全局级别。
  3. 添加、提交操作

    1. 将工作区中的改动添加到暂存区

      • git add <file>
      • 如果是修改一个已经存在的文件(即已经被 Git 追踪的文件),则可以不用改命令而直接使用下一个命令。
    2. 将修改的内容提交到本地仓库中

      • git commit <file>
      • 该命令会打开默认编辑器(如 vim),需要你来添加提交的消息。
      • 如需要直接添加消息而不打开编辑器:

        • git commit -m "commit message" <file>
    3. 将文件移出暂存区:

      • git rm --cached <file>
  4. 查询

    1. 查看状态

      • git status
      • 该命令用于查看工作区、暂存区的状态(当前在哪个分支、是否还有东西没有提交)。
    2. 显示日志

      • git log 完整显示日志,space 向下翻页、B 向上翻页、Q 退出。
      • git log --pretty=oneline 只会显示完整的哈希值和提交信息。
      • git log --online 只显示 7 位哈希值(GitHub 即是如此)。
      • git reflog 查看所有分支的操作记录(包括被删除的)。
  5. 变更版本

    • 用于前进 / 后退版本。注意:git 有 指针 的概念,本质上是通过移动指针来选择版本。

      • git reset --hard [索引值]
      • 索引值是上文提到的 7 位哈希值
    • 使用 ^ 操作符(只能后退)

      • git reset --hard HEAD^ 几个^就后退几个版本
    • 使用 ~ 操作符(只能后退)

      • git reset --hard HEAD~[数字] 数字为几就回退几个版本
    • 进阶:

      1. 如果删除行为已经同步到了本地库,则通过回退到上个版本来找回文件。
      2. 如果删除行为已经提交到了暂存区,则直接 hard reset 到最新的版本即可。
      • 但无论如何,该文件都需要已经提交到了本地库,否则 git 无法恢复。
    • reset 的三个参数对比

      1. --soft

        • 仅在本地库移动 HEAD 指针
        • 最新-暂存区工作区
          his1本地库--
      2. --mixed

        • 在本地库移动 HEAD 指针后,重置暂存区
        • 最新--工作区
          his1本地库暂存区-
      3. --hard

        • 在本地库移动 HEAD 指针和重置暂存区后,重置工作区
        • 最新---
          his1本地库暂存区工作区
  6. 比较文件

    1. 和暂存区比较

      • git diff <file>
    2. 和本地库比较

      • git diff HEAD <file>
    3. 和历史版本比较

      • git diff HEAD^ <file> 和 3.5 的操作方式相同

至此,本文的全部内容就结束了,感谢你的阅读,欢迎继续阅读本站的其他文章。