git 是一个免费开源的分布式版本控制系统(DVCS),是一个基于内容寻址的存储系统
优势:快;完全的分布式;轻量级的分支操作;git 已经成为现实意义上的标准;社区成熟活跃
help
git help
git
fot
帮我们列出某个命令的帮助文档
基本操作
git config —— 配置 git
用户配置:
git config --global user.name "hyt"
git config --global user.email [email protected]
配置级别:
--local(默认,最高级别):只影响本仓库
--global(中优先级):影响到所有当前用户的 git 仓库
--system(低优先级):影响到全系统的 git 仓库
.git 文件夹非常重要,几乎记录了所有我们提交的信息,以及一些引用关系,包括 config 文件
git status —— 对状态的跟踪
git 中有内容状态和文件状态
内容状态主要标识着文件内容的改变,分三个区域:工作目录,暂存区,提交区
文件状态:未跟踪,已跟踪
git add —— 添加文件内容到暂存区(同时文件被跟踪)
有多个文件需要跟踪时,可以通过 git add . 添加所有当前目录的文件
忽略文件 .gitignore
在添加时忽略匹配的文件,仅用于未追踪的文件
当我们通过 git add 进行添加时,做了一层过滤,把所有 gitignore 中列的文件类型都进行了删除
git rm —— 删除文件
git rm --cached:仅从暂存区删除
git rm:从暂存区与工作目录删除
git rm $(git ls -file --delete):删除所有被跟踪,但是在工作目录被删除的文件
ls -file 帮助我们到暂存区查找相关文件,它列出了所有被删除的文件,同时这些文件会作为参数传入 rm 命令,删除所有在工作目录下删除的文件
暂存区
把暂存区想象成一个购物车,每类物品只能放置一次。
货架和购物车可以出现同种物品,货架上的物品可以替换掉购物车的物品,可以删除物品。
提交购物车完成购买,生成购买记录。
物品:文件 货架:工作目录 购物车:暂存区 购买:提交内容
git commit —— 根据暂存区内容创建一个提交记录
git commit -m 'initial commit' 暂存区中内容被提交,工作目录上内容还存在,形成提交历史
git commit -a -m 'full commit' 直接提交,形成工作目录
git log —— 显示提交历史信息
输出内容:SHA-1编码的 HASH 标识符,git config 配置的提交者信息,日期
git log --oneline 只输出部分 HASH 值
git 中别名的设置
git config alias.shortname
可设置成 global 级别,每个仓库都能使用
git diff —— 显示不同版本的差异
git diff :工作目录与暂存区的差异
git diff -cached [
git diff
除此之外我们也可以查看两次提交之间的变化关系,传入两个 Commit ID 即可
git checkout --
将文件内容从暂存区复制到工作目录
git reset HEAD
将文件内容从上次提交复制到暂存区
git checkout HEAD --
将内容从上次提交复制到工作目录
2.分支操作
分支模型是基于一系列分支操作进行的,分支操作概念主要是围绕提交历史展开的。
git branch —— 分支的增删查改
git branch
git branch -d
git branch -v:显示所有的分支信息
提交历史是跟不断向前的线,当时使用 commit 命令创建提交对象时,会有一个引用指向前一个提交;默认创建master分支(当前所在分支)和HEAD会指向当前最新的提交。
git branch next 在HEAD所指的 commit 对象上创建另外一个引用,这时 git commit 提交,创建一个提交对象,master分支和HEAD会随之向前,next仅创建,不切换
git 分支轻量级的秘密:一个分支的引用只是一个文本文件,只有一个 40 字符长的 SHA-1 编码,所有分支在 .git/refs/heads 目录下
git checkout —— 通过移动 HEAD 检出版本,可用于分支切换
git checkout 本质上只是用来移动 HEAD,相当于检出版本,因为 HEAD 指向当前提交,同时也会把当前的工作目录和暂存区恢复到你移动到的那个版本,相当于分支切换。
git checkout
git checkout -b
git checkout
传入 commit ID 时,导致 HEAD 与具体分支分离,一般不进行写操作只读取内容
git checkout -:恢复到上一个分支
git reset —— 当前分支回退到历史某个版本
git reset --mixed
git reset --hard
git reset --soft
git reflog —— 按之前经过的所有 commit 路径按序排
可以使用输出的 HASH 值进行重新回退到这个版本,或进行其它的操作,这个命令要尽快
使用捷径:
A^:A 上的父提交(前一个提交)
A~n:在 A 之前的第 n 次提交
有多种方式回退到我们需要的版本
reset vs checkout
在基本操作和分支操作都出现了 reset
reset 和 checkout 同时有两个作用范围,一种作用范围是 commit 操作(分支命令),一种是 file 操作。
当 reset 和 checkout 分别作用于 commit 和 file 操作时,他们相当于完全不同的操作
git stash —— 保存目前的工作目录和暂存区状态
git stash save 'push to stash area':save 后传入信息标识指令,方便查找
stash 相当于一个栈,可通过 list 子命令查看收藏了多少条记录
git stash apply stash@{0}:让保存的内容重新恢复到工作目录上
git stash drop stash@{0}:将对应的 stash 记录删除
stash pop = stash apply + stash drop 最顶端记录 pop 出来完成丢弃操作
git merge —— 合并分支
git merge next :将 next 分支合并到 master 分支,因为当前在 master 分支省略第二个参数
这是个三方合并,发生在三个节点上,两个分支节点及他们的共同祖先,合并的结果被复制到工作目录以及暂存区,然后完成一次提交,提交节点的父指向会有两根,指向 master 和 next
git cat-file -p HEAD
cat-file 帮助我们显示某个 git 里的具体对象的信息
由于操作在 master 分支上发生,next 分支引用并没有发生变化,master 和 HEAD 向前移动了一位,指向最新的提交
解决 merge 冲突
合并分支时会发生合并冲突,会提示哪个文件发生了冲突,发生在哪里
文件中的冲突,由两个箭头序列和一个等号序列分隔而成,需要将冲突文件编辑到我们需要的样子,比如说同时使用了两次提交的部分内容
最后用 git add . 和 git commit -m 'resolve' 完成冲突的解决
merge fast-forward
假设从 master 分支创建了next,master分支并未向前移动,仅在next分支上做操作
git merge next 仅将 master 分支指向 next 分支所在位置,提交历史变得线性
如果想要合并在哪个节点, git merge next --on-off ,不使用 fast-forward 方式进行分支合并
merge 的不足:当参与的人数越多,分支越多,它产生的结构也就越来越难以理解
git rebase —— 修剪历史基线,俗称“变基”
当 HEAD,feature 指向节点与 master 不同,git rebase master 找到三个提交节点,两个分支节点以及它们共同的祖先节点,git 还会找到共同节点与分支节点之间的提交记录,让这份提交在 master 分支上进行重演(而不是复制),commit ID 变化,HEAD 和 feature 指针指向最新的这次提交
git rebase --onto
有一种情况,我们其实并不是需要把所有的提交都进行在 master 分支上的重演,我们可以挑选需要重演的节点到 master 分支上,相当于挑选的节点已被丢弃
rebase vs merge
rebase 获得线性的提交记录
merge 会有合并记录,可以看到在哪个点合并
勿在共有分支使用 rebase
git tag —— 对某个提交设置一个不变的别名
比如某个发布之后,要设置一个别名
git tag v0.1 e39d0b2:可直接使用标签进行 checkout 等操作,不需要输入冗长的 HASH
3.远程操作
如何将我们本地的记录,同步到中央服务器,以便可以让其他开发者看到。
git 支持本地协议,可以初始化一个本地远程服务器
git init ~/git-server --bare
传入 bare 参数,将当前这仓库初始化为一个裸仓库(无工作目录)
中央服务器不需要工作目录,中央服务器是为了同步你和队友之间的分支操作
git push 提交本地历史到远程
直接将本地消息推送到中央仓库的 master 分支,其实是一个提交历史的复制
git remote 远程仓库相关配置操作
git remote add origin ~/git server:添加一个远程仓库别名
git remove -v:查看远程仓库信息
这个配置写在 config 文件里面,一般会把默认的远程分支名字取为 origin
push 冲突
当多人协同操作的时候,push 会冲突,一个祖先节点下衍生两个提交节点,这种情况下,git 会阻止提交,告诉你需要先获取远程的变动
git fetch 获取远程仓库的提交历史
git fetch + merge 解决冲突
git fetch origin master 获取远程仓库的更新,origin/master 被同步
git merge origin/master 完成三方合并,完成新的提交
git push origin master 将本地历史复制到服务器端
git pull = git fetch + git merge
git clone 克隆一个远程仓库作为本地仓库
git clone ~/git -server test2:把仓库克隆到 test2 目录下