前端git开发分支各种场景管理
github flow场景
第一步:根据需求,从master拉出新分支,不区分功能分支或补丁分支。
第二步:新分支开发完成后,或者需要讨论的时候,就向master发起一个pull request(简称PR)。
第三步:Pull Request既是一个通知,让别人注意到你的请求,又是一种对话机制,大家一起评审和讨论你的代码。对话过程中,你还可以不断提交代码。
第四步:你的Pull Request被接受,合并进master,重新部署后,原来你拉出来的那个分支就被删除。(先部署再合并也可。)
这个场景满足绝大多数的中小项目开发需求。
多主干场景
场景描述如下:
- 当前仓库是个通用组件,需要同时维护多个版本,如 1.x,2.x。
- 仓库代码针对多个场景的输出,对应的源码有差别,但需要同时维护。
- 仓库代码发布线上后,发布线上的代码不想立刻合并到 master,待确认线上稳定后再合并。
多主干项目v1版
a人开发分支为daily/1.0.0。
然后从daily/1.0.0切出功能分支feature/describe
,开发测试完毕后合并到daily/1.0.0,并删除feature/describe
分支。
发布分支从publish/1.0.0开始递增。
publish分支发布后,会合并到开发分支daily/1.0.0
,但不会把代码合到master。
b人开发分支也为daily/1.0.0,发布前需合并一下publish/1.x.x
的最新版本。
多主干项目v2版
a人开发分支为daily/2.0.0
.
然后从daily/2.0.0
切出功能分支feature/describe
,开发测试完毕后合并到daily/1.0.0,并删除feature/describe
分支。
发布分支从publish/2.0.0开始递增。
publish分支发布后,会合并到开发分支daily/2.0.0
,但不会把代码合到master。
b人开发分支也为daily/2.0.0,发布前需合并一下publish/2.x.x
的最新版本。
注意
以上功能只是一个思路,非git自带,需要自定义开发。
这种多主干场景也可以用fork仓库方式解决。
也就是Github fork其他项目的分支与主干保持同步
。
Github fork其他项目的分支与主干保持同步
Fork一个Repo
Fork是一个复制的操作,当你Fork一个项目之后,你就有了在原项目的基础之上进行修改和扩展的权限。
通常情况下,Fork操作用于参与别人的项目(成为项目中的一员),或者以别人的项目为基础来开发自己的项目。
当你使用一个开源项目的时候,如果项目中存在bug,除了可以将bug报告项目开发人员。你也可以通过Fork原项目,并参与进来。
- 首先,Fork原项目,并将项目代码更新到你的本地;
- 其次,修复项目中的bug,并确认问题已修复;
- 最后,如果一切测试都没有问题,你就可以提交一个pull request给项目所有人,如果项目所有者认可你的代码,他就会将你的修改更新到原项目中;
在Github中,Fork一个开源项目主要有两步:
查找到你想要Fork的项目;
点击项目介绍页面右上角的Fork;
保持同步
当你Fork一个项目之后,你的项目与原项目之间就不存在联系了,当原项目有更新的时候,你自己Fork的项目也不会同步保持更新。为了保持与原项目的一致,你需要使用到Git的命令行。
第一步 安装git客户端
如果你没有安装git的客户端,你需要先去下载git的客户端并安装,windows系统git下载安装地址:http://git-scm.com/download/
第二步 clone你fork的项目
fork一个项目使用git命令行clone项目:git clone git@github:[yourname]/Spoon-knife
第三步 添加新的远程仓库地址
当你clone完一个项目,可以使用git remote -v
来查看你fork的远程仓库的地址;默认的clone操作完成后,远端仓库的地址别名为:origin,为了需要与原项目保持更新,你还需要将原项目地址给添加进来,使用命令:git remote add upstream git@github.com:octocat/Spoon-Knife.git
可以添加远端仓库地址,其中upstream
为新的远端仓库的别名。
第四步 同步更新
假设你已经完成了前三步,当原项目有更新的时候,怎么将更新检入到本地呐,主要是以下几个步骤:
打开git命令行工具;
进入项目本地路径;
执行git fetch upstream
命令,检出upstream
分支以及各自的更新。
切换到你的本地分支主干:git checkout master
。
合并upsteram/master分支和master分支,将原项目中的更改更新到本地分支,这样就能使你的本地的fork分支与原项目保持同步,命令为git merge upstream/master
。
或者使用命令git cherry-pick
挑几个commit来合并。
执行git push将本地分支的修改推送到远端fork的项目。
参考:https://www.cnblogs.com/kakag/p/4287536.html
子模块场景
当前git项目依赖另一个git项目。
你想将两个项目单独处理但是又需要在其中一个中使用另外一个。
子模块变更
在子模块中的git操作就和独立的git项目操作一样。
进入到子模块目录,提交变更。
$ git add .
$ git commit -m "commit"
$ git push origin HEAD:master
提交完子模块的变更,还要回到父模块的目录,提交下子模块的变动。
cd ..
git status
git commit -m 'update submodule'
git push origin
子模块更新
在父模块的目录下更新子模块
git submodule update --recursive
在子模块的目录下,就是正常git操作
git pull
clone包含子模块的父模块仓库
方法1,直接递归clone
git clone git@github.com:jjz/pod-project.git --recursive
方法2,只clone了父模块,要追加clone子模块
git clone git@github.com:jjz/pod-project.git
cd pod-project
git submodule init
git submodule update
添加子模块
已有的项目中添加子模块步骤
git submodule add git@github.com:xxx/xxx-library.git xxx-library
git add .gitmodules xxx-ibrary
git commit -m "xxx-library submodule"
git submodule init
git submoudle update
删除子模块
cd pod-project
git rm --cached pod-library
rm -rf pod-library
rm .gitmodules
vim .git/config
# 删除submodule相关的内容
# 比如
# [submodule "*"]
# url = git@github.com:jjz/**.git
git commit -a -m 'remove submodule'
参考
https://git-scm.com/book/zh/v1/Git-%E5%B7%A5%E5%85%B7-%E5%AD%90%E6%A8%A1%E5%9D%97
https://www.jianshu.com/p/9000cd49822c
https://www.jianshu.com/p/b49741cb1347
回滚场景
常见回滚场景
- 丢弃工作区的修改(没有git add过),用命令
git checkout -- file
- 丢弃暂存区的修改(已git add过,没有commit过),用命令
git reset HEAD <file>
- 丢弃本地仓库的当前提交(已commit过,但没有推到远程仓库),命令
git reset --hard commit_id
- 丢弃本地仓库的当前提交(已推到远程仓库),并且覆盖远程仓库提交历史
# 下面两个命令不建议,会被打
git reset --hard resetVersionHash
git push -f origin currentBranch
忠告:如果你的回退涉及到了远程分支,在版本回退时最好使用revert,因它没有修改版本历史;如果使用reset,因为你的reset操作,会使你比远程少了几个提交,远程会提示你落后于远程版本,应该先git pull代码,那么你的reset操作又有何意义呢?(git push -f 强推可以做到,但不推荐这样做)
- 描述如下
假设一开始你的本地和远程都是:
a -> b -> c
你想把HEAD回退到b,那么在本地就变成了:
a -> b
这个时候,如果没有远程库,你就接着怎么操作都行,比如:
a -> b -> d
但是在有远程库的情况下,你push会失败,因为远程库是 a->b->c,你的是 a->b->d
两种方案:
push的时候用--force,强制把远程库变成a -> b -> d,大部分公司严禁这么干,会被别人揍一顿。
实践方案如同4。
做一个反向操作,把自己本地变成a -> b -> c -> d,注意b和d文件快照内容一莫一样,但是commit id肯定不同,再push上去远程也会变成 a -> b -> c -> d
反向操作描述如下(建议操作):
- git log --pretty=online 显示有三个版本
- git revert 版本号,抵消某个版本与其之后版本的修改,注意,这里的逻辑与git reset不一样,如果想回到Second commit的版本,就需要抵消掉Third commit的修改。所以这里应该git revert Third commit的版本号
- revert的过程中可能会有冲突,git status查看冲突位置,解决冲突,git commit 文件名(无需git add)
- git log --pretty=online,Third commit并没有丢失,而是多了一个revert版本,你可以 git log -p查看每个版本的修改,发现revert的版本所做的修改与Third commit恰恰相反,正好抵消掉了它的修改。
git reset commitID
是返回到指定commitID。
git revert commitID
是撤销指定的commitID。
git撤回已add未commit的修改
也就是撤销暂存区的修改。
git checkout .
git删除未跟踪文件
-
删除 untracked files
git clean -f
-
连 untracked 的目录也一起删掉
git clean -fd
-
连 gitignore 的untrack 文件/目录也一起删掉 (慎用,一般这个是用来删掉编译出来的 .o之类的文件用的)
git clean -xfd
-
在用上述 git clean 前,墙裂建议加上 -n 参数来先看看会删掉哪些文件,防止重要文件被误删
git clean -nxfd
git clean -nf
git clean -nfd
git merge了错误分支,如何优雅的回退到merge前的状态?
当前master分支,小明和小王在中午12点分别新建了a b 分支。
1.小明在a分支,下午 1 3 5点分别提交了三个commit
2.小王在b分支,下午 2 4 6点分别提交了三个commit
3.小明在a分支,在下午7点执行了git merge b,此时commit的顺序是1 2 3 4 5 6倒序,但是此时发现merge了错误分支,想回退到下午7点时的没merge的状态,即1 3 5commit状态,如何优雅的进行git回退操作?
使用git merge --abort
。
从commit历史,以及.git库里移除掉某文件
通常是误commit大文件导致不能push。
git push时终端报错:
error: RPC failed; HTTP 413 curl 22 The requested URL returned error: 413 Request Entity Too Large
fatal: The remote end hung up unexpectedly
你已经把大文件写入本地.git历史中。
你需要把它从commit历史,以及.git库里移除掉。
可以使用git filter-branch --tree-filter 'rm -f 文件名' HEAD
命令
查看历史提交记录
git log v1.0.. 查询从v1.0以后的提交历史记录(不包含v1.0)
git log test..master 查询master分支中的提交记录但不包含test分支记录
git log master..test 查询test分支中的提交记录但不办含master分支记录
git log master…test 查询master或test分支中的提交记录。
git log test –not master 屏蔽master分支
仅查看当前分支的提交,不考虑其它分支。
假设你的分支test基于分支master切出来,那么使用git log master..test
或者git log master..