我把git想简单了

git 是开源的分布式版本控制系统,能够有效、高速地处理从很小到很是大的项目版本管理。咱们平时可能常用它,可是你真的了解 git 吗?先抛几个问题 git add 发生了什么?git 有哪些暂存区?git pullgit fetch 区别?git mergegit rebase 区别?git resetget 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 changes
  • git add 添加文件。细分来讲,应该是将工做区中的文件差别提交至暂存区。 至关于 smartgitstage
  • 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> 放弃更改。(不加 -- 也能够放弃更改) 至关于 smartgitunstage
  • git reset HEAD <file> 取消添加暂存区
  • git switch <name> 切换分支,新版本提供的命令。 git switch -c <name> 建立并切换

借一张图网站

工做区,暂存区,本地仓库,远程仓库

工做区就是咱们 克隆 clone 一个项目,这个项目就是 工做区;当执行 git add 时,会将改动添加到某个地方,这个地方就是暂存区本地仓库,由 .git 目录管理;远程仓库,就是拉取的地址。他们之间的关系以下面两张图所示:spa

HEAD

HEADgit 内部的一个指针,指向当前版本。这个当前版本包含两个概念 分支提交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 pullgit fetch 均可以从远程仓库中拉取最新代码。不一样之处在于更新的方式不一样。

git fetch

git fetch 方式,是将远程主机的最新内容拉到本地,用户在检查了之后决定是否合并到工做本机分支中。最新的更新记录会保存在 .git/FETCH_HEAD 文件中。

git pull

git pull 则是将远程主机的最新内容拉下来后直接合并,这样可能会产生冲突,须要手动解决。git pull = git fetch +git merge

注意,不必定是 git merge 也能够选择 git rebase,好比,我用的 smartgit:

git merge 与 git rebase

git mergegit rebase 都是用来合并分之的。不一样之处,在于生成的 log 分叉线不一样。

git merge 会把公共分支和你当前的commit 合并在一块儿,造成一个新的 commit 提交。

git rebase 会把你当前分支的 commit 放到公共分支的最后面,因此叫变基。就好像你从公共分支又从新拉出来这个分支同样。

假设,你有以下分支记录,

假设在 master 分支上的新提交与你正在开发的 feature 相关。须要将新提交合并到你的 feature 分支中,你能够有两个选择:merge 或者 rebase

git merge 方式

git checkout feature
git merge master

# 或者一条命令。前提是你得在 feature 分支上
git merge feature master 
复制代码

如上图所示,这会在 feature 分支中建立一个新的 merge commit,它将两个分支的历史联系在一块儿。

使用 merge 是很好的方式,由于它是一种 非破坏性的 操做。现有分支不会以任何方式被更改。这避免了 rebase 操做所产生的潜在缺陷。

缺点是会产生一个额外的提交。

git rebase 方式

git checkout feature
git rebase master
复制代码

如上图所示,这会将整个 feature 分支移动到 master 分支的顶端,从而有效地整合了全部 master 分支上的提交。可是,与 merge 提交方式不一样,rebase 经过为原始分支中的每一个提交建立全新的 commits重写 项目历史记录。

rebase 的主要好处是能够得到更清晰的项目历史。

git rebase 黄金法则

git rebase 的黄金法则是 永远不要在公共分支上使用它

什么是 公共分支呢。个人理解是想 master dev test 这样的分之,或者说是有两我的以上使用的分支,就叫公共分支。

你 rebase master 分支到 feature 分支之上会发生什么:

git reset 与 get revert

git resetget revert 均可用于版本回退,区别在于,一个能够硬重置,不保留记录;一个是覆盖式提交,保留记录。

先假设咱们有这样的分支:

git reset

git reset 分为 软重置(git reset --soft <commit id>) 和 硬重置(git reset --head <commit id>)。默认为 软重置,通常在回滚代码的时候,咱们用的是 硬重置

git reset --hard <commit id>
git push -f
复制代码

git revert

git revert 还原,经过对特定的提交执行还原操做,咱们会建立一个包含已还原修改的新提交

git 练习

发现一个很好的了解Git 基本概念和操做的工具,Git Online 。这个网站经过一个个任务让你了解 git,若是不想作题,能够直接加参数 NODEMO Git Online 沙盒模式,来在线验证。

若是,还想经过动图的方式,直观的了解 git 命令是如何工做了,可参考我转载的这篇文章 CS可视化:有用的Git命令

参考连接

Git 教程

一个小时学会Git

git rebase VS git merge? 更优雅的 git 合并方式值得拥有

Git恢复以前版本的两种方法reset、revert(图文详解)

相关文章
相关标签/搜索