git commit
git log
master` ,其实是一个特殊的 `branch`:它是 Git 的默认 `branch
所谓的「默认 branch」,主要有两个特点:
新创建的 repository(仓库)是没有任何 commit
的。但在它创建第一个 commit
时,会把 master
指向它,并把 HEAD
指向 master
。
当有人使用 git clone
时,除了从远程仓库把 .git
这个仓库目录下载到工作目录中,还会 checkout
(签出) master
(checkout
的意思就是把某个 commit
作为当前 commit
,把 HEAD
移动过去,并把工作目录的文件内容替换成这个 commit
所对应的内容)。
branch
理解为从初始 commit
到 branch
所指向的 commit
之间的所有 commit
s 的一个「串」。例如下面这张图:
bramch的理解
1.所有的 branch
之间都是平等的。
包含了从初始
commit` 到它的所有路径,而不是一条路径。并且,这些路径之间也是彼此平等的。git checkout -b feature1
…
git commit
git checkout master
…
git commit
git branch -d feature1
需要说明的有两点:
HEAD
指向的 branch
不能删除。如果要删除 HEAD
指向的 branch
,需要先用 checkout
把 HEAD
指向其他地方。
由于 Git 中的 branch
只是一个引用,所以删除 branch
的操作也只会删掉这个引用,并不会删除任何的 commit
。(不过如果一个 commit
不在任何一个 branch
的「路径」上,或者换句话说,如果没有任何一个 branch
可以回溯到这条 commit
(也许可以称为野生 commit
?),那么在一定时间后,它会被 Git 的回收机制删除掉。)
出于安全考虑,没有被合并到 master
过的 branch
在删除时会失败(因为怕你误删掉「未完成」的 branch
啊):
所谓「引用」(reference),其实就是一个个的字符串。这个字符串可以是一个 commit
的 SHA-1 码(例:c08de9a
),也可以是一个 branch
(例:`ref: refs/heads/xxx)。
Git 中的 HEAD
和每一个 branch
以及其他的引用,都是以文本文件的形式存储在本地仓库 .git
目录中,而 Git 在工作的时候,就是通过这些文本文件的内容来判断这些所谓的「引用」是指向谁的。
实质上,push
做的事是:把当前 branch
的位置(即它指向哪个 commit
)上传到远端仓库,并把它的路径上的 commit
s 一并上传。
git checkout feature1
git push origin feature1
它做的事也是合并:指定一个 commit
,把它合并到当前的 commit
来
git merge branch1
merge
有什么用
合并分支
当一个 branch
的开发已经完成,需要把内容合并回去时,用 merge
来进行合并。
pull
的内部操作
之前说过,pull
的实际操作其实是把远端仓库的内容用 fetch
取下来之后,用 merge
来合并。
commit
一下git merge feature1
在 Git 中,有两个「偏移符号」: ^
和 ~
。
^
的用法:在 commit
的后面加一个或多个 ^
号,可以把 commit
往回偏移,偏移的数量是 ^
的数量。例如:master^
表示 master
指向的 commit
之前的那个 commit
; HEAD^^
表示 HEAD
所指向的 commit
往前数两个 commit
。
~` 的用法:在 `commit` 的后面加上 `~` 号和一个数,可以把 `commit` 往回偏移,偏移的数量是 `~` 号后面的数。例如:`HEAD~5` 表示 `HEAD` 指向的 `commit`往前数 5 个 `commit
git log -p
git log --stat
commit
,直接输入 git show
;要看指定 commit
,输入 git show commit的引用或SHA-1
git show
的最后加上文件名commit
的区别:git diff --staged
(或 --cached
)git diff
不加选项参数commit
的区别:git diff HEAD
git merge branch1
git checkout branch1
git rebase master
commit -—amend
git reset --hard HEAD^
git rebase --onto 目标 commit
起点 commit
终点 commit
git rebase --onto 第3个commit 第4个commit branch1
git reset --hard branch2
--hard
:重置位置的同时,清空工作目录的所有改动;--soft
:重置位置的同时,保留工作目录和暂存区的内容,并把重置 HEAD
的位置所导致的新的文件差异放进暂存区。--mixed
(默认):重置位置的同时,保留工作目录的内容,并清空暂存区。git checkout branch2
git checkout branch名
的本质,其实是把 HEAD
指向指定的 branch
,然后签出这个 branch
所对应的 commit
的工作目录
checkout
和 reset
都可以切换 HEAD
的位置,它们除了有许多细节的差异外,最大的区别在于:reset
在移动 HEAD
时会带着它所指向的 branch
一起移动,而 checkout
不会
git stash
git stash pop
git stash -u
config
HEAD
index
objects
git config --global user.name "John Doe"
git config --global user.email [email protected]
git config --list
blob对象就是单纯存储数据
像一个目录,管理一些“tree”对象或是“blob”对象
“commit”对象指向一个“tree对象”
一个“tag”对象包括一个对象名(SHA1签名)、对象类型、标签名、标签创建人的名字(“tagger”), 还有一条可能包含有签名(signature)的消息
跟踪新文件
git add README
git status
暂存已修改文件
查看已暂存和未暂存的修改
git diff
git diff --staged
移除文件
git rm
git rm --cached
查看提交历史
git log
一个常用的选项是,用来显示每次提交的内容差异。 你也可以加上来仅显示最近两次提交:
git log -p -2 git log --stat
git log --pretty=oneline
git log --pretty=format:"%h - %an, %ar : %s"
撤消操作
有时候我们提交完了才发现漏掉了几个文件没有添加,或者提交信息写错了。 此时,可以运行带有 选项的提交命令尝试重新提交:
git commit --amend
取消暂存的文件
git reset
撤消对文件的修改
git checkout -- filename
查看远程仓库
git clone https://github.com/schacon/ticgit
git remote -v
列出标签
git tag
git tag -l 'v1.8.5*'
创建标签
git tag -a v1.4 -m 'my version 1.4'
本地分支
1.分支概念
提交记录串成的时间线,默认初始创建的分支(时间线) —— master分支, 如果不切换到其他分支上,每次commit生成的快照都会串在这条分支上! 另外还有个 —— HEAD指针,该指针指向正在工作的本地分支,前面的版 本回退其实修改的就是这个HEAD指针的指向!
分支简介
git add README test.rb LICENSE
git commit -m 'The initial commit of my project'
新建分支
git add README test.rb LICENSE
git commit -m 'The initial commit of my project'
git merge git rebase
git reset 与 git checkout 差异
开发新需求都从master拉取feature分支,不同迭代发布代码使用不同的分支,避免相互影响。 需要进行开发环境联调的代码合并到develop分支,由jenkins自动发布到开发环境。
命名方式:dev-mmdd(时间)-需求名称,例如:dev-1205-xxxx
每月为一个迭代周期由系统owner拉取提测分支test,并定期维护(merge master)。开发feature分支合并到提测test分支,合并前需要由模块负责人进行review或交叉review。
多个feature分支在测试过程中,需要借助release分支来进行合并,然后进行提测。
多个feature分支在测试过程中,某一个需求不能如期发布,需要将release分支删除,讲课继续的分支重复执行第2部进行测试验证。
命名方式:test-mmdd(每月10日),例如:test-1215/ release-mmdd(每月10日),例如:release-1210
测试通过后release进行merge master,并解决冲突,在release分支回归测试
回归测试后,现在master分支拉取tag分支备份,然后把release合并到master
发布到master
命名方式:tag-mmdd(时间),例如:tag-1212
我们知道常用的命令:
git的本地库,暂存区,与工作区流程图:
再来一张图回忆一下常用命令:
GitFlow流程常用分支
也就是我们经常使用的Master分支,这个分支最近发布到生产环境的代码,最近发布的Release, 这个分支只能从
其他分支合并,不能在这个分支直接修改
这个分支是我们是我们的主开发分支,包含所有要发布到下一个Release的代码,这个主要合并与其他分支,比如
Feature分支
这个分支主要是用来开发一个新的功能,一旦开发完成,我们合并回Develop分支进入下一个Release
当你需要一个发布一个新Release的时候,我们基于Develop分支创建一个Release分支,完成Release后,我们合
并到Master和Develop分支
当我们在Production发现新的Bug时候,我们需要创建一个Hotfix, 完成Hotfix后,我们合并回Master和Develop分
支,所以Hotfix的改动会进入下一个Release
团队开发的规范:
当然每个公司可能制度不一样,总得来说,有master主分支,这个分支我们一般不会在上面修改改代码。
比如我们要开发出一个电商系统,需要有支付模块和订单模块,那就从develop分支拉取代码,分别创建feature1和feature2来实现这两块功能,然后合并到test测试分支,没有问题将主分支与版本分支(打标签)合并,完整功能上线!