开发工作流程
您已经拥有自己的 NumPy 存储库的分叉副本, 通过以下方式 制作自己的NumPy副本(Fork)以及 设置您的fork,您已经按照Git配置了 git , 并且已经链接了上游存储库,如将您的存储库链接到上游仓库中所述。
下面介绍的是Git的推荐工作流程。
基本工作流程
简而言之:
这种工作方式有助于使工作井井有条,并使历史尽可能清晰。
::: tip 另见
有许多在线教程可以帮助您学习git。有关特定git工作流的讨论,请参阅有关linux git工作流和ipython git工作流的这些讨论。
:::
创建新的功能分支
首先,从upstream存储库中获取新的提交:
git fetch upstream
然后,基于上游存储库的主分支创建新分支:
git checkout -b my-new-feature upstream/master
编辑工作流程
概述
# hack hackgit status # Optionalgit diff # Optionalgit add modified_filegit commit# push the branch to your own Github repogit push origin my-new-feature
更详细的内容
- 做一些更改之后,当您感觉您已经完成了一组完整的相关更改的工作集时,请继续执行下一步。
- 可选:检查哪些文件已使用git状态更改(请参阅git状态)。您将看到如下所示的清单:
# On branch my-new-feature# Changed but not updated:# (use "git add <file>..." to update what will be committed)# (use "git checkout -- <file>..." to discard changes in working directory)## modified: README## Untracked files:# (use "git add <file>..." to include in what will be committed)## INSTALLno changes added to commit (use "git add" and/or "git commit -a")
- 可选:将更改与
git diff(git diff)一起使用的以前版本进行比较。这将显示一个简单的文本浏览器界面,突出显示您的文件与以前版本之间的差异。 - 使用
git add modify_file添加任何相关的已修改或新文件(请参阅 git add)。这会将文件放入暂存区域,该区域是将添加到下一次提交的文件队列。仅添加具有相关完整更改的文件。留有未完成更改的文件供以后提交。 - 要将暂存的文件提交到仓库的本地副本中,请执行
git commit。此时,将打开一个文本编辑器,允许您编写提交消息。阅读提交消息部分,确保您正在编写格式正确且足够详细的提交消息。保存消息并关闭编辑器后,您的提交将被保存。对于琐碎的提交,可以使用-m标志通过命令行传递简短的提交消息。例如,git commit -am "ENH: Some message"。 - 在某些情况下,您将看到这种形式的 commit 命令:
git commit -a。 额外的-a标志自动提交所有已修改的文件并删除所有已删除的文件。 这可以节省一些git add命令的输入; 但是,如果您不小心,它可以为提交添加不需要的更改。 有关更多信息,请参阅为什么-a标志?,以及纠结的工作副本问题中有用的用例描述。 将更改推送到GitHub上的主仓库分支:
git push origin my-new-feature
有关更多信息,请参见git推送(git push)。
::: tip 注意
假设您已按照这些页面中的说明操作,git将创建一个指向您的github repo 的默认链接origin。在git> = 1.7中,您可以使用以下--set-upstream选项确保永久设置到origin的链接:
git push --set-upstream origin my-new-feature
从现在开始,git将知道这my-new-feature与my-new-feature您自己的github仓库中的分支有关。随后的推送调用命令将简化为以下写法:
git push
您必须使用 --set-upstream 创建的每个新分支。
:::
可能的情况是,当您处理编辑时,会添加新的提交,upstream 这会影响您的工作。
在这种情况下,请按照本文档的 Rebasing on master 部分将这些更改应用于您的分支。
编写提交消息
提交消息应该是明确的,并遵循一些基本规则。例:
ENH: add functionality X to numpy.<submodule>.The first line of the commit message starts with a capitalized acronym(options listed below) indicating what type of commit this is. Then a blankline, then more text if needed. Lines shouldn't be longer than 72characters. If the commit is related to a ticket, indicate that with"See #3456", "See ticket 3456", "Closes #3456" or similar.
描述变更的动机,bug修复的bug的本质,或者关于增强所做的一些细节,也可以包含在提交消息中。
消息应该是可以理解的,而不需要查看代码更改。像 Maint:Fixed Another one 这样的提交消息就是不应该做的事情的一个例子;
读者必须到别处去寻找上下文。
启动提交消息的标准首字母缩写词是:
API: an (incompatible) API changeBENCH: changes to the benchmark suiteBLD: change related to building numpyBUG: bug fixDEP: deprecate something, or remove a deprecated objectDEV: development tool or utilityDOC: documentationENH: enhancementMAINT: maintenance commit (refactoring, typos, etc.)REV: revert an earlier commitSTY: style fix (whitespace, PEP8)TST: addition or modification of testsREL: related to releasing numpy
要求您的更改与主仓库合并
当您觉得您的工作已经完成时,您可以创建拉取请求(PR)。Github有一个很好的帮助页面,概述了提交拉取请求的过程。
如果您的更改涉及API的修改或功能的添加/修改,您应该:
- 发送电子邮件到NumPy邮件列表,其中包含您PR的链接以及您的更改的描述和动机。这可能会产生变化和反馈。如果您的更改可能存在争议,那么从这一步骤开始可能是谨慎的做法。
doc/release/upcoming_changes/按照doc/release/upcoming_changes/README.rst文件中的说明和格式向目录 添加发行说明。
重新拉取主分支
这将通过上游NumPy github存储库的更改来更新您的功能分支。如果你不是绝对需要这样做,尽量避免这样做,除非你完成了。第一步是使用来自上游的新提交更新远程存储库:
git fetch upstream
接下来,您需要更新功能分支:
# go to the feature branchgit checkout my-new-feature# make a backup in case you mess upgit branch tmp my-new-feature# rebase on upstream master branchgit rebase upstream/master
如果您对上游已更改的文件进行了更改,则可能会生成需要解决的合并冲突。在这种情况下,请参阅 下面的帮助。
最后,在成功的rebase后删除备份分支:
git branch -D tmp
::: tip 注意
在master上重新绑定比将上游合并到您的分支更受欢迎。在处理功能分支时使用和不鼓励使用。git mergegit pull``
:::
从混乱中恢复
有时候,你搞砸了合并或重组。幸运的是,在Git中,从这些错误中恢复是相对简单的。
如果你在一次变革中陷入困境:
git rebase --abort
如果你注意到在rebase之后搞砸了你:
# reset branch back to the saved pointgit reset --hard tmp
如果您忘记创建备份分支:
# look at the reflog of the branchgit reflog show my-feature-branch8630830 my-feature-branch@{0}: commit: BUG: io: close file handles immediately278dd2a my-feature-branch@{1}: rebase finished: refs/heads/my-feature-branch onto 11ee694744f2552d26aa21a my-feature-branch@{2}: commit: BUG: lib: make seek_gzip_factory not leak gzip obj...# reset the branch to where it was before the botched rebasegit reset --hard my-feature-branch@{2}
如果您实际上并没有陷入困境,但存在合并冲突,则需要解决这些问题。这可能是一个比较棘手的事情。有关如何执行此操作的详细说明,请参阅有关合并冲突的文章。
您可能想要做的其他事情
重写提交历史
::: tip 注意
仅对您自己的功能分支执行此操作。
:::
你做出的承诺中有一个令人尴尬的错字?或许你做了几个错误的开始,你希望后人不要看。
这可以通过 交互式变基 来完成。
假设提交历史记录如下所示:
git log --onelineeadc391 Fix some remaining bugsa815645 Modify it so that it works2dec1ac Fix a few bugs + disable13d7934 First implementation6ad92e5 * masked is now an instance of a new object, MaskedConstant29001ed Add pre-nep for a copule of structured_array_extensions....
并且6ad92e5是master分支中的最后一次提交。假设我们要进行以下更改:
- 重写提交消息以
13d7934获得更明智的信息。 - 合并的提交
2dec1ac,a815645,eadc391到一个单一的一个。
我们做如下:
# make a backup of the current stategit branch tmp HEAD# interactive rebasegit rebase -i 6ad92e5
这将打开一个编辑器,其中包含以下文本:
pick 13d7934 First implementationpick 2dec1ac Fix a few bugs + disablepick a815645 Modify it so that it workspick eadc391 Fix some remaining bugs# Rebase 6ad92e5..eadc391 onto 6ad92e5## Commands:# p, pick = use commit# r, reword = use commit, but edit the commit message# e, edit = use commit, but stop for amending# s, squash = use commit, but meld into previous commit# f, fixup = like "squash", but discard this commit's log message## If you remove a line here THAT COMMIT WILL BE LOST.# However, if you remove everything, the rebase will be aborted.#
为了实现我们想要的目标,我们将对其进行以下更改:
r 13d7934 First implementationpick 2dec1ac Fix a few bugs + disablef a815645 Modify it so that it worksf eadc391 Fix some remaining bugs
这意味着(i)我们想要编辑提交消息
13d7934,以及(ii)将最后三个提交合并为一个。现在我们保存并退出编辑器。
然后,Git会立即调出一个编辑器来编辑提交消息。修改后,我们得到输出:
[detached HEAD 721fc64] FOO: First implementation2 files changed, 199 insertions(+), 66 deletions(-)[detached HEAD 0f22701] Fix a few bugs + disable1 files changed, 79 insertions(+), 61 deletions(-)Successfully rebased and updated refs/heads/my-feature-branch.
历史现在看起来像这样:
0f22701 Fix a few bugs + disable721fc64 ENH: Sophisticated feature6ad92e5 * masked is now an instance of a new object, MaskedConstant
如果出现问题,可以再次进行恢复,如上所述。
删除github上的分支
git checkout master# delete branch locallygit branch -D my-unwanted-branch# delete branch on githubgit push origin :my-unwanted-branch
(请注意:以前的冒号test-branch。另请参阅:https:
//github.com/guides/remove-a-remote-branch
几个人共享一个存储库
如果你想与其他人一起工作,你们都在同一个存储库,甚至同一个分支中,那么只需通过github共享它。
首先将NumPy分配到您的帐户,例如从NumPy 制作您自己的副本(分叉)。
然后,转到你的分叉存储库github页面,比方说 https://github.com/your-user-name/numpy
点击“管理”按钮,然后将其他任何人作为协作者添加到仓库:

现在这些人都能做到:
git clone git@github.com:your-user-name/numpy.git
请记住,以git@使用ssh协议开头的链接是可读写的; 以#开头的链接git://是只读的。
然后,您的协作者可以通常使用以下方式直接进入该回购:
git commit -am 'ENH - much better code'git push origin my-feature-branch # pushes directly into your repo
探索您的存储库
要查看存储库分支和提交的图形表示:
gitk --all
要查看此分支的提交历史列表:
git log
您也可以在 网络图形可视化 工具中查看您的 GitHub 仓库。
反向移植
Backporting是将numpy / master中提交的新功能/修复复制
回稳定版本分支的过程。要做到这一点,你要从你正在向后移植的分支上做一个分支,樱桃挑选你想要的提交
numpy/master,然后提交一个包含backport的分支的pull请求。
- 首先,您需要创建要处理的分支。这需要基于较旧版本的NumPy(而不是master):
# Make a new branch based on numpy/maintenance/1.8.x,# backport-3324 is our new name for the branch.git checkout -b backport-3324 upstream/maintenance/1.8.x
- 现在您需要使用git cherry-pick将变更从master应用到这个分支。
# Update remotegit fetch upstream# Check the commit log for commits to cherry pickgit log upstream/master# This pull request included commits aa7a047 to c098283 (inclusive)# so you use the .. syntax (for a range of commits), the ^ makes the# range inclusive.git cherry-pick aa7a047^..c098283...# Fix any conflicts, then if needed:git cherry-pick --continue
- 你可能会在这里遇到一些挑战。这些解决方法与 merge/rebase 冲突的解决方式相同。除了这里你可以使用 git blame 来查看 master 和 backported 分支之间的区别,以确保没有再搞砸别的事情了。
- 将新分支推送到Github存储库:
git push -u origin backport-3324
- 最后使用Github发出拉取请求。确保它是针对维护分支而不是主分支,Github通常会建议你对master进行pull请求。
将更改推送到主分支
仅当您拥有主NumPy仓库的提交权限时,这才有意义。
如果您准备好NumPy master或maintenance分支的功能分支中有一组 “就绪” 更改,则可以按upstream如下方式将它们推送到:
- 首先,在目标分支上合并(merge)或变基(rebase)。
- 只有几个不相关的提交会更倾向于 rebase:
参见 master分支上的rebase.git fetch upstreamgit rebase upstream/master
- 如果所有提交都相关,请创建合并提交:
git fetch upstreamgit merge --no-ff upstream/master
- 只有几个不相关的提交会更倾向于 rebase:
- 检查你要推动的东西看起来是明智的:
git log -p upstream/master..git log --oneline --graph
- 推送到上游:
git push upstream my-feature-branch:master
::: tip 注意
通常最好使用-n标志来检查您是否要将所需的更改推送到所需的位置。git push
:::
