如何进行代码贡献

本文概述了为Astropy项目贡献代码的过程。

已经有git经验了吗?以前有贡献吗? 直接跳到 Astropy指南 git .

预备知识

在执行本文档中的步骤之前,您需要:

  • 关于 GitHub

  • 星光源的本地副本。操作说明,包括设置git和GitHub所需的基础知识,请访问 尝试开发版本 .

新手 git 是吗?

一些 git 资源

如果您从未使用过git或使用git的经验有限,请花几分钟时间查看以下资源:

实际上,你只需要一小部分 git 为天体学做出贡献的命令。有一个更广泛的列表 Git资源 如果你想要更多的背景。

再次检查您的设置

在进一步操作之前,请确保已按照中所述设置了astropy 尝试开发版本 .

在终端窗口中,将目录更改为包含Astropy克隆的目录。然后,快跑 git remote ;输出应该如下所示:

your-github-username
astropy

如果这行得通,那也跑吧 git fetch --all . 如果它运行时没有错误,那么您的安装正在运行,并且您有克隆中所有分支的完整列表, your-github-usernameastropy .

关于中的姓名 git

git 被设计成 分布式 版本控制系统。存储库的每个克隆本身就是一个存储库。这可能会导致一些混乱,尤其是对于名为 master . 如果你列出你的git克隆知道的所有分支 git branch -a 你会看到的 调用不同的分支 master ::

* master                              # this is master in your local repo
remotes/your-github-username/master   # master on your fork of Astropy on GitHub
remotes/astropy/master                # the official development branch of Astropy

使用的命名方案 git 也将在这里使用。一个简单的分支名称,比如 master 是指你本地的 Astropy 中的一个分支。远程的分支,像 astropy ,被那个遥控器标记, astropy/master .

在处理pull请求时,这种重复的名称可能会非常混乱,尤其是当官方主分支, astropy/master ,在将您的贡献合并到中之前,由于其他贡献而导致的更改。因此,你不应该在你的主分支机构做任何工作, master . 总是在分支上工作。

本质的 git 命令

一个完整的 git 教程超出了本文档的范围,但此列表描述了少数几个 git 你可能会遇到的命令,在贡献 Astropy :

  • git fetch 获取Astropy的最新开发版本,您将使用该版本作为进行更改的基础。

  • git branch 制作一个逻辑上独立的Astropy副本来跟踪您的更改。

  • git add 暂存已更改或创建以添加到的文件 git .

  • git commit 将暂存的更改添加到存储库中。

  • git push 复制您提交给GitHub的更改

  • git status 查看已修改或创建的文件列表。

注解

一个好的git图形界面使这些步骤变得更容易。中介绍了一些选项 获取GitGUI(可选) .

如果出了问题

git 提供了多种从错误中恢复的方法。如果你最后做了一个 git 错了,请不要犹豫寻求帮助。一个额外的资源,引导你从 git 错误是 git choose-your-own-adventure .

Astropy指南 git

  • 不要用你的 master 任何事都可以。考虑 正在删除主分支 .

  • 做一个新的分支,叫做 特征分支 ,对于每个可分离的更改集:“一个任务,一个分支” (ipython git workflow

  • 开始新的 特征分支 来自astropy的最新开发版本(说明如下)。

  • 例如,为更改的目的命名分支 bugfix-for-issue-14refactor-database-code .

  • 频繁提交,并始终包含提交消息。每个提交应该表示一组逻辑更改。

  • 询问 astropy-dev mailing list 如果你被卡住了。

  • 从不合并来自的更改 astropy/master 到你的功能分支。如果开发版本中的更改需要更改我们的代码,则可以 回扣,但只有在被要求的情况下 .

另外还有一些 git 本文档中使用的命名约定:

  • 更改遥控器的名称 originyour-github-username .

  • 命名作为主要天体数据库的遥控器 astropy ;在本文档的早期版本中,它被称为 upstream .

工作流程

从概念上讲,这些是你在制作Astropy时要遵循的步骤:

  1. 获取最新的Astropy

  2. 创建新功能分支 ;您将对此分支进行更改。

  3. 安装您的分支

  4. 跟随 编辑工作流 编写/编辑/记录/测试代码-频繁地、小规模地提交代码。

  5. 添加变更日志条目

  6. 将更改复制到GitHub

  7. 来自GitHub, 要求审阅您的更改 让阿谀奉承的维护者知道你有贡献要回顾。

  8. 根据需要修改和推动 以响应请求请求的请求。将这些更改推送到GitHub会自动更新pull请求。

这种工作方式有助于保持工作井然有序,具有可读的历史记录。这反过来使项目维护人员(可能是您)更容易看到您所做的以及为什么要这样做。

遵循这些步骤解决一个异常问题的有效示例是 为Astropy贡献代码,一个有效的例子 .

一些与 git你可能想做的其他事情 .

正在删除主分支

听起来可能很奇怪,但删除自己的 master 分支可以帮助减少对您所在分支的混淆。见 deleting master on github 有关详细信息。

获取最新的Astropy

您应该不时地获取开发版本(例如Astropy astropy/master )来自GitHub的更改:

git fetch astropy --tags

这将删除您没有的所有提交,并将远程分支设置为指向最新提交。例如,“trunk”是指 astropy/master ,如果上次检查后有提交, astropy/master 在你取货后会改变。

创建新功能分支

做新的分支

当您准备好对代码进行一些更改时,应该启动一个新的分支。用于相关编辑集合的分支通常称为“要素分支”。

为每一组相关的更改创建一个新分支将使审阅分支的人更容易看到您在做什么。

为分支选择一个信息丰富的名称,以提醒您自己和其他人分支中的更改是为了什么。分支机构名称如 add-ability-to-flybuxfix-for-issue-42 清楚地描述分支机构的目的。

总是从 astropy/master 所以你的改变是基于最新版本的Astropy::

# Update the mirror of trunk
git fetch astropy --tags

# Make new feature branch starting at astropy/master
git branch my-new-feature astropy/master
git checkout my-new-feature

将分支连接到GitHub

现在您已经创建并签出了一个新的分支,但是 git 不知道它应该连接到GitHub上的fork。你需要这样的连接才能让GitHub上的Astropy维护人员来管理你提议的变更。

要将本地分支连接到GitHub,您需要 git push 这个新分支到你的GitHub回购 --set-upstream 选项:

git push --set-upstream your-github-username my-new-feature

从现在开始Git会知道的 my-new-featureyour-github-username/my-new-feature 在你的GitHub分支的 Astropy 。

你仍然需要 git push 你对GitHub的定期更改。本节中的设置将使之更容易实现。

安装您的分支

理想情况下,您应该为这个修复设置一个Python虚拟环境;有关执行操作的说明,请参阅 Python虚拟环境 . 这样做可以确保你不会损坏你的主 astropy 安装并使其很容易从错误中恢复。

激活该环境后,需要安装 astropy 你正在努力。使用以下方法:

pip install -e .

关于建筑的更多细节 astropy 源代码,请参见 建筑Astropy及其子包 .

编辑工作流

从概念上讲,您将:

  1. 更改一个或多个文件和/或添加新文件。

  2. 检查您的更改是否不会破坏现有代码。

  3. 将文档添加到代码中,并在适当的情况下添加到Astropy文档中。

  4. 理想情况下,还要确保您的更改不会破坏文档。

  5. 添加对您贡献的代码的测试。

  6. 将更改提交到 git

  7. 必要时重复。

更详细地

  1. 对一个或多个文件进行一些更改。你应该跟着 Astropy 编码指南 . 每个逻辑更改集都应视为一次提交。例如,如果您正在Astropy中修复一个已知的bug,并且在实现修复时注意到了一个不同的bug,那么将这个新bug的修复作为一组不同的更改来实现。

  2. 测试您的更改不会导致 回归 ,也就是说,通过运行Astropy测试,您的更改不会破坏现有代码。您可以使用以下命令运行ipython中的所有Astropy测试:

    import astropy
    astropy.test()
    

    如果你的改变只涉及到星象的一小部分,例如时间,你可以运行那些测试::

    import astropy
    astropy.test(package='time')
    

    测试也可以在包根目录下从命令行运行,例如:

    pytest
    

    要在单个包中运行测试,例如Time,可以执行以下操作:

    pytest -P time
    

    有关运行测试的更多详细信息,请参阅 测试指南 .

  3. 确保代码中包含适当的docstring Numpydoc format . 如果合适,在添加新功能时,应更新中的相应文档 docs 目录;详细说明在 编写文档 .

  4. If you have sphinx installed, you can also check that the documentation builds and looks correct by running, from the astropy directory:

    cd docs
    make html
    

    最后一行应该说明 build succeeded ,并且不应提及任何警告。(有关详细信息,请参阅 编写文档

  5. 如果合适,请添加新代码的测试。有些更改(如文档)不需要测试。详细说明见 写作测试 ,但如果您没有编写测试或 pytest 但不要提没有添加测试的书面测试。编写测试的一个例子是 停下来想想:还有什么测试或其他改变吗? .

  6. 使用暂存更改 git add 并使用 git commit . 一个这样做的例子,基于一个实际的天体问题的修复,是在 为Astropy贡献代码,一个有效的例子 .

    注解

    让你的 git 提交短消息和描述性消息。如果在第二行提交或提交的消息中包含一个问题,请稍后提交: Closes #123 . 这样做将在请求被接受时自动关闭问题。

  7. 有些修改需要不止一次提交;如果有疑问,请将您的更改拆分为几个较小的提交,而不是一次执行多个操作的大型提交。根据需要重复上述步骤!

添加变更日志条目

向文件添加条目 CHANGES.rst 简要描述你所做的改变。在条目的末尾也包括拉取请求编号。一个示例条目,用于 PR 1845 是:

- ``astropy.wcs.Wcs.printwcs`` will no longer warn that ``cdelt`` is
  being ignored when none was present in the FITS file. [#1845]

如果您正在打开一个新的请求请求,您可能还不知道它的编号,但是您可以添加它 之后 你提出了拉动请求。如果您不确定将changelog条目放在哪里,请至少等到维护人员审阅了您的PR并将其分配给里程碑。

在编写变更日志条目时,不要尝试使用单个反勾来建立API引用链接。这是因为changelog(以其当前格式)是针对项目历史运行的,而您今天所做的API引用在Astropy的未来版本中可能无效。但是,鼓励使用双反撇号来表示模块/类/函数/参数名等。

将更改复制到GitHub

由于创建要素分支的方式,此步骤很简单。只是:

git push

要求审阅您的更改

A 拉取请求 在GitHub上,是一个将您所做的更改合并到另一个存储库中的请求。

当您准备请人检查您的代码并考虑将其合并为Astropy时:

  1. 转到你的Astropy分支的网址,例如。, https://github.com/your-user-name/astropy .

  2. 使用“切换分支”下拉菜单选择包含更改的分支:

    ../../_images/branch_dropdown.png
  3. 单击“拉请求”按钮:

    ../../_images/pull_button.png

    输入更改集的标题,以及对所做操作的一些说明。如果您希望特别关注什么,比如复杂的更改或您不满意的代码,请在此处添加详细信息。

    如果您不认为您的请求已经准备好合并,只需在pull-request消息中这样说。这仍然是开始初步代码审查的好方法。

    您也可以选择打开一个正在处理的请求。如果您这样做,而不是单击“创建拉请求”,而是单击它旁边的小向下箭头并选择“创建草稿请求”。这将让维护人员知道,您的工作还没有准备好进行全面审查,也没有准备好进行合并。另外,如果您的提交还没有准备好进行CI测试,您还应该使用 [ci skip][skip ci] 提交消息中的指令。

根据需要修改和推动

您可能会被要求在拉取请求的讨论中进行更改。在本地副本中进行这些更改,将其提交到本地repo并将其推送到GitHub。GitHub将自动更新您的请求。

不创建合并提交

如果与拉请求关联的分支落后于 master 分支机构https://github.com/astropy/astropy,GitHub可能会为您提供通过其web界面来弥补或解决冲突的选项,但不要使用此选项。使用web界面可能会在提交历史记录中创建一个“合并提交”,这是不可取的,因为“合并提交”可能会导致发布管理器的维护开销以及不需要的分支结构复杂性。不要使用 git pull 命令。

取而代之的是,在你的本地结账处,做一个 fetch 然后 rebase ,并根据需要解决冲突。看到了吗 回扣,但只有在被要求的情况下如何回扣 更多信息。

回扣,但只有在被要求的情况下

有时候Astropy的维护者可能会要求一个pull请求 重新定位压扁 在审查一个拉请求合并到主 Astropy 的过程中 主人 储存库。

决定何时请求 壁球重碱 留给个人维护人员。这些请求可能是为了减少存储库历史记录中保存的可见提交的数量,或者是因为同时Astropy中的代码更改。为了允许连续集成测试运行,可能需要重新设置基。两者都涉及重写 git 历史,意味着提交哈希会改变,这就是为什么只有在被要求时才应该这样做。

从概念上讲,重定基意味着将您的更改应用到官方Astropy的最新版本的开发分支,就好像这是您最初分支的版本一样。每个提交都是可见的,但是有新的元数据/提交哈希。压缩提交会更改元数据/提交哈希,并且还会删除单个提交的单独可见性;新的提交和提交消息将只包含先前提交的文本列表。

与其他区域相比,重定位更容易出错 git ,所以在你开始制作一个分支作为你工作的备份之前:

git branch tmp my-new-feature # make temporary branch--will be deleted later

在改变历史之后,例如 git rebase ,一个正常人 git push 被阻止,并且 git push --force 将是必需的。

如何回扣

在幕后, git 删除您所做的更改和分支,将其他人所做的更改更改到Astropy的开发分支,然后从开发分支重新创建分支并将更改应用到分支。

实际的重新定位通常很简单:

git fetch astropy master # get the latest development astropy
git rebase astropy/master my-new-feature

你更有可能遇到 冲突 在这里,你所做的改变与别人所做的改变相冲突的地方,比其他任何地方都要多。如果你需要帮助的话,寻求帮助。有关于如何操作的说明 resolve merge conflicts after a Git rebase .

如何挤压

通常我们会要求 壁球 当进行了大量的尝试和错误,但最终的修补程序仍然很小,或者添加和删除了文件(特别是二进制文件或不应保留在存储库中的文件),或者如果历史中提交的数量与正在执行的工作不相称(例如,30个提交逐渐细化了一个最后10行更改)。从概念上讲,这相当于从一个功能分支导出最终的diff,然后启动一个新分支并仅应用该补丁。

我们中的许多人发现,使用回扣实际上是最容易压扁的。特别是,您可以使用以下命令在现有分支中重定基址和压缩:

git fetch astropy
git rebase -i astropy/master

最后一个命令将打开一个包含所有提交的编辑器,允许您将多个提交压缩在一起,重命名它们等。有用的是,您正在编辑的文件中有关于如何操作的说明。

如何推动

使用后 git rebase 您仍然需要将更改推送到GitHub,以便其他人可以看到这些更改,并且可以更新pull请求。使用简单的 git push 将由于更改的历史记录而被阻止,并且需要使用以下命令手动重写:

git push --force

如果你遇到什么问题,尽管问。关于重新基准的更详细的概念讨论在 后备箱再平衡 .

一旦修改和新的git历史成功地推送到GitHub,就可以删除可能已经创建的任何备份分支:

git branch -D tmp