git-底层-高层指令

一 版本控制

版本控制最重要的就是历史记录

1 集中化的版本控制系统

集中化的版本控制系统诸如 cvs,svn以及 perforce 等,都有一个单一的集中管理的服务器,保存所有文件的修订版本,而协同工作的人们都通过客户端连到这台服务器,取出最新的文件或者提交更新

优点:每个人都可以在一定程度上看到项目中的其他人正在做些什么。而管理员也可以轻松掌控每个开发者的权限,并且管理一个集中化的版本控制系统; 要远比在各个客户端上维护本地数据库来得轻松容易

缺点:

① 中央服务器的单点故障。如果服务器宕机一小时,那么在这一小时内,谁都无法提交更新,也就无法协同工作

② 中央服务器的磁盘发生故障,碰巧没做备份,或者备份不够及时,就会有丢失数据的风险

③ 最坏的情况是彻底丢失整个项目的所有历史更改记录

2 分布式的版本控制系统

在这类系统中,像 Git,BitKeeper 等,客户端并不只提取最新版本的文件快照,而是把代码仓库完整地镜像下来。这么一来,任何一处协同工作用的服务器发生故障,事后都可以用任何一个镜像出来的本地仓库恢复。因为每一次的提取操作,实际上都是一次对代码仓库的完整备份。

分布式的版本控制系统在管理项目时 **存放的不是项目版本与版本之间的差异.**它存的是索引(所需磁盘空间很少所以每个客户端都可以放下整个项目的历史记录)

解决了集中式版本控制系统的缺陷:

① 断网的情况下可以进行开发(因为版本控制是在本地进行的),连不上服务器也可以进行开发!

② 每个客户端保存的也都是整个完整的项目(包含历史记录的! 更加安全)

二 git核心概念

1 git本地操作

三条主线:
1. 集中式版本控制系统 vs 分布式版本控制系统
2. 工作目录 暂存区 版本库
    workspace : 工作目录
    .git/index: 暂存区
    .git/objects: 版本库
3. git对象 树对象 提交对象
    git对象: git存储内容的最基本单位;一个git对象代表一个文件的版本
             缺点: 没有存储文件名;记住git对象的hash不太现实
    树对象:  是暂存区在某一时刻的快照;一个树对象代表一个项目的版本
             缺点: 没有项目版本的注释;记住树对象的hash不太现实
    提交对象: 是对树对象的包裹;记住提交对象的hash不太现实
              缺点: 记住提交对象的hash不太现实
    分支: 本质就是一个提交对象
               可以不用再记提交对象的hash;记住当前所处的分支即可(默认主分支master)

2 git底层命令

2.1 .git 目录
hooks         目录包含客户端或服务端的钩子脚本;
info          包含一个全局性排除文件
logs          保存日志信息
objects          目录存储所有数据内容(版本库)
refs             存所有分支
config        文件包含项目特有的配置选项
description   用来显示对仓库的描述信息
HEAD             当前所处分支
index            暂存区信息
2.2 git对象

Git 的核心部分是一个简单的键值对数据库。你可以向该数据库插入任意类型的内容,它会返回一个键值,通过该键值可以在任意时刻再次检索该内容

创建一个新文件并将其内容存入数据库:
echo 'version 1' > test.txt : 创建一个新文件
git hash-object -w 文件路径;(将文件内容以bolb的格式存储到git的版本库中)
git hash-object 文件路径 :返回对应文件的键值   hash值
查看数据内容:
find .git/objects -type f  : git存储数据
git cat-file -p hash ; 通过hash拉取对应的内容
git cat-file -t hash ; 通过hash拉取对应的内容的类型

问题:

① 记住文件的每一个版本所对应的 SHA-1 值并不现实

② 在Git中,文件名并没有被保存——我们仅保存了文件的内容

解决:树对象

2.3 树对象

树对象(tree object),它能解决文件名保存的问题,也允许我们将多个文件组织到一起。一个树对象包含了一条或多条记录(每条记录含有一个指向git对象或者子树对象的 SHA-1 指针,以及相应的模式、类型、文件名信息)。一个树对象也可以包含另一个树对象

  • 创建首个版本-创建一个暂存区

    echo 'version 1' > test.txt
    git hash-object -w test.txt
    git update-index --add --cacheinfo 100644 git对象的hash 文件名:修改暂存区
    git write-tree : 生成树对象
    
  • 将两个版本塞入暂存区

    echo 'new file' > new.txt
    .....编辑test.text
    git update-index --add 文件名(new.txt)
    等价于下面两个:
    	git hash-object -w test.txt 生成new.txt对应的hash
    	git update-index --add --cacheinfo 100644 git对象的hash new.txt
    git update-index --add test.txt
    git write-tree 第二个树对象
    
  • 将第一个树对象加入第二个树对象,使其成为新的树对象

git read-tree -prefix=bak hash   把树对象读入暂存区
git write-tree

git ls-files -s : 查看暂存区
2.4 提交对象

我们可以通过调用 commit-tree 命令创建一个提交对象,为此需要指定一个树对象的 SHA-1 值,以及该提交的父提交对象(如果有的话 第一次将暂存区做快照就没有父对象)

创建提交对象:

echo "注释" | git commit-tree 树对象的hash -p 上一次的提交对象的hash
echo 'second commit' | git commit-tree 0155eb -p fdf4fc3

查看提交对象:

git cat-file -p hash

注意:

git commit-tree不但生成提交对象而且会将对应的快照(树对象)提交到本地库中

3 git高层命令

git init    : 初始化git仓库;生成一个.git目录
                .git/objects : 版本库
                .git/index   : 暂存区
                .git/HEAD    : 版本库当前所处的分支

git add ./  : 将当前目录下的所有文件加入到版本库生成对应的git对象
              再将每一个git对象及其对应的文件名注册到暂存区
              相当于 git hash-object & git update-index的结合
git commit -m "注释" : 对暂存区做快照生成对应的树对象;
                      对树对象进行包裹注释;生成对应的提交对象
                      将当前生成的提交对象的hash赋值给主分支
                      相当于 git write-tree & git commit-tree的结合

4 DOS命令(windows)

cls : 清除屏幕

5 linux命令

clear :清除屏幕
echo 'test content':往控制台输出信息
echo 'test content' > test.txt : 创建文件并将控制台的信息放到该文件中
ll :将当前目录下的 子文件&子目录平铺在控制台
find 目录名: 将对应目录下的子孙文件&子孙目录平铺在控制台
find 目录名 -type f :将对应目录下的文件平铺在控制台
cat 文件的url : 查看对应文件的内容
mv 源文件 重命名文件: 重命名
rm  文件名 : 删除文件
vim 文件的url(在英文模式下)
    按 i 进插入模式  进行文件的编辑
    按 esc键再按:键 进行命令的执行
            q!   强制退出(不保存)
           	wq  保存退出
            set nu 设置行号

三 git高层命令

1 CRUD(create、read、update、delete)

初始化仓库:git init
查看文件状态:git status
加入暂存区:   git add ./
提交到版本库: git commit -m "注释"
跳过暂存区进行提交(对应的文件已经被提交过一次)  git commit -a -m "注释"
1.1 create新增
git status:查阅新增和修改的文件
git add ./ & git commit -m "注释"
1.2 update更新
git status:查阅新增和修改的文件
git add ./ & git commit -m "注释"  或者 git commit -a -m "注释"
1.3 delete删除
删除工作目录中对应的文件 & git add ./
git commit -m "注释" 或者 git rm 对应的文件
git commit -m "注释"
1.4 read查询
git status:查看项目中文件的状态
           红:文件没有被纳入到暂存区
           绿:文件纳入到暂存区但是还未提交
           空:文件已经被提交
git log --oneline:查看提交链 (当前分支所拥有的提交链,看不到完整的提交链)
git diff : 当前做的哪些事情还没有暂存
git diff --staged :有哪些更新已经暂存起来准备下次提交
git reflog
1.5 重命名
重命名对应的文件 & git add ./
git commit -m "注释"  
或者
git mv 原文件名 新文件名
git commit -m "注释"
1.6 配别名
git congif --list : 查看本地的git配置,所有alias开头的都是别名配置
git config --global alias.damu status : 新增别名
git congfig --global --unset alias.damu : 删除别名

配置别名:

$ git config --global alias.co checkout 
$ git config --global alias.br branch 
$ git config --global alias.ci commit 
$ git config --global alias.st status  
$ git config --global alias.lol  “log --oneline --decorate --graph --all”
可以看到完整的分支图

2 分支(git杀手锏)

2.1 查看分支列表
git branch 
2.2 创建分支
git branch name             指向当前所处分支所指向的提交对象
git branch -merged          查看哪些分支已经合并到当前分支
git branch --no-merged      查看所有包含未合并工作的分支
git branch name commitHash  新建一个分支并且使分支指向对应的提交对象
2.3 切换分支
git checkout name (不用考虑上下级关系)
最佳实践:一定要在最干净的状态下切换(没有提交到仓库)git st 查看
如果在切换分支的时候,状态不干净,又必须得切,要使用git存储
git checkout -b name 切换并新建分支
最佳实践:不要再空分支上切换分支

切换分支的时候动了几个区域?

① HEAD ② index(暂存区) ③工作目录

2.5 git存储
git stash:将当前内容存储起来
git stash list:查看存储
git stash apply 存储名: 应用存储
git stash drop 存储名:删除存储
git stash pop  应用栈顶存储并删除
2.6 合并分支
git merge 分支名   分清谁合并谁 上级合并下级,并删除下级
快进合并:永远都不会产生冲突,也不会生成新的提交对象 
典型合并:可能会产生冲突,一定会生成新的提交对象
2.7 删除分支
git branch -d name
git branch -D 强制删除
2.8 案例

原有代码:master.txt 是稳定的代码,不要动。初始化开发

分支代码:dev.txt

git checkout -b dev
git branch   ----master dev
git chenkout -b wang 在dev上新建切换wang.txt 并提交 修改再保存 git status
git stash   git st 保存起来
git checkout master  git log --oneline 不能直接改
git chenkout -b hotbug 重新切一个 修改并提交  查看git log --oneline 
git checkout master   git merge hotbug 在主分支上进行合并(快进合并)
git branch -d hotbug   在主分支上删除紧急分支    查看git  status 
git stash list 
git stash pop  拿到并删除
进行最终的提交
git log --oneline 只能查看当前文件下的对象
git lol(lol是别名)
git checkout dev  在dev上合并并进行删除
git merge wang
git branch -d wang  
git checkout master(记得检查是够干净模式)
git merge dev   会生成一个新的提交对象 进入vim模式  i(插入)  esc wq!(保存退出)
git branch -d dev

演示冲突:

在master创建v1.txt并提交 修改再次提交 git lol
git co -b a  修改再次提交
切到master git co -b b
再次修改  提交  git lol 
在masret 快速合并 git merge  b  删除git br -d b  git lol
git merge a 产生了冲突   沟通好后手动修改提交即可git add ./ git commit -m ""
2.9 数据恢复:时光机

制定提交对象创建分支

git branch name(分支名)  commithash(提交对象的hash)
git lol

3 后悔药 重置撤销

3.1 重置reset
git ls-files -s     查看暂存区内容   git cat-file -p hash
cat .git/HEAD        查看head内容
git reset --soft commithash(HEAD~)   动HEAD
git reset --mixed HEAD~              动了两个区域  动HEAD index
git reset --hard HEAD~  			 动了三个区域  动HEAD index  工作目录
切换分支:git checkout 分支名  也是动了三个区域 但是有保护机制,防止数据丢失
3.2 路径重置:
git reset --soft HEAD~ filepath :不允许进行路径重置的
git reset [--mixed] commithash filepath:支持路径重置,动index,不建议指定提交对象
	建议使用 git reset filepath 相当于 git reset HEAD filepath
git reset --hard commithash filepath:
不允许进行路径重置,可以hard的变种checkout支持,只动index,工作目录
	git checkout 分支名 filepath 相当于 git reset --hard 分支名对应的提交对象 filepath
	git checkout -- filepath 相当于 git reset --hard HEAD filepath

git checkout -h 信息查询
3.3 撤销对工作目录的修改:本质上是一个覆盖操作
git checkout 路径(可以是文件也可以是文件夹)
3.4 撤销对暂存区的修改:本质上是一个覆盖操作
git reset  file
3.5 撤销对版本库的修改
① 提交注释写的有问题
git commit ---amend -m "重新填注释"
	相当于 git reset --soft HEAD~ 加 git commmit -m "重新填注释"
git log 看不到上次的提交
git reflog
② 提交完发现有修改但是没有进暂存区
git add ./
git commit --amend -m "重新填注释"
3.5 回滚

版本的回滚

git st 
git reset --hard hash 

回滚到之前的版本

git  reflog  
git reset --hard hash 

4 git特点

① 直接记录快照,而非差异比较

② 近乎所有操作都是本地执行

③ 时刻保持数据完整性

④ 文件的三种状态

  • 已提交 已提交表示该文件已经被安全地保存在本地数据库中了
  • 已修改 已修改表示修改了某个文件,但还没有提交保存
  • 已暂存 已暂存表示把已修改的文件放在下次提交时要保存的清单中

四 远程操作

远程仓库是指托管在因特网或其他网络中的你的项目的版本库。与他人协作涉及管理远程仓库以及根据需要推送或拉取数据。

1 本地分支

本地创建的master,dev等

2 跟踪分支

远程仓库的别名/分支名 存在于本地仓库

在git push ..远程仓库的别名 分支名 的时候,git会在本地帮助我们生成跟踪分支

3 远程分支

远程仓库的master,dev等

4 推送代码&拉取代码 (本地于远程没有建立跟踪关系)

推送:git push 远程仓库别名 分支名
拉取更新数据到跟踪分支:git fetch 远程仓库别名
本地分支合并跟踪分支获取更新: git merge 跟踪分支

5 建立本地分支与跟踪分支之间建立一对一的关系

① 在第一次往远程仓库推送分支的时候,可以建立关系

git push -u 远程仓库的别名 分支名

② 错过上述情况

git branch -u 跟踪分支

③ 克隆仓库

master分支自动跟踪

④ 克隆仓库

git checkout 分支名(必须存在对应的跟踪分支)

6 如何查看本地分支与跟踪分支之间的一对一对应

git branch -vv

7 克隆

git clone 远程仓库地址

8 删除远程分支

git push 远程别名 --delete 分支名

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

9 模拟项目经理

① 新建远程仓库

码云 github gitlab…

② 新建本地仓库
初始化仓库: git init
在master分支上 上传基本代码
基于master分支切出dev分支 上传一些需求等...
基于dev分支切出自己的个性化分支 进行需求开发
需求开发完成之后 切到dev分支合并自己的个性化分支....
切到dev,合并dev和个性化分支 :git merge 个性化分支    查看:git lol
③ 为远程仓库配别名
1. 查看别名 : git remote -v
2. 新增别名 : git remote add 别名 仓库地址
3. 删除别名 : git remote rm 别名
④ 将本地分支推送到远程
git push 远程仓库的别名 分支名 (不会建立跟踪关系)
git branch -u 跟踪分支(jd/dev) (重新建立本地与跟踪分支的一对一关系)
    等价于
git push -u 远程仓库的别名 分支名
git branch -vv:查询有没有关系
git remote -v:查看别名
⑤ 推送 拉取
git push
git pull

10 模拟组员

① 克隆远程仓库
git clone url :
    1. 将远程仓库的所有内容都下载到本地      git lol
    2. 在本地新建所有与远程对应的跟踪分支    git br -vv
    3. 默认建立master分支与其对应的跟踪分支之间的一对一关系
② 切换到dev分支
git checkout dev :
    1. 在本地新建dev分支
    2. 建立dev分支与其对应的跟踪分支之间的一对一关系
    3. 将远程dev分支的数据拉取到本地dev上
    4. 切换到dev分支
③ 业务开发
基于dev分支切出自己的个性化分支 进行需求开发
需求开发完成之后 切到dev分支合并自己的个性化分支....
④ 推送 拉取
git push
git pull(git fetch + git merge)
eg:git fetch jd:将远程更新拉取到跟踪分支 
   git merge jd/dev 合并跟踪分支
   git br -u jd/dev 关联dev关系   git branch -vv
⑤ 案例
先看看控制面板里的用户账户--凭据管理器有没有地址
先做主分支 提交,再做dev分支(新建文件dev.mk,提交)
在dev上创建分支wang分支 创建文件wang.html再次提交
切到dev,合并 git merge wang       git lol
配置:git remote add https://gitee.com/wangxiu216/jdong.git   git remote -v 
推送:git push jd master      git push jd dev
项目经理修改dev.md内容,再次提交,但是远程没有更新
git branch -vv:查询有没有关系      git push jd dev:需要指定分支  此操作是在本地上
在仓库里直接修改dev.md并提交 但是本地不知道 没有建立一对一关系
git  fetch jd将远程的更新拉取到跟踪分支上  git merge jd/dev合并即可看到更新的内容
git br -u jd/dev:关联dev关系    git branch -vv :有蓝颜色的跟踪分支
本地修改dev.md 提交 git st       git push :建立了跟踪关系,就可以直接push
远程修改 就可以直接git pull       将master也进行跟踪
克隆:git br -vv 主分支默认跟踪   切换 git co dev

五 pull request

  • 为第三方库做贡献

  • 公司项目遇到了很大的问题,团队问题解决不了,需要请外援

pr流程

① fork目标仓库

② 克隆frok完仓库 新建自己的个性化分支 进行修改并提交

③ 进行代码的合并 在dev上进行合并 git push 到远程

④ push代码 提pr

⑤ 目标仓库审核检验

⑥ 合并br

⑦ fork仓库使用fetch命令订阅目标仓库的更新

git remote add 别名 地址
git fetch 别名
git merge 跟踪分支
删除新建的个性化分支
再次新建分支进行业务开发

注意点:

每次在发起新的Pull Request时 要去拉取(git pull)最新的源仓库的代码 而不是自己fork的那个仓库。

六 tag

Git 可以给历史中的某一个提交打上标签,以示重要。 比较有代表性的是人们会使用这个功能来标记发布结点(v1.0 等) 也是一个提交对象,跟分支的本质一样

列出tag
git tag
创建轻量级tag:

轻量标签很像一个不会改变的分支 - 它只是一个特定提交的引用

git tag vx.y.z hash(可以默认)   X(库产生巨大的改变) Y(新增API)      Z(解决bug)
创建附注级tag:

附注标签是存储在 Git 数据库中的一个完整对象,可以被检验。

git tag -a vx.y.z
查看tag的明细
git show v.0.0     
检出tag
git br vx hash
git co -b vx
远程标签
git push 远程别名 vx.y.z
git push 远程别名 --tags   一次性推送很多标签
删除标签
git tag -d vx.y.z
git push origin :refs/tags/v1.4       更新远程仓库

七 忽略项目

https://www.toptal.com/developers/gitignore

https://github.com/github/gitignore

一般我们总会有些文件无需纳入 Git 的管理,也不希望它们总出现在未跟踪文件列表。通常都是些自动生成的文件,比如日志文件,或者编译过程中创建的临时文件等。我们可以创建一个名为 .gitignore 的文件,列出要忽略的文件模式。

你可能感兴趣的:(vue)