本文是我使用 Git 一段时间和看过一些资料后的总结,以及我的看法,深感 Git 的规范使用很是重要,不规范的使用会带来不少麻烦。html
Gitflow 为不一样的分支分配一个很明确的角色,并定义分支之间如何和何时进行交互。分别有历史分支、功能分支、发布分支和维护分支。git
使用两个分支来记录项目的历史。 master
分支记录了正式发布的历史,而develop
分支做为功能的集成分支。所以,master
分支的每次提交都应分配一个版本号。github
功能分支是从develop
中checkout
出来的新分支,每一个功能对应一个分支。shell
1.假设开发a功能:bash
git checkout -b feature-a develop
复制代码
2.当新功能完成时,合并回develop分支。网络
git checkout develop
git merge --no-ff feature-a
git push
git branch -d feature-a
复制代码
1.当develop
分支开发到须要发布时,从develop
分支拉出一个发布分支,命名为release-*
或release/*
。ide
git checkout -b release-0.1 develop
复制代码
2.该分支用于发布循环,只作bug修复、文档生成等面向发布的任务。新功能再也不添加到这个分支上。 3.一旦发布完成,把发布分支merge
到master
分支上。svn
git checkout master
git merge --no-ff release-0.1
git push
复制代码
4.打tag
记录版本号,方便跟踪每次发布。工具
git tag -a 0.1 -m "release 0.1 publish" master
git push --tags
复制代码
5.把这些重新建发布分支以来作的修改merge
到develop
分支。测试
git checkout develop
git merge --no-ff release-0.1
git push
复制代码
6.最后删除发布分支
git branch -d release-0.1
复制代码
当线上版本出现bug时,就须要用到维护分支,它用于快速给产品发布版本打补丁。
1.从master
分支拉一个维护分支(这是惟一从master
分支拉出来的分支)。
git checkout -b hotfix master
复制代码
2.修复完成后,立刻合并回master
和develop
。
git checkout master
git merge --no-ff hotfix
git push
git checkout develop
git merge --no-ff hotfix
git push
git branch -d hotfix
复制代码
3.master
用新版本号打tag
。
git tag -a 0.2 -m "release 0.2 publish" master
git push --tags
复制代码
master
和develop
分支分别记录发布和功能开发的历史develop
master
和develop
GitHub 使用的工做流
master
上的东西都是可发布的(已发布或立刻发布)master
拉一个名称清晰的新分支push
到远程仓库merge
时,打开一个pull request
master
push
到master
后,应该当即发布develop
做为固定的持续集成和发布分支
master
拉一个功能分支。develop
。develop
后,rebase master
到develop
,完成发布。tag
。develop
分支的发布版本合并回master
。master
),和当前开发的其余分支不产生依赖关系master
始终是已发布状态暂时想不到。。。
Pull requests
不是一种工做流,而是一个能让开发者更方便地进行协做的功能,能够在提议的修改合并到正式项目以前对修改进行讨论。这种方式对分支的合并有一些限制,例如只有项目维护者有权限合并分支到仓库中。其工做方式:
push
分支修改到远程仓库中。Pull requests
。Pull Requests
。git commit --amend
最多见的用法是上次提交信息写错,或提交文件多了或漏了之时,从新提交覆盖上一次提交。
其实它还有一个用法,就是用来合并提交。例如上次提交的修改并不彻底,再做修改以后能够用该命令把本次提交与上次提交合并在一块儿。
在须要回滚一次或屡次提交时,能够用git reset
。因为该命令比较危险,建议用于已经把最新提交推到远程仓库上的本地分支。
把已在暂时区的文件取消,恢复到已修改未暂存状态。
git reset
后面可带参数HEAD~[n]
(n >= 1)。表示回退到n
个提交以前。同时,它也能够用来合并提交。下面的写法与git commit --amend
结果是同样的。
git reset HEAD~1
git commit
复制代码
下面的用法则是合并了屡次提交
git reset HEAD~2
git commit
复制代码
git reset
后面也能够带版本号,直接回退到指定版本。
git reset的三种参数
--hard
,如git reset --hard [version]
会执行如下操做:
--soft
,如 git reset --soft [version]
会执行上述的操做a。即只更改引用的指向,不改变暂存区和工做区。--mixed
或者不使用参数(默认为--mixed
),如 git reset [version]
会执行上述的操做a和b。即更改引用的指向及重置暂存区,可是不改变工做区。--no-ff
是不快速合并的意思
git merge
的结果:
被merge的分支和当前分支在图形上并为一条线,被merge的提交点逐一合并到当前分支。
git merge --no-ff
的结果:
被merge的分支和当前分支不在一条线上,被merge的提交点还在原来的分支上,同时在当前分支上产生一个合并点。
git rebase
通常解释为变基
,也有解释为衍合
,我的以为变基
比较容易理解。
git merge
是把两个分支的代码合并到一块儿,其实git rebase
也是相同的做用,可是表现上是两种不一样的形式。
例如如今 dev 提交了一次,master 在此以后也提交了一次,两个分支的状态以下:
能够看出git merge
后,不管加不加--no-ff
参数,提交点的顺序都和提交的时间顺序相同,即 master 的提交在 dev 以后,如图:
而git rebase
后,顺序就变成被rebase
的分支(master)全部提交都在前面,进行rebase
的分支(dev)提交都在被rebase
的分支以后,在同一分支上的提交点仍按时间顺序排列,如图:
从上面的图能够看出,dev 在rebase
master 后,分支发生了变化,本来是两个分支,rebase
的结果看起来是: dev 是基于 master 的分支,且产生了一些新提交。
通常来讲,rebase
后的 dev 和远程的origin/dev
会发生分离,在命令行界面中会提示:
Your branch and 'origin/dev' have diverged,
and have 1 and 1 different commits each, respectively.
(use "git pull" to merge the remote branch into yours)
复制代码
这时须要用git push -f
强制推送,覆盖远程分支。若使用了提示中的git pull
,结果会变成合并,并产生一个合并提交点。
注:慎用git push -f
!
注意git pull
时请加上--rebase
,理由下面会说。
在通常状况下,加与不加--rebase
是没有区别的。然而,结合上面说的git rebase
功能,能够知道某个分支可能与其远程分支发生分离,而当你pull
时,你的本地分支仍是和原来的远程分支同样,这时若是使用git pull
,则会变成你的本地分支和远程分支合并,正确的作法是git pull --rebase
,才会拉取到最新的分支。
因此推荐在任什么时候候pull
远程分支,最好加上--rebase
参数。
查看提交记录的命令是git log
,而git reflog
的功能是查看本地操做记录,如此一来能够看到本地的commit
, merge
, rebase
等操做记录。
6fe46ab HEAD@{0}: rebase finished: returning to refs/heads/dev
6fe46ab HEAD@{1}: rebase: dev modify a
2c92bcb HEAD@{2}: rebase: checkout master
9b26f5d HEAD@{3}: reset: moving to 9b26f5db1e8597b884c45114fbbff36c440da274
5531fc0 HEAD@{4}: merge master: Merge made by the 'recursive' strategy.
9b26f5d HEAD@{5}: checkout: moving from master to dev
复制代码
Pro Git,Git工具书: http://iissnan.com/progit/html/zh/ch1_5.html
Git 工做流指南,介绍了几种主流工做流: https://github.com/xirong/my-git/blob/master/git-workflow-tutorial.md
Gitflow 有害论: http://insights.thoughtworkers.org/gitflow-consider-harmful/
GitHub Flow: http://scottchacon.com/2011/08/31/github-flow.html
Google 的“主干开发”(trunk-based development): http://www.ruanyifeng.com/blog/2016/07/google-monolithic-source-repository.html