20171130 Git

一、Git的基本概念:

(一)版本控制工具的分类

  • 本地版本控制系统:rcs
  • 集中化的版本控制系统:cvs, svn
  • 分布式的版本控制系统:bitkeeper, Git

(二)Git的工作目录分类

  • 工作区:Working Directory,工作目录中除.git目录外的部分
  • 暂存区:Staging Area,索引对象
  • 版本库:Repository,对象库

(三)Git配置文件:git config

  • 仓库特有:REPO/.git/config
  • 用户全局:~/.gitconfig, --global
  • 系统:/etc/git/gitconfig, -system

(四)Git的对象类型: .git/objects

  • 块(blob)对象:文件的每个版本表现为一个块(blob)
  • 树(tree)对象:一个目录代表一层目录信息
  • 提交(commit)对象:用于保存版本库一次变化的元数据,包括作者、邮箱、提交日期、日志;每个提交对象都指定一个目录树对象
  • 标签(tag)对象:用于给一个特定对象一个易读的名称

(五)Git中的文件分类:分为三类

  • 已追踪的(tracked):已经在版本库中,或者已经使用git add命令添加至索引中的文件
  • 被忽略的(Igored):在版本库中通过“忽略文件列表”明确声明为被忽略的文件
  • 未追踪的(untracked):上述两类之外的其它文件

二、Git基础操作:暂存、提交

(一)add/rm/mv命令:

  • git add:暂存文件,添加至索引

  • git ls-files:
    默认显示索引中的文件列表的原始文件名
    -s:显示暂存的文件信息:权限、对象名、暂存号及原始文件名
    -o:显示未被追踪的文件

  • git rm:
    git rm:删除工作目录中的文件,及索引中的映射
    git rm --cached:只删除索引中的映射

  • git mv:
    git mv:改变工作目录中的文件名,及索引中的映射

(二)提交相关的命令:

  • git commit:提交至版本库

  • git log:查看提交日志

  • 提交的标识:
    引用:reference, SHA1, 绝对提交名
    符号引用:symbolic reference
    refs/heads/REF:本地特性分支名称
    refs/remotes/REF:远程跟踪分支名称
    refs/tags/REF:标签名

  • Git会自动维护几个特定目的的特殊符号引用:
    HEAD:始终指向当前分支的最近提交;或检出到其它分支时,目标分支的最近提交
    ORIG_HEAD:合并操作时,新生成的提交前面的那一个提交保存于此引用中
    FETCHED_HEAD:指向着目前已经从远程仓库取下来的分支的最近提交
    MERGE_HEAD:合并操作时,其它分支的上一次提交

  • git diff:比较提交、索引及工作目录

  • git reset:撤消此前的操作
    --soft:将HEAD引用指向给定的提交,但不影响索引和工作目录
    --mixed:将HEAD引用指向给定的提交,并将索引内容改变为指定提交的快照;但不改变工作目录
    --hard:将HEAD引用指向给定的提交、将索引内容改变为指定提交的快照,并改变工作目录中的内容反映指定提交的内容

  • 实验1:Git的基础操作举例

    • 建立目录,Git初始化本目录,在本目录下建立.git的隐藏目录
    mkdir -pv testapp/examples
    cd testapp/
    git init
    tree .git/
    
    20171130 Git_第1张图片
    • 上图展现了git目录结构,主要包含:
      branches:分支信息
      HEAD:指向当前分支的指针
      objects:Git对象
      refs:引用

    • 每一次git add操作都会在.git/objects目录中产生blob对象文件

    echo test line 1 > README
    git add README
    echo test line 2 >> README 
    git add README
    tree .git/
    
    20171130 Git_第2张图片
    • git add将变动文件存入暂存区后,git status可以提示当前的commit状态,并且查看上一次commit后变动的文件
    echo test example line 1 > examples/example01
    git add examples/example01
    git status
    
    20171130 Git_第3张图片
    • git commit后在.git/objects目录中新产生了很多commit对象文件
    git commit -m "v 0.1"
    tree .git/
    
    20171130 Git_第4张图片
    • git commit提交后,git status查看状态提示工作目录"clean";
      git log查看commit历史,可以明确看到本次提交的对象文件名以及提交者、提交时间、提交摘要信息
    git status
    git log
    
    20171130 Git_第5张图片
    • git ls-files查看当前索引文件的原文件名信息
    git ls-files
    git ls-files -s
    
    20171130 Git_第6张图片
    • 至此,可以总结一下git commit后.git/objects目录下的对象文件内容:
      0e---c52bcb201df969d28819ee5e67c0e817e35951
      git add examples/example01产生的blob对象
      1e---06d5b2a1a27e4f769348117e613ca0ddfa102f
      第二次git add README产生的blob对象
      3e---458f63a7d3d4a23a8cc4d5ddcff976eaaf02e6
      git commit产生的tree对象
      61---e358aa4aea526ce0b55bd6d1aaf266c2bf7cb3
      第一次git add README产生的blob对象
      ce---fefb13e8ae824aa4d59e464f4dae0a550b0dfd
      git commit产生的tree对象
      fe---3fc696f08c9488ac94070d284cbaf9e786205e
      git commit产生的commit对象

    • 总结:
      每一次git add操作都会产生blob对象
      每一次git commit操作都会产生变动目录(从发生变动的文件所在目录至工作目录的所有层级目录)的tree对象,以及本次commit的commit对象

  • 实验2:Git的撤销操作举例

    • 修改README文件,git add添加至缓存区,git commit提交版本库
    echo test line 3 >> README 
    git add README
    git commit -m "v 0.2"
    git log
    
    20171130 Git_第7张图片
    • soft模式撤销,可以看到git commit操作被撤销
    git reset --soft fe3fc6    // 取目标对象文件名的前6位左右即可
    git log
    
    20171130 Git_第8张图片
    • 但是soft模式撤销下,blob对象没有撤销,文件的修改没有被撤销
    git ls-files -s
    cat README
    
    20171130 Git_第9张图片
    • 此时,只需执行git commit操作即可
    git commit -m "v 0.2.1"
    git log
    
    20171130 Git_第10张图片
    • mixed模式下的撤销不仅撤销了git commit操作,而且撤销了git add操作(注意两次git ls-files操作结果中README对应blob文件的变化),但文件的修改没有被撤销
    git ls-files -s
    git reset --mixed fe3fc6
    git log
    git ls-files -s
    cat README
    
    20171130 Git_第11张图片
    • 此时,执行git add和git commit操作
    git add README
    git commit -m "v 0.2.2"
    git log
    
    20171130 Git_第12张图片
    • hard模式下的撤销将git commit, git add操作全部撤销,并且文件内容的修改也被撤销,故此模式危险性较大
    git reset --hard fe3fc69
    git log
    git ls-files -s
    cat README
    
    20171130 Git_第13张图片
    • 注意,撤销操作并未真正删除blob, commit对象文件,只是将原来指向他们的指针指向命令指定的之前操作的位置

    • 使用tree .git/命令查看此时的.git目录,发现之前git commit -m "v 0.2.2"时产生的commit对象82---ee06b08e0fb3dd3e3fcd8ecc30c289e38590bf和之前git add README产生的blob对象85---d402490f750fd3e2439e81aeb9f37b217b2705仍旧存在

    • git的撤销操作只是指针的移动,不涉及对象文件的删除,故出现git层面无法恢复的误操作时,理论上还可以在文件层面尝试修复

三、Git分支:

  • 分支命名法则:
    可以使用/,但不能以/结尾
    不能以-开头
    以位于/后面的组件,不能以.开头
    不能使用连续的...
    不能使用空白字符
    不能使用^, ~, ?, *,[等

  • git分支操作基础命令
    git branch BRANCH_NAME [START_COMMIT]:创建分支
    git branch -d BRANCH_NAME:删除分支
    git show-branch:查看分支及其相关的提交
    git checkout :检出分支

  • 分支合并:
    合并基础:要合并的分支的最近一次的共同提交
    我们的版本:当前分支的最近一次提交
    他们的版本:要合并进来的分支的最近一次提交

  • 无冲突合并:
    $ git checkout master
    $ git status
    $ git merge BRANCH_NAME
    $ git log --graph --pretty=oneline --abbrev-commit

  • 有冲突合并:
    手动解决冲突后,重新git add, git commit

  • 变基操作:git rebase
    $ git checkout dev
    $ git rebase master
    $ git checkout master
    $ git merge -m "MSG"

  • git merge(合并)与 git rebase(变基)的区别:

20171130 Git_第14张图片
  • 实验3:Git的分支管理举例

    • 从commit: "v 0.2.3" 开始建立分支bugfix01,并进行了一次commit: "v 0.2.3.1"
    echo test 4 >> README     // 主分支上的操作
    git branch bugfix01     // 建立分支bugfix01
    git checkout bugfix01     // 检出分支bugfix01,转入分支bugfix01
    echo test 5 >> README
    git add README
    git commit -m "v 0.2.3.1"
    git log
    
    20171130 Git_第15张图片
    • 合并分支
    git checkout master     // 转入主分支
    echo test example line 2 >>  examples/example01
    git add examples/example01
    git commit -m "v 0.3"
    git merge bugfix01     // 合并分支
    git log --graph --pretty=oneline --abbrev-commit
    cat README
    cat examples/example01
    
    • 主分支最近一次commit: "v 0.3"
    20171130 Git_第16张图片
    • 分支合并后的commit演进
    20171130 Git_第17张图片
    • 可以看到主分支对examples/example01的改变和bugfix01分支对README的改变都在分支合并后得到了体现
    20171130 Git_第18张图片

四、Git分布式版本管理

  • Git服务器支持的协议类型:
    本地协议(local)、HTTP/HTTPS协议、SSH协议、Git协议

  • 从Git服务器克隆操作:
    git clone URL

  • URL格式:

    • 本地协议:
    /path/to/repo.git 
    file:///path/to/repo.git 
    
    • Git协议:由git-daemon程序提供,监听在tcp的9418端口;仅支持“读”操作,无任何认证功能
    git://host/path/to/repo.git
    git://host/~user/path/to/repo.git 
    
    • SSH协议
    ssh://[USER@]host[:port]/path/to/repo.git
    ssh://[USER@]host[:port]/~USERNAME/path/to/repo.git
    
    • HTTP/HTTPS协议:从1.6.6版开始支持智能http协议,支持读/写/认证

    http://host/path/to/repo.git

五、引用远程版本库:

  • git remote命令:管理远程仓库

  • git fetch:取回远程服务器的更新

  • git pull:取回远程服务器更新,而后与本地的指定分支合并
    git pull <远程主机名> <远程分支名>:<本地分支名>

  • git push:将本地的更新推送到远程主机
    git push <远程主机名> <本地分支名>:<远程分支名>

  • 实验4:实现克隆远程版本库至本地,在本地修改后推送更新至远程版本库

    • 在github网站上注册账号,建立一个项目仓库"testapp1",可以自动为其生成一个README文件,并添加开源证书"Apache License 2.0"
    20171130 Git_第19张图片
    • 在项目页的右上方"Clone or download"下,点击红框按钮将https网址复制下来作为git clone操作的URL
    20171130 Git_第20张图片
    • 执行git clone操作将远程项目克隆至本地,对项目进行修改(文件的修改,git add,git commit等操作),并推送更新至远程项目
    git clone https://github.com/hellopeiyang/testapp1.git     // 从远程克隆项目至本地
    cd testapp1/
    echo "test line 1" > testfile                              // 创建一个新文件
    git add testfile
    git commit -m "v 0.1"                                      // 创建一个新commit
    git log
    // 为最近的commit: "v 0.1"建立一个标签"testapp-v0.1"
    git tag -a testapp-v0.1 -m "testapp-v0.1" 948a23  
    git tag --list
    ls .git/refs/tags/                                         // tag标签在.git目录中的位置
    git push --tags origin master                              // 将本地项目推送至远程
    
    • 在本地创建的commit: "v 0.1",可以为本次commit创建一个tag: "testapp-v0.1"
    20171130 Git_第21张图片
    • 本地项目更新推送至远程,输入注册的账号和密码
    20171130 Git_第22张图片
    • 远程项目成功获得更新,可以看到新增的文件testfile和最近的commit: "v 0.1"
    20171130 Git_第23张图片
  • 实验5:利用GitLab搭建一个类似GitHub的平台,同样实现实验4的操作

    • 在服务器主机上安装gitlab服务
    rpm -ivh gitlab-ce-8.8.3-ce.0.el7.x86_64.rpm     // 安装gitlab全自动安装包
    gitlab-ctl reconfigure                           // 执行gitlab环境配置
    gitlab-ctl start                                 // 启动gitlab
    
    • 浏览器登录服务器主机,自动进入管理员密码修改页面
    20171130 Git_第24张图片
    • 要求注册账户,注册成功后进入管理页面,建立自己的项目testapp2
    20171130 Git_第25张图片
    • 建立项目完成后,点击红框中按钮复制项目仓库http地址
    20171130 Git_第26张图片
    • 克隆远程项目至本地,在本地就行修改,同步本地项目至远程,与实验4类似
    git clone http://node0.hellopeiyang.com/morningpeiyang/testapp2.git
    cd testapp2
    echo "test file 1" > testfile
    git add testfile
    git commit -m "v 0.1"
    git push origin master
    
    20171130 Git_第27张图片
    • 此时远程项目已经获得了更新
    20171130 Git_第28张图片

你可能感兴趣的:(20171130 Git)