git是分布式版本控制系统。
- 版本控制系统:
- 集群式版本控制(CSV / SVN):增量
- 分布式版本控制(Git):全量(每一个版本都包含全部文件,数据在任何版本都完整)
- git优势
- 本地版本控制
- 重写提交声明
- git管理下的文件的状态
- 未跟踪
- 已跟踪:已经add过的
- 已修改(modified)
- 已暂存(staged)
- 已提交(commited)
加密算法
- shal:目的产生随机数。区分哪一次提交(并且不重复)
- md5
- 区域
- 工作区
- 暂存区
- 版本库
- 对象
- Git 对象
- 树对象
- 提交对象
一、Git 底层概念(底层命令)
(一)基础的linux命令
clear
:清屏echo 'test content'
:往控制台输出信息ll
:将当前目录下的子目录&子文件平铺在控制台find 目录名
:将对应目录下的子孙文件&子孙目录平铺在控制台。find 目录名 -type f
:将对应目录下的子孙文件平铺在控制台。rm 文件名
:删除文件mv 源文件 重命名文件
:重命名cat 文件的url
:查看对应文件的内容vim 文件的url
(在英文模式下)- 按 i 进插入模式,进行文本编辑
- 按 esc 键:退出文本编辑模式
- 按冒号
:
键:进行命令的执行:q!
:强制退出不保存:wq
:保存并退出set nu
:设置行号
(二).git目录
- .git文件里的东西
- hooks:目录包含客户端或服务端的钩子脚本。
- info:包含一个全局性排除文件
- logs:保存日志信息
- objects:目录存储所有数据内容
- refs:目录存储指向数据的提交对象的指针(分支)
- config:文件包含项目特有的配置选择
- description:用来显示对仓库的描述信息
- HEAD:文件指示目前被检出的分支
- index:文件保存暂存区信息。
(三)git对象
- Git的核心技术是一个简单的键值对数据库。你可以向该数据库插入任意类型的内容。它会返回一个键值,通过该键值可以在任意时刻再次检索改内容。
- git 对象:
key:value
组成的键值对(key是value对应的hash)- 键值对在git内部是一个blob类型
- 代表文件的一次次版本。
- 存在问题:
- 记住文件的每一个版本的 sha-1哈希值,不现实
- 在Git中,文件名没有被保存而是保存了文件内容。(解决方法:树对象)
- 注意:当前操作都不涉及暂存区。只涉及本地区和版本区
向数据库写入内容,并返回对应键值
- 命令:
echo 'test content' | git hash-object -w --stdin
-w
选项,指示hash-object
命令存储数据对象。若不指定此选项,则该命令仅返回对应的键值。--stdin
选项(standard input),指示该命令从标准输入读取内容。若不指定此选项,则须在命令尾部给出待存储文件路径。git hash-object -w 文件路径
:存文件git hash-object 文件路径
:返回对应文件的键值。如下ce013625030ba8dba906f756967f9e9ca394464a
- 返回的键值:该命令输出一个长度为40个字符的校验和。这是一个sha-1哈希值
补充
- 一竖杠
|
是两条命令的分隔。 - sha-1哈希值是键,文件内容是值。
根据键值拉取数据
- 命令:
git cat-file -p ce013625030ba8dba906f756967f9e9ca394464a
-p
选项,可指示该命令自动判断内容的类型,并为我们显示格式友好的内容。返回:对应文件内容。-t
选项,可指示该命令为我显示文件类型。返回:git类型(blob,tree,commit)。
(四)树对象
- 树对象:解决文件名保存问题,允许我们将多个文件组织到一起。
- 代表项目的一次次版本。
- 可以认为树对象就是我们项目的快照。
- 查看暂存区:
git ls-files -s
构建树对象
- 我们可以通过
update-index;
write-tree;
read-tree
等命令构建树对象,并塞到暂存区。
小测试
- 1.利用update-index命令,为test.txt文件的首个版本,创建一个暂存区。并通过write-tree命令生成树对象。
- 命令:
a)git update-index --add --cacheinfo 100644\ce013625030ba8dba906f756967f9e9ca394464a test.txt
b)git write-tree
- 文件模式:
100644
表明这是一个普通文件。100755
表示一个可执行文件。120000
表示一个符号链接。
--add
选项:把文件添加到暂存区。--cacheinfo
选项:因为将要添加的文件位于git数据库中,而不是位于当前目录下。
- 文件模式:
- 命令:
- 2.新增new.txt。将new.txt和test.txt文件的第二个版本塞入暂存区。并通过write-tree命令生成树对象
- 命令:
a)echo 'a new file' > new.txt
b)git update-index -cacheinfo 100644\38748dc9f68597a98e4c4d0162078bc783b16226 test.txt
第二个版本。同名则覆盖。
c)git update-index --add --cacheinfo e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 new.txt
d)git write-tree
- 命令:
到目前有五个对象,五个哈希值。两个树对象,三个git对象。
- 3.将第一个树对象加入第二个树对象,使其成为新的树对象。
- 命令:
a)git read-tree --prefix=bak 620ffd0fd9579a46e46ef4505b198ee0a01a57f2
第一个树对象的哈希值
b)git write-tree
- git read-tree:把树对象读入暂存区。
- 命令:
查看树对象
- 命令:
git cat-file -p 620ffd0fd9579a46e46ef4505b198ee0a01a57f2
用树对象的哈希值
解析树对象
(五)提交对象
- 提交对象:通过调用commit-tree命令创建一个提交对象,为此需要指定一个树对象的sha-1值,以及该提交的父提交对象(第一次将暂存区做快照没有父对象)
- 可以形成链式结构。
创建提交对象
- 第一次创建提交对象命令:
echo 'first commit' | git commit-tree 620ffd0fd9579a46e46ef4505b198ee0a01a57f2
- 返回一个哈希值,代表commit对象
- 继续创建提交对象命令:
echo 'second commit' | git commit-tree 第一棵树对象哈希值 -p 第二棵树对象的哈希值
查看提交对象
- 命令:
git cat-file -p commit对象的哈希值
- 返回:
tree tree对象的哈希值
author 名称 邮箱 时间戳
committer 名称 邮箱 时间戳
提交说明
- 返回:
二、git 的高层命令(CRUD)
git -version
:安装git init
:创建git本地版本库rm -rf .git
:删版本库,并且删掉里面的子目录。git status
:查看文件状态。
(一)设置邮箱和用户名
git config
- 1.
git config --system
:基本不用。给当前计算机一次性设置~
.gitconfig
- 2.
git config --global
:推荐,给当前用户一次性设置 - 3.
git config --local
:给当前项目一次性设置.git
/config
git config --local user.name 'konsoue'
:设置用户名git config --local --unset user.name
:删除用户名
- 地址越精确,优先级越高。3>2>1
- 1.
(二)配别名
- 可以通过git config命令来未每一个命令配置一个别名。
git config --global alias.别名 "原名"
git config --global alias.lol "log --oneline --decorate --graph --all"
这样以后使用就这样用git lol
(三)文件操作
增
touch a.txt
:在工作区新建a.txt文件git add hello.txt
:添加hello.txt到暂存区git add .
:把工作区所有文件添加到暂存区。
git rm test.txt
:在工作区删除test.txt文件,并add到暂存区。git rm --cached hello.txt
:把暂存区的hello.txt退回工作区
git commit
:把暂存区的文件提交到对象区。git commit -m "第一次提交"
:提交说明少,可以这么写
删
git checkout -- hello.txt
或者git restore hello.txt
:撤回上一次修改,还原到已提交状态。git reset HEAD hello.txt
或者git restore --staged hello.txt
:把刚提交到暂存区的hello.txt文件删回工作区。git rm hello.txt
:把版本库的hello.txt删回暂存区。(现在可以删回工作区或者再提交一次。)
查
rd 文件夹
:进入某个文件夹查看ls
:查看当前文件夹的所有文件cat
:查看文本文件内容。git log
:查看本分支提交日志git log -2
:最近提交的两次记录git log --pretty=oneline
:提交对象哈希值和提交说明放在同一个区域。git log --pretty=format:"%h - %an ,%ar : %s"
:显示shal函数前一部分,%an用户名,%ar提交世界,%s提交说明git log --oneline --decorate --graph --all
:查看所有分支的提交日志。
git reflog
:记录着HEAD的所有移动。git diff
:查看当前更新未暂存git diff --cached
或者git diff --staged
: 查看更新且已暂存,未提交的文件。
git cat-file -p 暂存区文件哈希值
:查看暂存区文件内容git config
:config配置的意思git config --list
:查看仓库级、全局级、系统级配置文件git config --edit
:编辑.git文件里的config文件
改
vi hello.txt
:把对象区的hello.txt提回工作区,让你修改。要重新提交。echo 'world' > hello.txt
:把hello.txt内容写改为worldgit mv 原文件名 重命名文件名
:给工作区的文件重命名,且add到暂存区里。
(四)git 本地分支操作
- 分支的本质:其实就是一个指向提交对象的可变指针.
- HEAD 是一个指针,它默认指向 master 分支,切换分支就是让 HEAD 指向不同的分支。
- 像是一只领头羊(往前走的是它),带着master或者其他分支往前走。
- 命令:
git branch
显示分支列表
创建&删除分支
- 创建分支命令:
git branch 分支名
作用:这会在当前所在的提交对象上创建一个可移动的新指针。git branch 分支名 commitHash
作用:新建一个分支并使这个分支指向对应的提交对象。
- 删除分支命令:
git branch -d 分支名
。合并后用小d- 未合并强制删除用大D
git branch -D 分支名
- 未合并强制删除用大D
版本穿梭:建个分支给之前的提交对象。回去查看一波
切换分支
- 命令:
git checkout 分支名
- 切换三个地方:把HEAD、工作区、暂存区切换到分支所在版本。
- 最佳实践:每次切换分支前,保证当前分支一定是干净的(已提交状态)
- 注意:
- 在切换分支时,如果当前分支上有未暂存的修改(第一次)或者 有
未提交的暂存。分支可以切换成功,但是可能污染其他分支。
- 在切换分支时,如果当前分支上有未暂存的修改(第一次)或者 有
合并分支
- 快进合并(fast forward):a分支落后于b分支时,在a分支用命令
git merge b分支名
就会把a分支快进到和b分支同步。这样a分支就合并了b分支的版本。 - 典型合并:
- (1)两个分支并排时
- (2)是快进合并,但是强制不快进
git merge --no--ff 分支名
- 冲突:如果你在两个不同的分支中,对同一个文件的同一个部分进行了不同的修改,Git 就没法干净的合并它们,这时就产生冲突。
- 查看冲突:
git status
- 解决冲突:
vim 有冲突的文件
修改冲突,然后git add .
表明冲突已修改,git commit -m ''
提交
- 查看冲突:
分支模式
- 长期分支
- 特性分支
(五)git 栈存储
- 想从b分支切到a分支,但是b分支的工作已经提交过version1,但是修改成version 2,但还不想提交,可以先放到栈里。(栈里面一般放一两个)
- 命令:
git stash
:把修改后的文件,放到栈里。git stash list
:查看栈有啥东西。git stash apply stash@{n}
:应用栈的储存,但没有删除。没写指定的储存,默认栈顶。git stash drop 栈顶(stash@{n}
:删除栈的储存。没写指定储存,默认栈顶git stash pop
:应用栈顶的储存,而且删除。
(六)git撤回&重置
git撤回(后悔药)
- 所谓撤回,只是视觉效果的撤回。
- 工作区:撤回在工作区已跟踪的文件的修改。
- 命令:
git checkout -- test.txt
或者git restore test.txt
- 命令:
- 暂存区:撤回暂存区的文件修改。
- 命令:
git reset HEAD test.txt
或git restore --staged test.txt
- 命令:
- 版本库:撤回版本库的文件修改。
- 命令:
git commit --amend
- 原理:把暂存区的数据重新提交并且重新注释。
是不是调用了git reset --soft HEAD~
和git commit
- 命令:
git重置(reset):版本穿梭
- reset三部曲
- 移动HEAD
- 命令:
git reset --soft HEAD~
- 作用:移动HEAD和HEAD所对应的分支。
git checkout
是移动HEAD而已。~是回到HEAD的父节点,可以换成提交对象的哈希值。
- 命令:
- 更新暂存区(索引)
- 命令:
git reset HEAD~
或git reset --mixed HEAD~
- 作用:移动HEAD和HEAD所对应的分支,且把暂存区更新到HEAD父节点的版本。
- 特有命令:
git reset [--mixed] HEAD~ filename
- 最后加上一个文件名,只回退这个文件。HEAD和其对应分支不移动
- 命令:
- 更新工作区
- 命令:
git reset --hard HEAD
- 作用:移动HEAD和HEAD所对应的分支,且把暂存区、工作区更新到HEAD父节点的版本。
- 存在风险:把工作区未跟踪的文件抹掉。
- 命令:
- 移动HEAD
- 利用
git reflog
命令找到原来的节点的哈希值,在那里创建个分支,然后切回去。
(七)打tag(标签)
- Git可以给历史中的某一提交打上tag,以示重要。比如这个软件第几个版本了。
- tag标签,就像个不会动的分支。
- 命令:
git tag
:列出标签名
创建标签
- git使用两种类型标签:轻量标签 与 附注标签
- 命令:
git tag v1.0 (提交对象的哈希值)
- 这样就打了个tag交v1.0
- 切回某个tag的版本,命令:
git checkout tagName
- 头部分离:切回去的版本没有分支,不能修改。得加一个分支。
查看特定标签
- 命令:
git show tagName
- 显示该标签所在版本的内容。
删除tag
- 命令:
git tag -d tagname
三、远程仓库
- 远程仓库是指托管在因特网或其他网络中的你的项目的版本库。
(一)三种分支
- 分支
- 远程分支:在github仓库的分支
- 它们以
远程库别名/远程分支名
形式命名。 - 远程引用:对远程仓库的引用(指针),包括分支、标签等。
- 查看远程引用完整列表:
git ls-remote 远程库别名
- 更多远程分支的信息:
git remote show 远程库别名
- 它们以
- 远程跟踪分支(跟踪分支):就是本地分支 跟踪 远程分支
- 创建命令:
git checkout -b 新建本地分支名 远程分支
- 远程跟踪分支是远程分支状态的引用。 它们是你不能移动的本地引用,当你做任何网络通信操作(fetch、push、pull)时,它们会自动移动。
- 远程跟踪分支像是你上次连接到远程仓库时,那些分支所处状态的书签。
- 例如,如果你想要看你最后一次与远程仓库 origin 通信时 master 分支的状态,你可以查看 origin/master 分支。
- 创建命令:
- 本地分支
- 远程分支:在github仓库的分支
(二)远程协作基本流程
- 项目经理创建远程仓库(github)
(1)在github初始化一个空的仓库 - 项目经理创建本地仓库
- 项目经理为远程库配置别名&用户信息
(1)命令:git remote add 远程库别名 url
添加一个新的远程Git仓库,同时指定一个你喜欢的远程库别名(remoteName)
(2)命令:git remote -v
显示远程仓库使用的Git别名与其对应的url
(3)命令:git config --local user.name 'yourName'
配置用户信息。(用户名,用户邮箱)
(4) - 项目经理推送本地项目到远程仓库
(1)清理windows凭据
(2)命令:git push 远程库别名 本地分支
输入用户名 密码后会附带生成远程跟踪分支 - 成员克隆远程仓库到本地
(1)命令:git clone url
(克隆不需要git init)
在本地生成.git文件,默认给远程仓库配个别名origin。 - 项目经理邀请成员进入团队
在github上操作 - 成员推送提交到远程仓库
(1)修改源码文件,提交到本地库
(2)git push 远程仓库别名 本地分支
输入用户名 密码,自动生成远程跟踪分支 - 项目经理更新成员提交内容
(1)命令:git fetch remoteName
四、github
一、基本概念
- 仓库 (Repository)
- 用来存放项目代码,每个项目对应一个仓库,多个开源项目则有多个仓库。
- 收藏 (Star)
- 收藏项目,方便查看。
- 复制克隆项目 (Fork)
- 复制别人仓库里的开源项目,自己新建个仓库放它。(本质上是在原有项目上新建分支),随便改,因为是备份,不会影响原有的代码与结构。
- 发起请求 (Pull Request)
- 基于 fork。改了别人的代码,觉得有用,想把改进合并到原有项目里。这时发送 pull request (PR) 请求,原有项目创建人 review 完,觉得 Ok,就接受你的 RP。
- 关注(watch)
- 关注某个项目后, 当项目有更新,通知你。
- 事务卡片(lssue)
- 发现代码 bug,但目前没有成型代码,需要讨论时用。
- Github主页
- 仓库主页
- 个人主页