20171130 Git

作者: 哈喽别样 | 来源:发表于2017-12-02 17:10 被阅读4次

    一、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/
      
      • 上图展现了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/
      
      • git add将变动文件存入暂存区后,git status可以提示当前的commit状态,并且查看上一次commit后变动的文件
      echo test example line 1 > examples/example01
      git add examples/example01
      git status
      
      • git commit后在.git/objects目录中新产生了很多commit对象文件
      git commit -m "v 0.1"
      tree .git/
      
      • git commit提交后,git status查看状态提示工作目录"clean";
        git log查看commit历史,可以明确看到本次提交的对象文件名以及提交者、提交时间、提交摘要信息
      git status
      git log
      
      • git ls-files查看当前索引文件的原文件名信息
      git ls-files
      git ls-files -s
      
      • 至此,可以总结一下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
      
      • soft模式撤销,可以看到git commit操作被撤销
      git reset --soft fe3fc6    // 取目标对象文件名的前6位左右即可
      git log
      
      • 但是soft模式撤销下,blob对象没有撤销,文件的修改没有被撤销
      git ls-files -s
      cat README
      
      • 此时,只需执行git commit操作即可
      git commit -m "v 0.2.1"
      git log
      
      • 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
      
      • 此时,执行git add和git commit操作
      git add README
      git commit -m "v 0.2.2"
      git log
      
      • hard模式下的撤销将git commit, git add操作全部撤销,并且文件内容的修改也被撤销,故此模式危险性较大
      git reset --hard fe3fc69
      git log
      git ls-files -s
      cat README
      
      • 注意,撤销操作并未真正删除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 <branch>:检出分支

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

    • 无冲突合并:
      $ 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(变基)的区别:

    • 实验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
      
      • 合并分支
      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"
      • 分支合并后的commit演进
      • 可以看到主分支对examples/example01的改变和bugfix01分支对README的改变都在分支合并后得到了体现

    四、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"
      • 在项目页的右上方"Clone or download"下,点击红框按钮将https网址复制下来作为git clone操作的URL
      • 执行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"
      • 本地项目更新推送至远程,输入注册的账号和密码
      • 远程项目成功获得更新,可以看到新增的文件testfile和最近的commit: "v 0.1"
    • 实验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
      
      • 浏览器登录服务器主机,自动进入管理员密码修改页面
      • 要求注册账户,注册成功后进入管理页面,建立自己的项目testapp2
      • 建立项目完成后,点击红框中按钮复制项目仓库http地址
      • 克隆远程项目至本地,在本地就行修改,同步本地项目至远程,与实验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

        本文链接:https://www.haomeiwen.com/subject/omobbxtx.html