参与开源社区的常见事项(Git篇)
由于整个开源圈在技术界已经有了无可比拟的地位和影响, 不管是为了个人情怀, 还是提高个人影响, 都应该积极的参与开源, 推广我为人人, 人人为我的精神.
不管由于种种原因, 开源圈最早主要是技术大牛在参与, 因此有一些普通人并不好理解上手的习惯和门槛, 这篇文章主要说一下参与开源过程中, 与git相关的事项. 主要包括Github, Gitlab 与 JIRA (Apache生态), 而关于Git的一些棘手问题, 参考以前篇
0x01. Github相关
很常规的问题直接参考github官方文档. Gitlab后面会单独说
注意: 因为Github的客户端 操作基本是一键/智能化的, 方便查看对比和自动暂存恢复/回滚, 理解了手工步骤之后, 建议还是直接用客户端, 更简洁易用
1. Github PR
注意, 在Github上, 普通人参与开源的第一步就是fork
开源项目, 然后提交pr(pull request)了. 那么这里有个很让人觉得繁琐的事, 就是fork
后的代码是不会自动更新的, 需要定时的手动同步合并一下, 往上很多写法过于繁琐, 我实践后总结了以下步骤:
- 下载代码:
git clone git@github.com:xxx/yourusername/x.git
(注意这里地址就是自己fork后的仓库地址) - (可选)
git remote -v
查看状态(会有一个你fork地址的fetch
&push
,执行步骤3后可再对比看看). - 添加remote库 :
git remote add xx https://github.com/xxxx/autorName/x.git
(这里xx是指的对方版本的名字, 随意取 ,地址就是对方仓库地址) git fetch xx
拉分支到本地 (可以看到* [new branch] master -> up/master
提示)git rebase xx/master
合并操作(如果无更新也会提示。也可用merge,具体区别待补充)- 4和5步可以合并为一个命令,
git pull --rebase xx master
(推荐)
- 4和5步可以合并为一个命令,
- (可选)然后走
git add-->git commit-->git push
-f (rebase/amend可能修改提交记录, 所以需要强制推送) - 最后在你fork后的项目界面手动提PR,等待原项目作者确认 (在一个PR中可提交多个不同的
commit
, 合并时可只选取一条)
第一次初始化好了之后,以后直接跳到第4步,之前不用重复做,具体如下:
先每次git remote update xx
获取更新(xx是3中设置的名字).然后rebase合并(如果有多个分支注意checkout
切换)
2. 快速更新
上面讲的是正常的PR/更新流程, 你可能觉得更新一次怎么这么麻烦, 这还有更简单粗暴的.. 如果 fork 的项目本地是毫无修改的, 在确定我们可以直接覆盖的前提下, 可以用 reset 大法实现三板斧更新:
1 | #1.更新全部远端分支 |
*提醒: *如果本地有修改切勿这样操作.
3. 清理本地多余分支
很多时候, 远端的仓库会经常删除开发的分支, 此时你只是git pull
并不会更新本地的其它不存在的分支, 也不想手动去一个个删, 应该这样做:
1 | # 检测有哪些分支远端已经不存在了.dry-run只是告诉你, 不会实际执行 |
至此就简单说了一下如何 “fork –> 添加代码 –> 提交PR –> 更新” 的脉络, 比较基础, 但是足以应付入门的操作.
至于可能会涉及到的冲突解决, rebase
, 或者修改错误提交的相关问题, 这也是 git 进阶的重要操作 — “回滚/撤回“ , 详细参考下一篇Git 常用操作
0x02. Gitlab相关
首先, 如果是 V10
以上的gitlab, 基本是和github 大致相同的, 这部分可以参考上面的情况. 但是考虑到不同环境 gitlab 版本各不相同, 加上内网环境也有一些限制, 导致这里会有许多内网专属的使用问题.
比如迁移仓库, 新旧版本 gitlab 的配置如果可以直接导出导入, 那就会非常傻瓜化, 但是如果 git仓库并不能这样创建, 那就需要手动去从API层面写爬虫去迁移. 这个之后我会贴一下之前写的 python 脚本. 帮助快速做跨平台/版本迁移.
先说一下最关键的几个问题:
- 跟进社区
- 大版本升级
A. 多次cherry-pick
跟进社区最常用的就是 cherry-pick
,因为大版本肯定是用 merge 了. 这里关键是比如 HDFS 的一个新功能, 不大不小, 可能有几千行代码, 跨度也有半年以上, 而且因为 JIRA
或者 Github
并不能保证在一个 issue 中汇总所有相关Patch, 所以如何高效合并就是个重要问题
B. 大版本的Merge
这里主要还是要依赖 IDEA 的强大多窗口合并功能
未完待续, 之后迁移
0x03. Git Flow
说完了两大主流git远程仓库. 再说一下 git 的工作流 (git glow), 原本 git 就不是给几个人设计的系统, 它面向的场景其实是多分支, 多版本, 多人合作的环境, 先说说基本原则, 再说说其他事项
A. 原则
- master分支不允许直接改动, 开发必须新建分支, 然后合并到master (dev可选)
- master分支必须打tag, 提交信息需按规范书写
B. 核心步骤
- 如果需要下载的代码不是主分支,使用
git clone -b branchName https://xxx
即可.不需要下master - 创建新的分支(比如dev) :
git checkout -b dev
(等同于先git branch dev 再git checkout dev) - 然后git add –>commit ,然后有两种选择,一是直接push到远端git仓库,二是合并到master
- 推送dev分支,
git push dev
(当然第一次可能需要带上--set-upstream
) - 合并dev到master :
git checkout master
,git merge --no-ff dev
,这时候也有两种情况, 冲突否?- 冲突,人工解决冲突文件,删掉冲突标记.然后再add->commit->push
- 不冲突,fast-forward
- 推送dev分支,
- 当从git仓库clone代码的时候,git就会自动把本地的master分支和仓库端对应起来,仓库端默认名是
origin
,git remote -v
可以查看详细信息. (正常权限会有fetch 和 push [拉取])
C. 想把master内容合并到其他分支
大部分流程说的都是如何把dev/其他分支合并到master,但是实际开发中还有个常见需求,就是不希望影响master分支,但是希望合并到自己的分支,master–>dev ,步骤如下:
- (可选)如果dev有改动未提交,先提交改动,不然会禁止切到master
git checkout master
git pull
- (可选) 如有冲突,这里需先解决,然后
git add.
–>git commit -m "merge master to dev"
git checkout dev
git merge master
(这一步是核心,把 master 改动合并过来,在 master 如果没提交这会自动补充msg)git push
(推送到远程仓库的dev)
未完待续
参考资料:
- Github官方文档