Git版本控制

Git的介绍
  • git的特点:
    • 版本控制:
      • 可以解决多人同时开发的代码问题,也可以解决找回历史代码的问题
    • 分布式:
      • Git 是分布式版本控制系统,同一个 Git 仓库,可以分布到不同的机器上。首先找一台电脑充当服务器的角色,每天 24 小时开机,其他每个人都从这个“服务器”仓库克隆一份到自己的电脑上, 并且各自把各自的提交推送到服务器仓库里, 也从服务器仓库中拉取别人的提交。可以自己搭建这台服务器,也可以使用 GitHub 网站。
  • 什么是版本控制
    • 版本控制(Revision control)也称源代码控制管理系统或修订控制系统, 是保存文件多个版本的一种机制。它是一种软件工程技巧,籍以在开发的过程中,确保由不同人所编辑的每个与所开发的文件相关的产物都应被置于版本控制之下。 能记录任何工程项目内各个模块的改动历程, 并为每次改动编上序号。
  • 版本控制的目的
    • 1、保留项目中每个文件的所有版本的历史信息,并使它易于查找。
    • 2、让(分布式的)项目团队可以便捷的协作工作
项目的介绍
  • 一般的软件it项目周期如下
    • 决策阶段:
      • 项目立项--项目调研--确定项目需求--项目目标
    • 设计阶段:
      • 项目分析--项目设计--需求基线设计--项目时间计划
    • 开发阶段:
      • 划分需求--代码开发(开发-调试-开发-调试-...)--代码管理
    • 部署阶段:
      • 代码部署--产品上线--项目验收...
  • 项目周期与配置管理
    • 整个 it 周期都需要进行配置管理,版本控制只是配置管理中的一项,而版本控制在 it 项目周期中可以划分两个阶段:代码控制/环境控制。
    • 开发人员开发完代码后,提交代码进行编译,生成可执行文件,然后可执行文件到达运维工程师后,运维工程师拿到配置文件后,调用 saltstack 等管理工具进行环境的配置管理
Git常用的工具
  • Git
    • git 是一个分布式的版本管理系统,同时他也是一个底层的协议
  • Gitlab
    • Gitlab 是 git 私有仓库解决方案,也是我们项目私有的中央服务器,他是企业私有的,内网不对外公开的一个基于 GIT 的源码托管解决方案基于 Ruby on rails 开发集成了 nginx postgreSQL redis sidekiq 等组件
  • Github
    • Github 是 git 共有仓库解决方案,也是我们项目开放的中央服务器,所有网上的人都可以使用

Git的常用操作
  • 安装Git
    • sudo apt-get install git        安装git
    • git --help      查看可以使用的git命令
  • 对当前分支进行操作
    • add           Add file contents to the index
      • 将文件加入到暂存区
    • mv              Move or rename a file, a directory, or a symlink
      • 相当于执行了 mv/git rm/git add 这三个命令
    • reset            Reset current HEAD to the specified state
      • 回滚操作
    • rm                Remove files from the working tree and from the index
      • 从版本库中移除,rm --cached file 表示将 file 从暂存区中移除
  • 查看历史操作和工作状态
    • bisect                 Use binary search to find the commit that introduced a bug
    • grep                   Print lines matching a pattern
    • log                      Show commit logs
    • show                  Show various types of objects
    • status                 Show the working tree status
      • 查看 git 目录下当前的所有对象状态,如果 status -s 则显示状态的概览
  • 提交,标记和验证公共记录
    • branch               List, create, or delete branches
    • checkout           Switch branches or restore working tree files
    • commit             Record changes to the repository
      • 提交更新
    • diff                     Show changes between commits, commit and working tree, etc
      • 查看尚未暂存的文件,  diff --staged 查看暂存区文件
    • merge               Join two or more development histories together
    • rebase               Forward-port local commits to the updated upstream head
    • tag                     Create, list, delete or verify a tag object signed with GPG
  • 和共有仓库进行交互
    • fetch/lone            Download objects and refs from another repository
    • pull               Fetch from and integrate with another repository or a local branch
    • push             Update remote refs along with associated objects
Git的区域管理
  • Git的四个区域
    • git 存在四个区域:
      • 工作目录、暂存区域、本地仓库、远程仓库
    • 创建方式
      • 当使用git init的时候创建了三个区域:工作区域 / 暂存区域 / 本地仓库
    • 这四个区域存在的地方:
      • 工作目录、暂存区域、本地仓库 这三个区域在我们的主机上
        • 工作区:就是我们创建的目录里面除了.git之外的所有区域(也就是除了.git目录之外的所有区域)
        • 暂存区:就是临时存放文件的地方,在.git目录中对应index文件
        • 仓库区:就是真正存贮我们提交后的代码的地方,对应.git目录中的object文件
      • 远程仓库就是远程的代码仓库,在远程服务器上,如github
    • 当使用git init的时候创建了三个区域:工作区域/暂存区域/本地仓库
  • 工作区域(Working Directory)
    • 工作区域
      • 电脑中的目录,除了.git 之外所有的内容
  • 版本库(Repository)
    • 版本库
      • 我们创建git版本库的目录,有一个.git目录,这个不是工作区,是git的版本库
    • 版本库包含的东西
      • stage(index):暂存区域
      • HEAD:git会为我们自动创建第一个分支master,指向这个分支的指针就是HEAD,HEAD就像指向版本的GPS,它显示的位置在哪,我们就处在哪个分支
    • 向版本库提交内容的过程
      • 我们创建 git 版本库时,git 自动为我们创建了唯一一个 master 分支,所以,现在,gitcommit 就是往 master 分支上提交更改。你可以简单理解为,需要提交的文件修改通通放到暂存区,然后,一次性提交暂存区的所有修改。
  • 暂存区& & 本地仓库
    • 往 git 版本库里添加的步骤
      • 第一步是用 git add 把文件添加进去,实际上就是把文件修改添加到暂存区;
      • 第二步是用 git commit 提交更改,实际上就是把暂存区的所有内容提交到当前分支
    • 向暂存区和本地仓库中添加的原理
  • 远程仓库
    • 就是放在远端服务器上的代码仓库,比如公共代码仓库  github
文件的四个状态
  • 文件的状态转变过程
    • git 是通过四种状态来对文件进行版本管理:untracked(文件未加载到缓存)、unmodified(文件已经添加到本地仓库)、modified(文件上传仓库后进行了修改)、Staged(文件在缓存区)
文件的常见管理操作与文件状态的转换
  • 查看文件状态 
    • git  status     查看文件的状态---四个状态
      • 文件如果还没有添加到版本管理,那么他的状态为---untracked
      • 如果文件已经被管理那么处于UNmodified状态,当被修的时候,将会被自动拉倒工作区---变为Modify状态
  • 修改文件并添加到缓存 
    • vi  code.txt    对文件进行修改   --- 变为Modified状态
    • git add code.txt       将文件添加缓存区   ---变为Staged状态
  • 撤销之前的修改
    • git reset    选项    <文件>     是对项目的提交进行回滚操作的命令,它有如下几个参数
      • --soft 缓存区和工作目录都不会被改变, 只是本地库中的文件回滚到指定版本---Staged状态
      • --mixed 默认选项,版本库回退到指定版本,缓存区清空,但工作目录不变----Modify状态
      • --hard  缓存区和工作目录和数据库都同步到你指定的版本  ----Unmodified状态
    • git checkout -- <文件>     丢弃工作区的改动,直接将版本库中的文件拉倒工作目录中
    • 常见的撤销场景
      • 当你改乱了工作区某个文件的内容,想直接丢弃工作区的修改时,用命令 git checkout-- file。
      • 当你不但改乱了工作区某个文件的内容,还添加到了暂存区时,想丢弃修改,分两步,第一步用命令 git reset HEAD file,就回到了场景 1,第二步按场景 1 操作。
      • 已经提交了不合适的修改到版本库时,想要撤销本次提交,使用git reset --hard HEAD^ file

Git常用命令实践
  • 使用前的配置
    • 创建git版本库的目录,并创建版本库
      • mkdir   git_test     
      • cd   git_test
      • git   init
        • 可以看到在 git_test 目录下创建了一个.git 隐藏目录,.git所在的目录就是版本库目录(里面有branches分支、config配置文件、description描述、HEAD指针、hooks触发动作、info信息、objects对象(用来存储git对象提交的代码会以一定的格式存储在该文件夹中)、refs查询远程工作系统)。
    • 个人用户信息配置
  • 文件版本的创建与回退
    • 在版本库目录中创建一个文件(创建需要进行版本管理的文件)
      • touch   code.txt       创建需要版本控制的文件
      • vi     code.txt       对文件进行更改
    • 给文件创建一个版本
      • git   add   code.txt
      • git   commit   –m  '版本 1'
        • -m是为版本输入说明信息
      • git rm  --caced  code .txt     将文件从缓存区删除
    • 查看版本记录日志
      • git   log
        • 可以查看到当前版本的之前所有的提交记录,和当前版本前的所有版本号
        • --graph   显示所有分支的信息
        • --pretty=online    友好的显示,只显示有帮助的信息
    • 回退到前面某一个版本(回退到前面的版本)
      • git reset --参数 HEAD^ <文件>
        • HEAD  表示当前最新版本,HEAD^代表前一个版本(有几个^代表前几个版本),也可以使用 HEAD~n 表示当前版本的前n个版本
        • --soft   缓存区和工作目录都不会被改变, 只是本地库中的文件回滚到提交的那个版本
        • --mixed 默认选项,缓存区回退到你指定的提交版本,但工作目录不变
        • --hard   缓存区和工作目录和数据库都同步到你指定的提交
    • 查看之前的所有版本和操作记录
      • git   reflog     可以查看之前的所有操作记录,和每次的版本号
    • 回退到任意之前任意版本
      • git  reset  -- 参数  版本号  <文件>
        • --soft   缓存区和工作目录都不会被改变, 只是本地库中的文件回滚到提交的那个版本
        • --mixed 默认选项,缓存区回退到你指定的提交版本,但工作目录
        • --hard   缓存区和工作目录和数据库都同步到你指定的提交
    • 丢弃工作区的修改
      • git checkout -- <文件>   获取版本库中当前版本的文件,当文件被删除或者想要获取版本库中的文件的时候可以使用
  • 查看工作状态与更改的内容
    • git status     查看当前的工作状态位于(staged、modified、Unmodified、Untracked)
    • git  diff  当前版本  之前版本  -- 哪个文件
      • 示例:
        • 如果只写一个版本号,代表版本中的文件和当前工作区中的文件进行对比
  • 删除文件
    • 将工作区的文件删除,并同步到缓存区
      • git  rm  -r 将删除操作提交到暂存区
    • 会将版本库中的文件也删除
      • git commit -m "Delete some files."
    • 如果要恢复删除了的文件(如果还没有进行commit操作)
      • git checkout –- 文件   将工作区的文件回退到和版本库中的版本相同(提交删除之前)
  • 分支相关命令
    • git  branch       查看分支
      • -va  查看本地和远端的分支
    • git  branch <name>                  创建分支
    • git  checkout <name>        切换分支
    • git  checkout -b <name>      创建+切换分支
    • git  merge <name>      合并某分支到当前分支
      • --no--ff  强制禁用快速合并,合并后将会自动的提交一次commit
      • -m  '  '     添加备注信息
    • git  branch -d <name>       删除分支 
    • git  stash      将分支冻结
    • git  stash pop       将分支解除冻结
    • git  stash  list       查看被冻结了的内容

分支管理的介绍
  • 分支管理的简介
    • 分支就是科幻电影里面的平行宇宙,当你正在电脑前努力学习 Git 的时候,另一个你正在另一个平行宇宙里努力学习 SVN。如果两个平行宇宙互不干扰,那对现在的你也没啥影响。不过,在某个时间点,两个平行宇宙合并了,结果,你既学会了 Git 又学会了 SVN!
  • 分支管理的作用
    • 创建了一个属于你自己的分支,别人看不到,还继续在原来的分支上正常工作,而你在自己的分支上干活,想提交就提交,直到开发完毕后,再一次性合并到原来的分支上,这样,既安全,又不影响别人工作。   总而言之就是,每个人都有自己的开发分支,在每个人完成自己的开发内容后,在统一的在一个分支上进行代码的合并;
  • 工作中常见的分支
    • master 分支 线上环境主分支
    • release 分支 预发布环境分支
    • dev 分支  开发环境分支
    • test 分支  测试环境分支
    • bug 分支  专用的修复 bug 分支
  • 分支管理的详细过程
    • git的分支和HEAD和master
      • 分支
        • git 把我们之前每次提交的版本串成一条时间线,这条时间线就是一个分支。截止到目前只有一条时间线,在 git 里,这个分支叫主分支,即 master 分支。
      • HEAD
        • HEAD 严格来说不是指向提交,而是指向 master,master 才是指向提交的,所以,HEAD指向的就是当前分支。
      • master
        • 哪个分支创建的当前代码仓库,谁就是 master。它是当前代码仓库的主分支。
    • 创建分支的过程
      • 创建master分支
        • 一开始的时候,master 分支是一条线,git 用 master 指向最新的提交,再用 HEAD 指向 master,就能确定当前分支,以及当前分支的提交点,每次提交,master 分支都会向前移动一步,这样,随着你不断提交,master 分支的线也越来越长。
      • 创建新的分支 
        • 当我们创建新的分支,例如 dev 时,git 新建了一个指针叫 dev,指向 master 相同的提交,再把 HEAD 指向 dev,就表示当前分支在 dev 上,git 创建一个分支很快,因为除了增加一个 dev 指针,改改 HEAD 的指向, 工作区的文件都没有任何变化从现在开始,对工作区的修改和提交就是针对 dev 分支了,比如新提交一次后,dev 指针往前移动一步,而 master 指针不变
    • 分支合并的过程
      • 快速合并分支(默认方式)(Fast Forward)
        • 使用场景
          • 如果不需要对分支进行管理,不用记录分支提交节点和主分支的提交记录,那么就使用快速合并
        • 具体的实现步骤:
          • 1、切换到 master 分支;    
          • 2、执行快速合并操作 git  merge  分支名  -m '',将 dev 合并到 master 分支上。
            • -m  为合并备注信息
            • -ff    强制使用快速合并
        • 特点:
          • 合并分支的时候主分支不会创建新的提交,主分支会直接指向更新的分支当前提交
          • 分支的提交记录不会分叉
          • 历史记录上没有父提交记录,因为master值直接指向更新的分支的最新提交,master本身没有提交
      • 非快速合并分支(对分支进行管理)
        • 使用场景
          • 当想要在主分支进行合并的时候,记录主分支的提交记录,和分支的提交记录
          • 有的时候使用快速提交不能成功,这时候要强制使用非快速合并
          • 备注:
            • 如果是由于默认的快速合并不能使用而执行的非快速合并,如果没有添加-m 备注信息 会弹出编辑器提示补充合并备注信息,这时候需要手动将备注信息补充到编辑器中;
        • 具体实现步骤:
          • 1、切换到 master 分支;  
          • 2、执行非快速合并   merge  --no-ff  -m  分支名      '禁用fast-forward合并'
            • --no-ff    强制使用非快速合并
            • -m  为合并提交备注   
            •  备注:使用非快速合并一定要备注信息
        • 特点:
          • 分支合并主分支会创建新的提交,可以在历史记录中查看得到
          • 分支的提交记录会分叉
          • 历史记录上有父提交记录,让提交历史更加清晰
    • 分支删除的过程
      • 合并完分支后,相当于 master 和 dev 现在完全一摸一样了,那么我们这个时候就可以删除 dev 分支。删除 dev 分支就是把 dev 指针给删掉:
      • 步骤:1、我切换到其他分支,只要不是 dev 分支即可;    2、 git  branch -d <name>       删除分支 
  • 创建分支过程和应用命令
    • 查看所有分支,并查看当前的工作分支
      • git  branch
    • 创建一个新的分支,并切换到分支上工作
      • git  checkout  -b  dev
        • -b   代表brand,  创建的时候带该参数
        • 切换到分支上便可以在分支上进行操作,不会影响master分支的版本库;
    • dev分支的工作完成,我们可以切换回master分支
      • git checkout  master
    • 分支进行合并
      • git  merge  dev  将dev分支的工作成果合并到master分支上;
        • git merge 命令用于合并指定分支 到当前分支
        • -m  ' '    添加备注信息
        • --no-ff    强制使用非快速合并
    • 删除dev分支
      • git  branch  -d  dev    删除了分支的指针,即删除了分支
    • 命令总结:
      • 查看分支:   git branch
      • 创建分支:   git branch <name>
      • 切换分支:   git checkout <name>
      • 创建+切换分支:   git checkout -b <name>
      • 合并某分支到当前分支:   git merge <name>
        • --no--ff  强制禁用快速合并,合并后将会自动的提交一次commit
        • -m  添加备注信息    使用--no-ff要使用,不然会弹出编辑器弹框
      • 删除分支:   git branch -d <name>
  • 解决分支冲突
    • 什么是分支冲突
      • 当创建了一个新的分支,并且在分支上对文件进行了操作并且进行了提交
      • 在master分支上对相同的文件也进行了修改并且进行了提交
      • 这时候,分支的修改情况变了这样,这种情况,git无法进行快速合并,因为这种合并可能会有冲突
    • 解决办法
      • 在master分支上手动修改有冲突的文件
        • 文件一般情况下会变成这样
          • <<<<<<HEAD   ******  =====  中的内容是master文件比dev文件多的内容
          • =====   ******  <<<<<<dev   中的内容是devr文件比master文件多的内容
        • 处理步骤:
          • 我们可以将<<<<<<HEAD    、 =====   、<<<<<<dev   手动删除,再进行提交便可以解决冲突
    • 解决后的分支结果
    • 删除分支
  • Bug分支
    • 什么是bug分支
      • 软件开发中,bug 就像家常便饭一样。有了 bug 就需要修复,在 git 中,由于分支是如此的强大,所以,每个 bug 都可以通过一个新的临时分支来修复,修复后,合并分支,然后将临时分支删除。
    • bug分支和其他的分支的区别
      • 担当你正在对代码进行编辑,这项工作你只完成了一半,并不想提交, 但是,现在必须紧急修复 bug 并合并分支,这时候你需要先把你所在分支的工作区stash,stash后你的工作区冻结,不会进行分支合并和提交操作;
    • 处理bug分支的步骤
      • 先将正在处理的工作进行冻结
        • git  stash
      • 从master分支上创建bug分支
        • git  checkout  master      进入master分支
        • git  checkout  -b  bug-01     创建并跳转bug分支
      • 修复bug并提交
        • git add code.txt   上传bug文件到缓存区
        • git  commit  -m ''    将修改进行提交
      • 切换到master分支进行合并
        • git  checkout  master
        • git  merge -m '修复bug'     将bug分支进行合并,stash的分支将不会进行合并
      • 删除bug分支
        • git branch -d  bug -01
      • 切换掉工作分支继续工作
        • git  checkout  dev   切换到工作分支
        • git  stash list   查看被冻结的工作内容
        • git  stash  pop   把工作解冻,将分支状态恢复为冻结之前

 
刘小恺(Kyle) wechat
如有疑问可联系博主