git底层存储原理及常用命令

版本控制工具

集中式(svn)

svn因为每次存的都是差异需要的硬盘空间会相对的小一点可是回滚的速度会很慢

优点:

  • 代码存放在单一的服务器上,便于项目的管理

缺点:

  • 服务器宕机:员工写的代码得不到保障
  • 服务器炸了:整个项目的历史记录都会丢失

分布式(git)

git每次存的都是项目的完整快照需要的硬盘空间会相对大一点
(Git团队对代码做J极致的压缩,最终需要的实际空间比svn多不了太多可是Git的回滚速度极快)

优点:

  • 完全的分布式

缺点:

  • 学习起来比svn陡峭

git基础概念

* 客户端并不只是提取最新版本的文件快照,而是把代码仓库完整的镜像下来
* git核心本质上是一个键值对数据库。可以向该数据库插入任意类型的内容,
  他会返回一个键值,通过该值可以在任意时刻再次检索该内容。

区域

* 工作区 (沙箱环境 git不会管理 随便更改操作)

* 暂存区  (记录文件的操作)

* 版本库   (最终的代码实现提交到这里 .git目录就是版本库)

.git目录下文件的介绍

* hooks (钩子函数的一个库 类似于回调函数)
* info (包含一个全局性的排除文件)
* objects (目录存储所有数据内容)
* refs (目录存储指向数据(分支)的提交对象的指针)
* config (文件包含项目特有的配置选项)
* description (显示对仓库的描述信息)
* HEAD (文件目前被检出的分支)
* logs (日志信息)
* index (文件保存暂存区的信息)

基础Linux命令

* clear 清除屏幕
* echo 'hello word '>test.tet 命令台书写内容
* ll 将当前目录下的子目录展现出来
* find ./ 将当前目录下的子目录以及文件也展现出来
* find ./ -type f 只讲文件展现出来
* rm text.txt 删除文件
* MV a.txt b.txt 更名字
* cat a.txt 查看文件内容
* vim a.txt 编辑内容 i 插入 ese : wq 保存退出 :set nu 设置行号 q! 强制退出不保存

对象

* Git对象
    - echo "hello" | git hash-object --stdin 
     - 这句命令返回一个hash值用来标识这句话 但是并没有写到数据库中  
     - 内容不一样对应的hash值不一样

    - echo "hello" | git hash-object -w --stdin
     - 这句命令返回一个hash值用来标识这句话 并写到数据库中  
     - 查看有没有存在 可以通过 find ./ -type f 找对应hash的文件
     - 里面的内容是压缩的 通过 git cat-file -p hash注意前面的那两个字母也加上
     - git cat-file -t hash 查看git对象的类型 blob

    - 将新创建的文件添加到git数据库中即生成一个git对象
     - git hash-object -w ./a.txt

    - 如果文件更改git数据库里面不会自动的添加要手动添加过去 这时会在添加一个git对象
     - git hash-object -w ./a.txt
    
    - 实质上Git对象是一个KYE:VALUE hash/value    
    - git对象不能当作项目的一次快照 只是组成项目的一部分

    - 存在的问题?
     - 记住文件的每一个(版本)对应的hash值并不现实
     - 在git中,文件名并没有被保存,只能通过hash

    - 注意:此时的操作只是针对本地数据库进行操作,不涉及暂存区。


* 树对象
    * 树对象能够解决文件名保存的问题,也允许我们将多个文件组织到一起。

    * 构建树对象
     - git update-index --add --cacheinfo 100644 915c628f360b2d8c3edbe1ac65cf575b69029b61 test.txt
     - 文件模式为100644 表明这是一个普通文件
     - 文件模式为100755 表明这是一个可执行文件
     - 文件模式为120000 表明这是一个符号连接
     -  --add 因为此前该文件并没有在暂存区中 首次要加add
     -  --cacheinfo 因为要添加的文件在git数据库中,没有位于当前目录下

    * 暂存区做一个快照生成一个对象放到git数据库中
     - git write-tree
        对象类型是一个树对象
        树对象里面的内容是暂存区的快照(项目的快照)
    * 暂存区中文件名字不变 如果改变文件的内容,就会重新生成一个hash

    * 存在的问题?
     - 不知道hash值对应的是哪一个版本
     - 不知道这个版本的一些基础信息    

* 提交对象    
    - 提交对象完美的解决了上面的问题
    - 本质就是给树对象做一层包裹包含项目的基础信息
    - commit-tree创建一个提交对象,为此需要指定一个树对象的hash值,以及该提交的父提交对象  
    - echo "second commit" | git commit-tree     019fb2c522b604cd94929085bbac93d60e2f2063 -p  d248eb19a125c

    - 真正代表一个项目的是一个提交对象(数据和基本信息)这是一个链式的!! 
    
    - 注意:git对象代表文件的一次次版本,树对象代表项目的一次次版本

初始化git

* git init (初始化仓库 生成.git文件)
* git config --global user.name "Is zyd"
* git config --global user.email 1426593075@qq.com
* git config --global --unset user.name  删除配置信息
* git config --global --unset user.email 删除配置信息
* git config --list

添加到暂存区

* git add ./   首先将工作区(文件)做成git对象放到版本库 然后再放到暂存区 但是这里没有生成树对象
* git ls-files -s  查看暂存区的当前状态

添加到版本库

* git commit -m '提交的信息'

结论

* 一次完整的项目提交 包括至少一个提交对象 一个树对象 0或多个git对象
* 工作目录中文件只有两种状态 已跟踪(只要第一次add就跟踪上了) 未跟踪
* 已经跟踪的文件还有三种状态 已提交 已修改 已暂存
* 如果一个已经提交的文件再次修改要重新添加到暂存区否则显示已修改状态
* 如果一个文件暂存完了没有提交前还要在修改 这时会出现一个暂存一个已修改的情况需要重新add
* 
* 分支就是为了保护代码方便更改存在的 假如master里面的提交对象完美了就可以在创建一个分支   添加功能如果可以就可以master合并 不行的话就可以删除这个分支 这样对于master没有影响

* 新建一个分支到一个提交对象上面 这样做的好处是实现版本回推但是不改边主仓库的东西 用完删除这个分支就可以了特别方便

* 合并分支一定要注意顺序 后面的可能会过期还会存在bug 会产生冲突
    - 快速合并 一条分支
    - 典型合并 多条分支 会有冲突(打开冲突文件看哪里要留 然后暂存提交)
    - 同事之间的冲突才是最麻烦的

高级命令(crud)

* git init                初始化

* git add ./              将修改添加到暂存区   
* git commit -m "注释"     将暂存区提交到版本库项目
  git commit
  git commit -a
  git commit -a -m        git自动将已经跟踪过的文件暂存起来一并提交
  
* git rm yd.txt           删除工作目录中对应的文件 再将修改添加到暂存区 版本库多了一个提   交对象和树对象不过没有内容 删除文件属于修改操作 跟上面的提交步骤一样
* git mv 原文件名 新文件名   将工作目录中的文件进行重新命名 再将修改添加到暂存区

* git status              查看文件的状态
* git diff                查看哪些修改还没有暂存
* git diff --staged       查看哪些修改已经被暂存了 还没提交
* git log --oneline       查看提交历史记录

分支

* 分支的本质是一个提交对象,分支都会被HEAD引用(HEAD一个时刻只会指向一个分支)
  当我们有新的提交的时候 HEAD会携带当前持有的分支往前移动
  HEAD:是一个指针。他默认指向master分支,切换分支时其实就是让HEAD指向不同的分支
  每次有新的提交时,HEAD都会带着当前指向的分支一起往前移动
  
* 每一个功能都可以开一个分支,不影响主线的分支
* 分支就是一个活动的指针就在提交对象的前面指向最新提交
* master默认是主分支

* git branch		      显示分支列表
* git branch 分支名        创建分支 在当前提交对象上创建
* git branch 分支名 hash   在指定的提交对象上创建新的分支
* git branch -v  		  查看分支的最后一个提交
* git checkout 分支名      切换分支 切换分支的时候一定要提交完的时候再切否则会出现问题
* git checkout -b 分支名   创建分支并且切换过去
* git branch -d 分支名     删除空的分支,删除已经合并的分支
* git branch -D 分支名     强制删除分支 
* git merge 分支名  		合并分支
* git branch --merge      查看合并到当前分支的分支
* git branch --no-merge   查看没有合并到当前分支的分支列表
* git log --oneline --decorate --graph --all  查看完整的分支图(没删除前)
* git config --global alias.lol "log --oneline --decorate --graph --all" 配别名
* 版本穿梭(时光机) git branch 分支名 哈希

* 每次切换分支前 当前分支一定得是干净的!!!
* 在切换分支时,如果当前分支上有未暂存的修改(第一次)或者未提交的暂存(第一次)
  分支可以切换成功,但是这种操作可能会污染其他分支

存储

* 有时,当你在项目的一部分上已经工作一段时间后,所有东西都进入了混乱的状态,而这时你想要切换到另一个分支做一点别的事情。问题是,你不想仅仅因为过会儿回到这,而为做了一半的工作创建一次提交。
* git stash	将未完成的修改保存到一个栈上,而你可以在任何时候重新应用这些改动(git stash apply)
git stash apply	拿出栈顶的元素 但是不会消除
* git stash list 查看存储
* git stash drop 加上要移除的储藏的名字来移除它
* git stash pop 来应用储藏然后立即从栈上扔掉它

后悔药

* 仅限于被git管理的文件
* 工作区撤回在工作目录中的修改
  * git restore 文件名git
* 暂存区撤回自己的暂存
  * git restore --staged 文件名v
  * git reset HEAD 文件名
* 提交区注释写错了修改注释
  * git commit --amend   

远程协作

1. 远程协作
  * 创建一个空的远程仓库
  * 创建一个待推送得本地仓库
  * git remote add 别名 仓库地址(https) (查看别名git remote -v)
  * 配用户名,邮箱
  * 在本地仓库中初始化代码 提交代码
  * 推送(git push)
  * 邀请成员
  * 成员克隆远程仓库
  * 成员做出修改,推送自己得修改
  * 拉取成员得修改(git pull)
2. 做跟踪
	克隆仓库时,会自动为master做跟踪
	本地没有分支	git checkout --track 远程跟踪分支
	本地已经创建了分支 git branch -u 远程跟踪分支
3. 推送
	git push
4. 拉取
	git pull
5. 使用频率最高得五个命令
	git status
	git add
	git commit
	git push
	git pull

本地分支 远程分支 远程跟踪分支

* 正常的数据推送和 拉取步骤
	1. 确保本地分支已经跟踪了远程跟踪分支
	2. 拉取数据 git pull
	3. 上传数据 git push
* 一个本地分支怎么去跟踪一个远程跟踪分支
	1. 当克隆的时候,会自动生成一个master本地分支(已经跟踪了对应的远程跟踪分支)
	2. 在新建其他分支时 可以指定想要跟踪的远程跟踪分支
		git checkout -b 本地分支名 远程跟踪分支名
		git chrckout --track 远程跟踪分支名
* 将一个已经存在的本地分支 改成一个跟踪分支
	1. git branch -u 远程跟踪分支名  

删除远程分支

* git push 别名 --delete 分支名     删除远程分支
* git remote prune 别名 --dry-run  列出仍在远程跟踪但是远程已经被删除的无用分支
* git remote prune 别名    清除上面的命令列出来的远程跟踪

冲突

* git本地操作的冲突
    * 典型合并的时候
* git远程协作的时候
    * push
        * 两个人同时推(更改同一个文件)解决办法只能先把远程仓库拉下来 然后再更改那个    文件然后再add commit push  
    * pull
        * 更改完以后不push 直接pull会报错 远程仓库会覆盖更改的内容建议push 不过push还会出错就是上面那个错误

参加开源项目的步骤 (pull request)

* 如果参加某个项目时,但是没有推送权限,这时候可以通过对这个项目进行fork。这会在
  你的空间中创建一个完全属于你的项目副本,且你对其具有推送权限。通过这个方式项目的
  管理者不用忙着添加贡献者,人们可以fork这个项目将修改推送到项目副本上,并通过pull 
  request来将他们的改动进入源版本库

1. 先将源仓库fork到自己的仓库
2. 然后clone到本地仓库
3. 更改后提交到自己的远程仓库
4. pull request
5. 管理人审核 然后merge

* 不重新fork怎么解决
  * git 支持同时跟踪多个仓库
    git remote add 别名2 地址
    <!-- git remote rm 别名1 -->
    git fetch 别名2
    git branch -u 远程跟踪分支
    git merge 对应的远程跟踪分支
    git push (这里还是会提交到自己上面)
    然后pull request

SSH

* github特有的一种协议 走的不是验证密码的道路而是密匙
* 配置步骤
  * ssh -keygen -t rsa -C 邮箱名
  * 在c:\users\Adminstor\.ssh下生成公私密匙
  * ssh -T git@github.com 测试一下
  * 把公共的密匙复制到github账户里面setting下
  * 好处是不用每次输密码 而且项目经理不用设置贡献者 直接把他们的公共密匙复制到自己账户就可以了

.gitnore文件

* 这个文件可以直接从github上下载
* 目的是不在git仓库上传不必要的文件
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值