Git摘樱桃拆分commit进行提交
最近在对OAS进行优化的时候,针对一些改动想给上游仓库提出PR(这是我第一次提PR)。对原仓库提出PR后,我继续对Fork出来的仓库进行改动,上周五原作者针对PR提出建议一次改太多了
。我寻思着我也没改很多东西,然后打开Github,在提出的PR下方发现,它自动的最终了我后面的更改。这针对原作者的仓库进行合并无意是十分不友好的。通过冲浪发现Git摘樱桃可以提交个别的commit。
一、需求
- 本地仓库作出了大量修改,但只想把个别提交发送给上游仓库;
- 上游仓库有一些提交不适合你,你不想把它们一并合并到你的代码库中;
- 你的项目是完全独立的,只想选择性地接受上游的部分提交。
二、选择个别提交到上游仓库
1.增加远端
在本地项目中增加远端,Git默认的远端仓库叫origin
,实际上,它支持添加多个远端仓库。我们把上游仓库添加进来,取名为upstream
:
1 | git remote add upstream <上游仓库地址> |
注:请不要直接在上游仓库已存在的分支进行直接的更改,这是一个码喽
应有的修养。如果你这样做了,请在所有操作之前将你的工作分支转移至一个新的分支,确保上游仓库的内容不会干扰你的工作分支。
2.根据上游分支建立patch分支
假设我们要同步的上游分支是master
。首先把上游仓库同步到本地:
1 | git fetch upstream |
然后上游仓库master
分支的基础上建立一个新的patch-1
分支:
1 | git checkout -b patch-1 upstream/master |
**注意:**如果不事先使用git fetch
,则git checkout
的过程会失败,提示找不到分支upstream/master
。
3.找出要pull request的提交
这时就会自动切换到新分支patch_1
中。我们可以先切换回本地的工作分支(如master
):
1 | git checkout master |
然后浏览提交日志:
1 | git log |
在提交日志里,把你需要pull request的提交ID记录下来。下方提交日志的范例中,commit
字样后面的十六进制文本就是提交ID,通常只记前七位就可以了:
1 | commit b305a606dff60d9fc2371d3a70535cbedb449bfc (HEAD -> master, origin/master) |
4.git cherry-pick摘樱桃
这里假设要以上例中第二、第三个提交来发起pull request。
首先切换到patch-1
分支:
1 | git checkout patch-1 |
然后运行cherry pick,应用上述两个提交:
1 | git cherry-pick 8b442234891085a769f36debf21f0c46da5afb14 |
命令的输出结果如下所示,跟平时使用git commit
的输出是一样的:
1 | [patch-1 8b44223] Update: 2020-12-10 7:12:45 |
注:这里可能会出现冲突,你需要解决所有的冲突,然后继续执行git cherry-pick。具体来说如下:通过git status
查看存在冲突的文件,输入git diff
在代码中生成冲突提示,之后根据冲突提示开始逐个文件解决冲突。之后直接在IDE中完成修改解决冲突,重新git add .
将解决冲突的文件进行添加,然后git cherry-pick --continue
,提示成功即可。
5.推送分支
Cherry pick完成后,把patch-1
分支推到GitHub上自己的fork:
1 | git push origin patch-1 |
6.发起pull request
登录GitHub,然后像往常一样,从自己的仓库发起pull request。但要注意,你的仓库一侧用于比较的分支应该选择刚刚创建的patch-1
分支。
7.删除patch分支
如果上游仓库接受了你的pull request,你就可以把patch-1
分支删除了:
1 | # 首先确保不在patch-1分支中。Git不支持在一个分支里删除自己 |
三、拣选上游仓库的提交
1.增加远端
在本地项目中增加远端,Git默认的远端仓库叫origin
,实际上,它支持添加多个远端仓库。我们把上游仓库添加进来,取名为upstream
:
1 | git remote add upstream <上游仓库地址> |
注:请不要直接在上游仓库已存在的分支进行直接的更改,这是一个码喽
应有的修养。如果你这样做了,请在所有操作之前将你的工作分支转移至一个新的分支,确保上游仓库的内容不会干扰你的工作分支。
2.拉取上游分支
然后从上游仓库拉取所需分支(如master
)的内容,保存到本地。
首先,把上游仓库同步到本地:
1 | git fetch upstream |
然后,把上游仓库的master
分支下载下来,保存到一个新分支master-upstream
当中:
1 | git checkout -b master-upstream upstream/master |
拉取后就会自动切换到该新分支下,这样就可以像管理你的分支一样进行操作了,一些适用于本地分支的命令(如git merge
、git diff
、git cherry-pick
)均可使用。
如果之前已经进行过上述步骤,则使用git pull
更新本地的上游仓库:
1 | git pull upstream master-upstream |
3.找出要采用的提交
在master-upstream
分支下,查看提交记录:
1 | git log |
然后记下要采用的提交ID。
4.git cherry-pick摘樱桃
重新切换回你的仓库分支,然后使用git cherry-pick
应用提交(以下提交ID为示例):
1 | git checkout master |
5.把修改推到你的仓库
完成之后,直接把你的提交推到远程仓库:
1 | git push origin master |