一 版本控制

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

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对应的hashgit 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-treegit 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 分支名对应的提交对象 filepathgit checkout -- filepath 相当于 git reset --hard HEAD filepathgit 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 lol2. 在本地新建所有与远程对应的跟踪分支    git br -vv3. 默认建立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 的文件,列出要忽略的文件模式。

git-底层-高层指令相关推荐

  1. 一文讲透 Git 底层数据结构和原理

    简介: 本文将系统分享 Git 底层知识:对象生命周期变化,底层数据结构,数据包文件结构,数据包文件索引,以及详细分析对象查询流程和算法. 状态模型 上图描述了 git 对象的在不同的生命周期中不同的 ...

  2. Git简单基本操作指令集合

    Git简单基本操作指令集合 常用置顶 新添加到暂存区中文件前面有绿色的 A 标记 (这是精简的方式查询出来的状态 git status -s), 非精简方式查询出来的是 文件名全绿色的 修改过的.没有 ...

  3. GIT的PUSH指令

    ### GIT的PUSH指令 ``` $ git push <远程主机名> <本地分支名>:<远程分支名> ``` * `git push`命令用于将本地分支的更新 ...

  4. SCM工具-Git的相关指令

    这学期的软件构造课程,一点收获就是学习了Git的使用,作为SCM的一个工具,git在版本控制与软件配置管理上起到很大的作用. 在使用git前我们需要掌握一些概念. Git相关概念 1. 一个本地的Gi ...

  5. 浅谈 git 底层工作原理

    浅谈 git 底层工作原理 系统复习到这里也快差不多了,大概就剩下两三个 sections,这里学习一下 git 的 hashing 和对象. 当然,跳过问题也不大. config 文件 这里还是会用 ...

  6. 常用的Git命令行指令以及图形化界面的简单操作

    命令行操作 常用指令 指令 作用 指令 作用 cd 打开目录 pwd 绝对路径 ls 列出清单 mkdir 新建目录 cp 拷贝 mv 移动 rm 移除 touch 创建文档 一.git版本管理的指令 ...

  7. Git 底层数据存储结构与工作原理介绍

    前言 通过对 Git 底层 API 的使用来了解其存储结构与工作原理,通过了解工作原理可以帮助我们更好地解决各类 Git 代码版本管理操作上的问题. 介绍 Git 是一个内容寻址(content-ad ...

  8. git 相关文件指令随笔

    1.若commit 且push后,发现文件存在问题,可如下操作: (1)本地修改对应文件至OK,然后, git add filename git commit --amend git push ... ...

  9. git 强制更新远程_版本控制管理工具git的常见指令合集

    今天小千就来给大家介绍一下git中比较常见的指令合集,方便大家使用git,建议收藏起来方便日后查阅. 一.常见的命令 git help <command> # 显示command的help ...

最新文章

  1. 齐鲁工业大学计算机读研,齐鲁工业大学考研难吗
  2. Linux套接字与虚拟文件系统
  3. Windows下Caffe的学习与应用(二)——优化自己训练的模型(fine-tuning)
  4. 不用去验血,对照这张表,就能知道自己缺啥!千万收藏好!
  5. C++实现各种选择排序(简单选择排序,堆排序)
  6. Angular 5.0 学习2:Angular 5.0 开发环境的搭建和新建第一个ng5项目
  7. 1660用哪个驱动稳定_PDF转word怎么转?哪个PDF转换器最好用?-PDF ——快科技(驱动之家旗下媒体)-...
  8. java诺基亚nba,HMD 签约NBA 新秀劳里·马尔卡宁 为诺基亚手机品牌大使
  9. python 字符串替换多个_python同时替换多个字符串方法示例
  10. JZOJ 3457. 【NOIP2013模拟联考3】沙耶的玩偶(doll)
  11. mysql 时间类型转化_Mysql 字段类型转化 和 时间类型相关处理
  12. 【Tensorflow】相关面试题整理(转)
  13. C# async/await 使用总结
  14. 【PID优化】基于matlab天牛须算法PID控制器优化设计【含Matlab源码 1312期】
  15. 移远ec20型号区别_移远的EC20 4G模块
  16. 标签打印软件中Excel数据整理及导入
  17. 深度学习开源数据集整理
  18. OpenCV:计算三角形的角度
  19. 股票和外汇究竟哪个更存在风险呢?
  20. Simpson积分应用

热门文章

  1. python设置excel自动换行_python 操作Excel 设置格式
  2. Mysql配置文件读取顺序
  3. floatmap 二维数组_Golang学习笔记(四):array、slice、map
  4. mysql配置命令_MySQL基本配置命令总结
  5. linux实现字符火焰动画,linux flamegraph火焰图使用
  6. 微信小程序中处理 获取用户地址的回调
  7. mac下ssh免密登陆远程服务器(linux)
  8. Day 20:网络编程(1)
  9. Vue2.0 的漫长学习ing-2-6
  10. Linux - 有效群组(effective group)与初始群组(initial group),groups,newgrp