git
是开源的分布式版本控制系统,能够有效、高速地处理从很小到很是大的项目版本管理。咱们平时可能常用它,可是你真的了解 git 吗?先抛几个问题 git add
发生了什么?git 有哪些暂存区?git pull
与 git fetch
区别?git merge
与 git rebase
区别?git reset
与 get restore
区别?html
虽然,我一直在用 git ,像上面这些问题,我就不知道,因此将它们总结下。原文在我的博客git
开篇说了 git 是一个分布式的版本控制系统,那么什么是版本控制系统呢?能够参考 廖雪峰举的例子 Word 文档操做。微信
拿 Word
文档操做举例,当你想要 删除
某一段落的时候,又怕未来想要 恢复
找不到怎么办?你可能,会保存一个 副本
。接着再修改,再保存一个 副本
,这样一直持续,将会有好几个 副本
。分布式
过了一周,你想找到某一段,可能须要从这些 副本 中,一个一个查找,是否是很麻烦。工具
这仍是你一我的写 Word 的状况,假如,你的同事和你一块儿编辑这个 Word,为了保证文档同步,大家之间可能须要不停的相互发送传递(经过 U盘,或者 qq 微信 等方式)。总之,很繁琐。fetch
那假如说有这样一个软件,能够记录每次修改,并且还能够和多人共同编辑,是否是很方便。git 就是解决相似上面的问题,方便咱们查看每次修改内容,以及同步别人的修改等。动画
git clone
通常来讲,经过 git 来进行远程操做的第一步,是经过此命令从远程主机上克隆一个版本库git fecth
将某个远程主机的更新,所有取回本地git pull
取回远程主机某个分支的更新,再与本地的指定分支合并 smartgit pull 按钮有个下拉选项,能够选择: Merge fetched remote changes Rebase local branch onto fetched changesgit add
添加文件。细分来讲,应该是将工做区中的文件差别提交至暂存区。 至关于 smartgit
的 stage
git commit
提交文件。将暂存区中的修改,提交到本地分支。每次提交会产生一个 commit-id
,而且会带上你的 username email 等信息。git push
将本地分支的更新,推送到远程主机git marge
合并分之,多条线git rebase <name>
合并某分支到当前分之,变基 衍合,一条线git branch <name>
建立分支 git branch -d 删除分支git checkout
git checkout <name>
切换分支 git checkout -b <name>
建立 并 切换 分支。 git checkout -- <file>
放弃更改。(不加 -- 也能够放弃更改) 至关于 smartgit
的 unstage
git reset HEAD <file>
取消添加暂存区git switch <name>
切换分支,新版本提供的命令。 git switch -c <name>
建立并切换借一张图网站
工做区就是咱们 克隆 clone 一个项目,这个项目就是 工做区
;当执行 git add
时,会将改动添加到某个地方,这个地方就是暂存区
;本地仓库
,由 .git
目录管理;远程仓库
,就是拉取的地址。他们之间的关系以下面两张图所示:spa
HEAD
是 git
内部的一个指针,指向当前版本
。这个当前版本包含两个概念 分支
和 提交
。 HEAD
负责指向哪条 分支
,而 分支
指向某次具体 提交
。.net
默认状况
。
建立新分支
。Git建立一个分支很快,由于除了增长一个dev指针,改改HEAD的指向,工做区的文件都没有任何变化。从如今开始,对工做区的修改和提交就是针对dev分支了,好比新提交一次后,dev指针往前移动一步,而master指针不变。
合并分支
。首先切到 master ,而后 将 dev 合并到当前分支。就是直接把 master 指向 dev 的当前提交。git 很懒,这个提交方式 是由于 git 尝试采用 fast-forward
(—ff) 这类合并不会建立新的提交。
若是 master 上没有修改,这个时候状况就是这样的。若是 master 上修改,将会采用 No-fast-foward
(—no-ff),会建立一个 merge 提交。
删除分支
。开发完分以后,能够视状况将其删除。删除dev分支就是把dev指针给删掉
动画演示
以下:
git pull
与 git fetch
均可以从远程仓库中拉取最新代码。不一样之处在于更新的方式不一样。
git fetch
方式,是将远程主机的最新内容拉到本地,用户在检查了之后决定是否合并到工做本机分支中。最新的更新记录会保存在 .git/FETCH_HEAD
文件中。
git pull
则是将远程主机的最新内容拉下来后直接合并,这样可能会产生冲突,须要手动解决。git pull
= git fetch
+git merge
。
注意,不必定是 git merge
也能够选择 git rebase
,好比,我用的 smartgit:
git merge
与 git rebase
都是用来合并分之的。不一样之处,在于生成的 log 分叉线不一样。
git merge
会把公共分支和你当前的commit 合并在一块儿,造成一个新的 commit 提交。
git rebase
会把你当前分支的 commit 放到公共分支的最后面,因此叫变基。就好像你从公共分支又从新拉出来这个分支同样。
假设,你有以下分支记录,
假设在 master 分支上的新提交与你正在开发的 feature 相关。须要将新提交合并到你的 feature 分支中,你能够有两个选择:merge
或者 rebase
。
git checkout feature
git merge master
# 或者一条命令。前提是你得在 feature 分支上
git merge feature master
复制代码
如上图所示,这会在 feature 分支中建立一个新的 merge commit,它将两个分支的历史联系在一块儿。
使用 merge
是很好的方式,由于它是一种 非破坏性的
操做。现有分支不会以任何方式被更改。这避免了 rebase
操做所产生的潜在缺陷。
缺点是会产生一个额外的提交。
git checkout feature
git rebase master
复制代码
如上图所示,这会将整个 feature
分支移动到 master
分支的顶端,从而有效地整合了全部 master
分支上的提交。可是,与 merge
提交方式不一样,rebase
经过为原始分支中的每一个提交建立全新的 commits
来 重写
项目历史记录。
rebase 的主要好处是能够得到更清晰的项目历史。
git rebase
的黄金法则是 永远不要在公共分支上使用它
。
什么是 公共分支呢。个人理解是想 master
dev
test
这样的分之,或者说是有两我的以上使用的分支,就叫公共分支。
你 rebase master 分支到 feature 分支之上会发生什么:
git reset
与 get revert
均可用于版本回退,区别在于,一个能够硬重置,不保留记录;一个是覆盖式提交,保留记录。
先假设咱们有这样的分支:
git reset
分为 软重置
(git reset --soft <commit id>) 和 硬重置
(git reset --head <commit id>)。默认为 软重置,通常在回滚代码的时候,咱们用的是 硬重置
git reset --hard <commit id>
git push -f
复制代码
git revert
还原,经过对特定的提交执行还原操做,咱们会建立一个包含已还原修改的新提交
发现一个很好的了解Git 基本概念和操做的工具,Git Online 。这个网站经过一个个任务让你了解 git,若是不想作题,能够直接加参数 NODEMO Git Online 沙盒模式,来在线验证。
若是,还想经过动图的方式,直观的了解 git 命令是如何工做了,可参考我转载的这篇文章 CS可视化:有用的Git命令