实践:Git 的正确使用姿势与最佳实践 | 青训营
介绍
版本控制
版本控制是指在软件开发过程中对各种程序代码、配置文件及说明文档等文件变更的管理,版本控制系统能够随着时间的推进记录一系列文件的变化,方便以后随时回退到某个版本。
版本控制系统分为三大类:
- 本地版本控制:本地代码的版本控制
- 集中式版本控制:提供一个远程服务器来维护代码版本,本地不保存代码版本,解决多人协作问题
- 分布式版本控制:每个仓库都能记录版本历史,解决只有一个版本服务器保存版本的问题
Git
Git 是 Linux 发明者 Linus 开发的一款分布式版本控制系统,是目前最为流行和软件开发着必须掌握的工具。
它是一个分布式版本控制系统,保存的是文件的完整快照,而不是差异变换或者文件补丁。保存每一次变化的完整内容。
安装
我们可以在官网的下载链接Git - Downloads (git-scm.com)中下载对应系统的Git,或者也可以在阿里镜像找到对应的安装包。
然后根据引导一步一步安装Git,其中相关组件的安装可以参考如下指示:
安装完毕后,我们可以在命令行中输入git --version查看Git版本:
使用前,我们还需要在Git中进行一些配置,比如你的用户名、邮箱等,这些信息是用来在你向代码仓库中提交自己的代码进行标识的,我们可以通过git config命令进行配置,例如:
git config --global user.name "Tom"
git config --global user.email "123456@qq.com"
加上 --global表示在全局加上该配置,对所有的仓库生效。
同时,我们有时候会因为本地网络的问题无法访问到远程服务器,可以设置代理:
git config --global https.proxy 代理地址
# 如果需要解除代理设置,执行:
git config --global --unset https.proxy
我们也可以通过git config --list查看自己git的配置:
简单使用
首先,我们命令行中新建我们的工作目录:
mkdir git_study
cd git_study
然后使用git init 初始化本地的git仓库,默认仓库的初始分支是'master',我们可以通过git branch -m <name>来重命名刚创建的分支。
初始化之后,我们可以通过tree 命令来查看结构目录:
这里如果我们是在git bash中使用tree命令查看的话会提示命令不存在,需要输入tree.com才行:
具体可看git 入门教程之 git bash 竟然不支持 tree 命令 - 雪之梦技术驿站 - 博客园 (cnblogs.com)
同时,我们可以看到的目录结构只有文件夹的结构,如果想要查看所有内容,可以加上/F参数:
其中,各个文件目录的含义:
-
HEAD:指向当前所在的分支或提交。 -
config:存储仓库级别的配置选项,如用户名、邮箱等。 -
hooks/:包含了Git钩子脚本的目录,可以在特定的Git事件发生时执行自定义脚本。 -
info/`:存储一些额外的仓库信息,如排除文件、模板等。
-
objects/ :存储Git对象(blob、tree、commit等)的目录。
-objects/info/ :存储一些对象相关的额外信息。-objects/pack/`:存储打包的对象文件。
-
refs/:存储引用(分支、标签等)的目录。refs/heads/:存储分支引用。-
refs/tags/:存储标签引用。
如果想要直接下载远程代码仓库的代码到本地,我们可以通过git clone 仓库地址命令即可克隆所有的代码以及版本控制等信息,如果只希望下载代码,则可以加上--depth=1的参数。
另外,现在大部分仓库的代码可能依赖其他仓库的代码,称之为子仓库,那么我们在本地代码目录下还要执行git submodule update --init --recursive 来下载 submodule来将子仓库的代码也克隆下来
Git的过程
首先来看一下工作区、暂存区、版本库的概念:
工作区:仓库文件夹下的所有内容就是一个工作区;
版本库:记录了所有已经提交的数据;
暂存区:介于工作区与版本库间的区域,你在工作区的修改会先被上传到暂存区(这个过程称作 stage fix),然后你可以选择将暂存区的修改打包作为一次提交同步到版本库,也可以选择从版本库或工作区来覆写暂存区的内容(丢弃之前的修改)。
我们也可以通过具体的命令来了解:
git add 文件可以将工作区的指定文件的修改同步至暂存区;特别地,在仓库根目录下执行git add .可以将所有修改同步至暂存区;git commit [-m "提交消息"]可以将暂存区的修改作为一次提交,追加到当前分支的最新提交(即 HEAD);git checkout可以将版本库的特定提交与分支同步到暂存区与工作区,这使得你可以随时随地切换到历史代码现场或者是其他人的最新开发进度git push会将本地的版本库的分支推送至远程仓库;git fetch则相反,会从远程仓库下载最新的分支数据到本地;git pull则还会覆写你的工作区。
分支管理
往往在团队合作开发时,我们需要维持不同的代码版本:稳定版、开发版等,这样我们就需要会使用branch、merge、rebase等:
-
git branch可以创建和管理新的分支。在实践中,修改往往不会直接在主分支上进行,这样可以确保主分支永远拥有稳定的代码。当我们开始一个新功能的研发或是 bug 修复时,会先创建一个新分支(如果是别人的仓库,那么往往还伴随着一个 fork 操作),然后在上面进行开发,在确定无误后再将修改提交到主分支,最后删除新建的分支即可。每个人都可以同时在各自的分支上进行开发,并在最后进行合并,这十分利好团队合作。 -
git merge则负责实现上面提到的分支的合并。这条指令会生成一条merge commit,其中包括了整个分支上的提交记录,然后将其提交到指定的分支; -
git rebase叫变基,也负责分支修改的合并,不过原理不太一样:它会基于目标分支的最新状态重写当前分支的所有提交(相当于从目标分支合并到当前分支),然后修改主分支的指针,使它直接指向重写后的最新提交,在git log中看来就是一条笔直清爽的线。但使提交记录更整洁是有代价的:它会破坏当前分支的历史记录,此时如果有人已经依赖于当前分支的提交进行开发,则他们的工作很可能会作废,无法再提交,从而带来麻烦。