导读

事实上,无论是分布式还是集中式,两者都有其门面解决方案,即 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. 设置签名

    • 这一步将会告诉别人,到底是谁进行了这一次修改(区分不同的开发人员)。
    • 需要注意,这一步设置签名和登录远程库(代码托管中心)的账号、密码无任何关系。
    • 项目级别 / 仓库级别
    • 仅对当前的项目(本地仓库)范围内有效,去到另一个项目时该签名就不生效了:
    • 昵称:git config user.name yuuki
    • 邮箱:git config user.email [email protected]
    • 以上命令会将用户信息(签名)保存在当前项目的 .git 目录中的 config 文件内。

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

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

    1. 将工作区中的改动添加到暂存区
    • git add <file>
    • 如果是修改一个已经存在的文件(即已经被 Git 追踪的文件),则可以不用改命令而直接使用下一个命令。

      1. 将修改的内容提交到本地仓库中
    • git commit <file>
    • 该命令会打开默认编辑器(如 vim),需要你来添加提交的消息。
    • 如需要直接添加消息而不打开编辑器:

      • git commit -m "commit message" <file>
      • 将文件移出暂存区:
    • git rm --cached <file>
  4. 查询

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

      1. 显示日志
    • 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~[数字] 数字为几就回退几个版本

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

      • reset 的三个参数对比
    • --soft

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

      • 在本地库移动 HEAD 指针后,重置暂存区

      最新 | - | - | 工作区
      his1 | 本地库 | 暂存区 | -

    2. --hard

      • 在本地库移动 HEAD 指针和重置暂存区后,重置工作区

      最新 | - | - | -
      his1 | 本地库 | 暂存区 | 工作区

  6. 比较文件

    1. 和暂存区比较
    • git diff <file>

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

      1. 和历史版本比较
    • git diff HEAD^ <file> 和 3.5 的操作方式相同

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