学习随笔(一):Git 基本概述与工作原理

一,Git 与SVN 区别

  1. 管理方式不同

  • Git是分布式的,而svn是远程集中式
  • Git的每一个客户端都有一个仓库,即便是服务器断网了,也能够提交当前的代码版本与分支,可以进行任意的Git操作,只需要在能访问服务端的时候push上去就可以了

  2.存储方式不同

  • Git 是以元数据的方式存储,类似key-value 的结构,而svn是以文件的方式存储(新版的svn已经改成元数据存储方式)
  • 所以Git存储方式所占用空间相比svn更小

  3. 使用方式不同

  • svn 使用更简单,更加方便,直接可以commit提交远程仓库
  • Git 需要先添加到暂存区add,提交到本地库 commit,然后同步推送服务端 push

    

  4. 其他区别

  • Git没有一个全局版本号,而SVN有:目前为止这是跟SVN相比Git缺少的最大的一个特征
  • Git内容存储采用SHA-1哈希算法,这能确保代码内容的完整性,确保在遇到磁盘故障和网络问题时降低对版本库的破坏
  • 克隆一个分支,svn相当于下载那个分支的全部文件,非常耗时,而Git则是载入主要分支,克隆时只需要获取分支版本元数据

 


二, Git核心命令使用

  1. 创建项目并提交

1. $=> git init qingmu 会创建一个青木的文件夹,里面会有.git目录
2. $=> git status 用于显示工作目录和暂存区的状态
3. $=> git add README.MD 添加一个文件到暂存区
4. $=> git add -A 添加所有文件到暂存区
5. $=> git rm --cached README.MD 从暂存区删除,并不会删除本地文件
6. $=> git commit README.MD -m '第一次提交' 提交文件,并且带上说明
7. $=> git commit -a '提交全部' 提交所有暂存区文件
8. $=> git remote add origin https://gitee.com/yue22/YX-Cloud.git 添加远程仓库,origin表示默认远程仓库空间名称,可以自定义。
9. $=> git push --set -upstream origin master 添加上游主分库
10. $=> git push --set -upstream origin master 添加上游主分支到仓库
11. $=> git pull 从远程仓库更新代码到本地

  2. 分支管理  

1. $=> git branch [-avv] 查看当前分支
2. $=> git branch <branch name> 基于当前分支版本新建一个分支
3. $=> git branch <new branch name> <old branch name> 基于指定分支(包括远程与本地分支)创建
4. $=> git branch <branch name> <commit id> 基于提交的某个版本新建分支
5. $=> git branch -d <branch name>...   删除分支,可以多个
6. $=> git checkout <branch name> 切换分支
7. $=> git merge <merge target> 合并目标分支
# 如果合并分支出现冲突,会导致合并失败,此时status 为mergeing 状态
# 需要手动修改后重新提交

  3. 远程仓库管理

1. $=> git remote [-v]  查看远程仓库配置
2. $=> git remote add <name> <git url> 添加新的远程仓库
3. $=> git remote remove <name>  删除远程仓库
4. $=> git remote --set-upstream <name> <branch name> 上传指定分支到指定的远程仓库

  4. tag管理(tag 为只读标签)

1. $=> git tag  查看当前标签
2. $=> git tag <tag name> <branch> 基于指定分支打标签
3. $=> git tag -d <tag name> 删除标签

  5. 日志管理

1. $=> git log <--oneline> 查看主分支提交日志 , 参数表示一行显示,比较简洁
2. $=> git log <branch name> <--oneline> 查看指定分支提交日志
3. $=> git log <branch name1>.. <branch name2> 比较两个分支的版本差异2相对于1有多少版本没有合并
4. $=> git log --grapth --oneline 显示提交日志的网络
5. $=> git show <版本号> 查看指定版本号提交内容

三,Git基本原理

  • Git存储对象
  • Git树对象Git提交对象
  • Git引用

  1. Git存储对象

  • Git 是一个内容寻址文件系统,其核心部分是键值对数据库,向该数据库提交的内容都是以键值对存储,同时返回该值的键,可以通过键取回存储文件内容
# 往git 数据库中插入数据
$=> echo 'content data' | git hash-object -w --stdin
# 返回数据库键值对的键值
$=> 79362d07cf264f8078b489847132afbc73f87b9a
# 基于键值取回数据
$=> git cat-file -p 79362d07cf264f8078b489847132afbc73f87b9a

Git 基于每个文件中内容生成一个hash码,当同一个文件提交相同的内容的时候返回的hash key值是相同的

- 1. $ find .git/objects/ -type f   查看git 数据库中所有对象,包括存储对象、树对象、提交对象
- 2. 当我们修改内容后git add 添加到暂存区时,这个时候会生成相应内容的文件存储对象,如下图:                                              

  

  2.Git 树对象与Git提交对象

1. $ git commit -a -m '第一次提交'   提交暂存区的文件的文件对象,这个时候会生成一个commit 提交对象,一个树根节点对象,一个或多个树子节点对象,以及多个文件内容存储对象
2. $ git log  查看当前提交返回的提交对象key值
3. $ git cat-file -p 55b09dd79 通过返回的提交对象key值查询内容可获得,树根节点对象,以及作者,上一次提交对象等等信息
4. $ find .git/objects/ -type f  查询所有对象结构,可以一一对应上面几种对象类型   

  

5. $ git cat-file -p  cdbc7199296  查询根节点工作树,可以看到里面包含了一个文件对象的信息,一个文件目录的对象信息  

  

  • 对应的文件结构如下:

  

  • 1. 基于它的基本原理,我们可以知道,每一次的提交版本只要有内容改变必然会生成一个不同版本的提交对象commit,
  • 2. 由于树的子节点内容改变将导致树根节点也会生成不同的树根节点对象
  • 3. 而其他没有发生改变的文件并不会生成新的对象
  • 4. 整体为一个树形结构,当我们修改或新增某个文件以后只会影响当前文件对象与所有的父节点对象
  • 5. 这样当我们回滚某个提交版本时,通过日志文件可以查找指定版本的提交对象,然后与当前版本提交对象的工作树比对,只需要一次轮询或者递归便可以找出版本之间的差异,找到工作树对应节点文件内容,这样就能以非常快的速度完成版本的切换

  3.Git引用

  • 分支的管理其实就是对提交对象的管理,如下图我们可以发现,master分支其实就是引用的某一个提交对象的key值

  

  • 这个key值正好对应了我们最近一次的提交对象的key值 

  

  • 同理,tag标签以及各种其他分支也是引用了某一次提交对象而实现分支分管理的

吐槽:有点乱,这里抄一点,那里改一点,凑合着看。如有部分内容侵权,请原创作者联系本人修改。谢谢

原文地址:https://www.cnblogs.com/qmuyw/p/12916745.html