与Git-Trac协同开发¶
有时你只想为自己的私人需要而对Sage进行局部修改。但是,通常与他人共享代码和想法是有益的;在 Sage project 这(以及修复错误和升级组件)是在一个非常协作和公开的环境中进行的吗 the Sage Trac server (Sage bug和增强跟踪程序)。
一个人可以用 git
the hard way 为此,本节将解释如何使用帮助器 git trac
Sage在许多共同的命令上简化了行动。一些 tutorials 我们建议在导航它们的用途时可能会有所帮助。
除非您在Trac上有帐户,否则以下部分中的大多数命令都将不起作用。如果你想为Sage捐款,最好现在就开个账户(见 取得帐户 )
安装Git-Trac命令¶
Git与trac是一个独立的项目,两者不知道如何相互交谈。为了简化开发,我们有一个特殊的 git trac
git套件的子命令。请注意,这实际上只是为了简化与我们的trac问题管理的交互,您只需使用git和web浏览器就可以执行所有开发任务。看到了吗 艰难的路 相反,如果你喜欢用手做任何事情:
[user@localhost]$ git clone https://github.com/sagemath/git-trac-command.git
Cloning into 'git-trac-command'...
[...]
Checking connectivity... done.
[user@localhost]$ source git-trac-command/enable.sh
Prepending the git-trac command to your search PATH
这将创建一个目录 git-trac-command
.
采购 enable.sh
脚本中只有一种快速而肮脏的方法来临时启用它。为了以后在系统上进行更永久的安装,请确保将 git-trac
你的命令 PATH
. 假设 ~/bin
已经在您的 PATH
,您可以通过符号链接来完成此操作:
[user@localhost]$ echo $PATH
/home/user/bin:/usr/local/bin:/usr/bin:/bin:/usr/local/sbin:/usr/sbin
[user@localhost]$ cd git-trac-command
[user@localhost git-trac-command]$ ln -s `pwd`/git-trac ~/bin/
见 git-trac README 更多细节。此时你离开 git-trac-command
子目录,并且只在需要更新 git-trac
命令。
Git和Trac配置¶
注解
trac 使用用户名/密码进行身份验证。
我们的 git repository server 使用SSH公钥身份验证进行写访问。
您需要设置两种身份验证机制,以便能够使用“git-trac”上载更改。对于只读访问,不需要身份验证机制。建立 git trac
,首先转到Sage目录并告诉 git trac
关于您的trac帐户:
[user@localhost sage]$ git trac config --user USERNAME --pass 'PASSWORD'
Trac xmlrpc URL:
https://trac.sagemath.org/xmlrpc (anonymous)
https://trac.sagemath.org/login/xmlrpc (authenticated)
realm sage.math.washington.edu
Username: USERNAME
Password: PASSWORD
Retrieving SSH keys...
1024 ab:1b:7c:c9:9b:48:fe:dd:59:56:1e:9d:a4:a6:51:9d My SSH Key
其中,必须将USERNAME替换为trac用户名,并将PASSWORD替换为trac密码。如果您没有trac帐户,请使用 git trac config
没有任何争论。中的单引号 'PASSWORD'
对密码中可能包含的特殊字符进行转义。密码以明文形式存储在 .git/config
,因此请确保系统上的其他用户无法读取它。例如,通过运行 chmod 0600 .git/config
如果你的主目录还不是私有的。
除了用户名和密码,您还可以通过传递生成的令牌来配置身份验证 --token=<token>
而不是 --pass
::
[user@localhost sage]$ git trac config --user=<username> --token=<token>
如果您使用GitHub帐户对Trac进行身份验证,则需要这样做,因为您没有Trac密码。登录用户可以在 the token tab in preferences on the trac site .
注解
此处输入的用户名不是GitHub用户名,而是trac用户名,即trac服务器右上角给出的gh-<GitHub username>。
如果同时配置了令牌和用户名/密码,则基于令牌的身份验证优先。
如果不想在磁盘上存储trac用户名/密码/令牌,可以使用环境变量临时覆盖它 TRAC_USERNAME
, TRAC_PASSWORD
和 TRAC_TOKEN
分别。这些配置优先于任何其他配置。
如果没有列出SSH密钥,那么您还没有将SSH公钥上载到trac服务器。你现在应该按照 将您的公钥链接到您的Trac帐户 ,如果要上载任何更改。您可能需要将私钥添加到身份验证代理:
[user@localhost sage]$ ssh-add
注解
这个 git trac config
命令将自动添加 trac
远程git存储库到远程列表(如果需要)。
如果按照上述说明进行操作,则将设置两个远程存储库:
[user@localhost sage]$ git remote -v
origin git://github.com/sagemath/sage.git (fetch)
origin git://github.com/sagemath/sage.git (push)
trac git://trac.sagemath.org/sage.git (fetch)
trac git@trac.sagemath.org:sage.git (push)
这个 git@...
推送url的一部分意味着写访问是由SSH密钥保护的,您必须按照中所述设置 将您的公钥链接到您的Trac帐户 . 只读访问通过fetch url进行,不需要SSH。
最后,如果您不想使用 git trac
子命令,然后您可以手动设置远程,如上一节中所述 Trac服务器 .
Trac票务和Git分支机构¶
现在让我们开始向Sage添加代码!
创建票据¶
假设您已经编写了一个计算最后孪生素数的算法,并希望将其添加到Sage中。你应该先开罚单:
[user@localhost sage]$ git trac create 'Last Twin Prime'
Remote branch: u/user/last_twin_prime
Newly-created ticket number: 12345
Ticket URL: https://trac.sagemath.org/12345
Local branch: t/12345/last_twin_prime
这将创建一张名为“最后一张双人特价票”的新trac客票 远程分支 u/user/last_twin_prime
依附于它。远程分支名称是从票证标题自动派生的;如果您不喜欢这样,则可以使用 -b
切换以显式指定它。看到了吗 git trac create -h
了解详情。此新分支将自动签出 地方分行 名称 t/12345/last_twin_prime
.
注解
只有一些trac字段是自动填充的。看到了吗 售票区 关于哪些trac字段可用以及我们如何使用它们。
检查现有的票据¶
或者,您可以使用 web interface to the Sage trac development server 开一张新票。只需登录并单击“创建票证”。
或者其他人已经开了罚单。然后,为了找到合适的本地分支来进行编辑,您只需运行:
[user@localhost sage]$ git trac checkout 12345
Loading ticket #12345...
Checking out Trac #13744 remote branch u/user/last_twin_prime -> local branch t/12345/last_twin_prime...
这个 git trac checkout
命令下载一个现有的分支(如trac票证上的“branch:”字段中指定的那样)或创建一个新的分支(如果还没有分支)。与create命令一样,可以使用 -b
你想换就换。
关于分支机构名称的说明¶
trac票证的“Branch:”字段(请参见 售票区 )指示包含其代码的git分支。我们的git服务器为 远程分支名称 :
您可以读/写/创建一个名为
u/your_username/whatever_you_like
. 其他人都会读书。每个人都可以读/写/创建一个名为
public/whatever_you_like
.
根据您的协作风格,您可以使用其中一种。这个 git trac
子命令默认为前者。
作为惯例 git trac
子命令使用 本地分支机构名称 形式的 t/12345/description
,其中数字是trac票号。脚本使用这个数字从本地分支名称中计算出票据。如果需要,可以重命名本地分支,但如果它们不包含票证号,则在上载更改时必须手动指定票证号。
正在将更改上载到Trac¶
自动推送¶
在某个时候,你可能希望与我们分享你的改变:也许它已经准备好接受审查了,或者你正在与某人合作,希望“直到现在”分享你的改变。这只需:
[user@localhost sage]$ git trac push
Pushing to Trac #12345...
Guessed remote branch: u/user/last_twin_prime
To git@trac.sagemath.org:sage.git
* [new branch] HEAD -> u/user/last_twin_prime
Changing the trac "Branch:" field...
这会将您的更改上载到 Sage git server . 这个 git trac
命令使用以下逻辑查找远程分支名称:
默认情况下,远程分支名称将是trac票证上已有的名称。
If there is no remote branch yet, the branch will be called
u/user/description
(u/user/last_twin_prime
in the example).你可以使用
--branch
但需要在远程命名选项后面显式指定分支名称 关于分支机构名称的说明 你要有书面许可。
指定票号¶
您可以将任何本地分支上载到现有票据,无论是否使用创建本地分支 git trac
. 这与您从一张罚单开始时的情况完全一样,只是您必须指定票证号(因为无法判断您想要的是哪张票)。也就是说:
[user@localhost sage]$ git trac push TICKETNUM
你必须更换 TICKETNUM
带着trac票的号码。
完成它¶
通常在上传之前要经过几次提交迭代,而且在准备好审阅更改之前,您可能也会将更改推送几次。
一旦您对上传的更改感到满意,必须由其他人进行审阅,然后才能将其包含在Sage的下一个版本中。若要将您的票证标记为“准备审阅”,应将其设置为 needs_review
在trac服务器上。此外,通过在第一行插入以下内容,将您自己添加为该票据的作者(或作者之一):
Authors: Your Real Name
从Trac下载更改¶
如果有人在处理罚单,或者你刚换了电脑,你会想把最新版本的分公司从一张罚单拿到你当地的分公司。完成:
[user@localhost sage]$ git trac pull
从技术上讲,这是一个 合并 (就像标准一样 git pull
)命令。看到了吗 合并和重基 了解更多背景信息。
合并¶
一旦你在一个跨越多个票证的更大的项目上工作,你就要把你的工作建立在尚未合并到Sage中的分支上。这在协作开发中是很自然的,事实上,我们非常鼓励您将工作分成逻辑上不同的部分。理想情况下,每个单独使用并且可以独立审查的部分应该是不同的罚单,而不是一个巨大的补丁炸弹。
为此,您可以将其他票据(或其他本地分支机构)的分支机构合并到当前分支机构中。这称为合并,它所做的只是将来自其他分支的提交包含到当前分支中。特别是,当一个新的Sage版本发布时,这是完成的:完成的票证与Sage master合并,结果是下一个Sage版本。Git足够聪明,不会合并两次提交。特别是,可以合并两个分支,其中一个分支已经合并了另一个分支。合并的语法很简单:
[user@localhost sage]$ git merge other_branch
这将创建一个新的“合并”提交,将当前分支和 other_branch
.
警告
应该避免双向合并分支。一旦合并了B和B合并了A,就没有办法区分最初在A或B中进行的提交。实际上,合并这两种方式合并了分支,使单独的审查变得不可能。
在实际操作中,只应在满足以下条件之一时进行合并:
如果两个票证发生冲突,则必须将其中一个合并到另一个中才能解决合并冲突。
或者你肯定需要一个作为另一个分支开发的特性。
合并的一个特例是在 develop
分支机构。这使您的本地分支机构最新的Sage版本。不过,上述针对不必要合并的警告仍然适用。尝试使用最初使用的Sage版本进行所有开发。合并的唯一原因 develop
分支是指您需要一个新功能或分支发生冲突时。看到了吗 将分支更新到最新的SageMath版本(并最小化重新编译时间) 有关详细信息。
合作与冲突解决¶
交换分支¶
通过多次重复上述步骤,很容易进行协作。例如,Alice启动一个罚单并添加一些初始代码:
[alice@laptop sage]$ git trac create "A and B Ticket"
... EDIT EDIT ...
[alice@laptop sage]$ git add .
[alice@laptop sage]$ git commit
[alice@laptop sage]$ git trac push
trac票据现在将“Branch:”设置为 u/alice/a_and_b_ticket
. Bob下载了这个分支,并在上面做了更多的工作:
[bob@home sage]$ git trac checkout TICKET_NUMBER
... EDIT EDIT ...
[bob@home sage]$ git add .
[bob@home sage]$ git commit
[bob@home sage]$ git trac push
trac票据现在将“Branch:”设置为 u/bob/a_and_b_ticket
,因为鲍勃不能写信给 u/alice/...
. 现在这两位作者只是拉/推他们的合作:
[alice@laptop sage]$ git trac pull
... EDIT EDIT ...
[alice@laptop sage]$ git add .
[alice@laptop sage]$ git commit
[alice@laptop sage]$ git trac push
[bob@home sage]$ git trac pull
... EDIT EDIT ...
[bob@home sage]$ git add .
[bob@home sage]$ git commit
[bob@home sage]$ git trac push
他们也不需要在他们的远程分支上进一步提交Bob和他们自己的分支。只要它们的更改不冲突(同时编辑相同的行),就可以了。
冲突解决¶
如果存在重叠编辑,则会发生合并冲突,这是分布式开发不可避免的后果。幸运的是,使用git解决这些问题很常见,也很容易。作为一个假设性示例,请考虑以下代码片段:
def fibonacci(i):
"""
Return the `i`-th Fibonacci number
"""
return fibonacci(i-1) * fibonacci(i-2)
这显然是错误的;两个开发人员,即Alice和Bob决定修复它。首先,在树林中远离任何互联网连接的小屋中,Alice校正种子值:
def fibonacci(i):
"""
Return the `i`-th Fibonacci number
"""
if i > 1:
return fibonacci(i-1) * fibonacci(i-2)
return [0, 1][i]
并将这些更改转换为新的提交:
[alice@laptop sage]$ git add fibonacci.py
[alice@laptop sage]$ git commit -m 'return correct seed values'
但是,由于没有internet连接,她无法立即将更改发送到trac服务器。同时,Bob将乘法改为加法,因为这是正确的递归公式:
def fibonacci(i):
"""
Return the `i`-th Fibonacci number
"""
return fibonacci(i-1) + fibonacci(i-2)
并立即上传他的零钱:
[bob@home sage]$ git add fibonacci.py
[bob@home sage]$ git commit -m 'corrected recursion formula, must be + instead of *'
[bob@home sage]$ git trac push
最后,爱丽丝回到了文明社会。在她的邮箱里,她发现了一封trac通知邮件,Bob已经将进一步的变更上传到了他们的联合项目中。因此,她一开始就把他的变化转移到她自己的本地分支机构:
[alice@laptop sage]$ git trac pull
...
CONFLICT (content): Merge conflict in fibonacci.py
Automatic merge failed; fix conflicts and then commit the result.
文件现在如下所示:
def fibonacci(i):
"""
Return the `i`-th Fibonacci number
"""
<<<<<<< HEAD
if i > 1:
return fibonacci(i-1) * fibonacci(i-2)
return [0, 1][i]
=======
return fibonacci(i-1) + fibonacci(i-2)
>>>>>>> 41675dfaedbfb89dcff0a47e520be4aa2b6c5d1b
冲突显示在冲突标记之间 <<<<<<<
和 >>>>>>>
. 上半场(直到 =======
马克)是爱丽丝的当前版本,下半部分是鲍勃的版本。第二个冲突标记后面的40位十六进制数是这两个标记的最新公共父级的SHA1哈希。
现在Alice的工作是通过协调更改来解决冲突,例如通过编辑文件。她的结果是:
def fibonacci(i):
"""
Return the `i`-th Fibonacci number
"""
if i > 1:
return fibonacci(i-1) + fibonacci(i-2)
return [0, 1][i]
然后上传她的原始更改 and 她对trac的合并承诺:
[alice@laptop sage]$ git add fibonacci.py
[alice@laptop sage]$ git commit -m "merged Bob's changes with mine"
结果提交图现在有一个循环:
[alice@laptop sage]$ git log --graph --oneline
* 6316447 merged Bob's changes with mine
|\
| * 41675df corrected recursion formula, must be + instead of *
* | 14ae1d3 return correct seed values
|/
* 14afe53 initial commit
如果鲍勃决定在票子上做进一步的工作,那他就得把爱丽丝的零钱拿出来。然而,这一次他并没有冲突:git下载了Alice的冲突提交和她的解决方案。
复习¶
有关审阅者应检查哪些内容的说明,请参阅 审阅者的检查表 .
如果你去 web interface to the Sage trac development server 然后,您可以单击“Branch:”字段并查看通过合并票据的所有提交而添加的代码。这是需要检讨的。
这个 git trac
命令提供两个可能很方便的命令(replace 12345
如果您不想使用web界面:
git trac print 12345
直接在终端中显示trac票证。git trac review 12345
从票证下载分支,并显示正在添加的内容,类似于单击“branch:”字段。
要在最少的重新编译的情况下检查票据,请首先构建“develop”分支,即最新的beta版本。只要签出一个旧的记录单,很可能会将Sage树重置为旧版本,因此您必须编译旧版本的包才能使其正常工作。相反,您可以使用以下命令创建票据和开发分支的匿名(“分离头”)合并:
$ git trac try 12345
这只会触及真正被票证修改的文件。特别是,如果只有Python文件被罚单更改(这对于大多数罚单都是这样),那么您只需运行 sage -b
重建Sage类库。如果更改了Python以外的文件,则必须运行 make
. 完成审阅后,只需签出一个命名分支,例如:
$ git checkout develop
如果要编辑票据分支(即添加其他提交),则不能使用 git trac try
. 你必须 检查现有的票据 以实际的票务分公司为起点。