艰难的路

如果您没有git经验,我们建议您阅读 与Git-Trac协同开发 而不是章。这个 git-trac 简化了与git和trac服务器的交互。

如果你只想用git来做贡献,那就对了。本章将告诉您如何做到这一点,假设您对git有一些基本的了解。尤其是,你应该读过 Sage开发过程 第一。

Randall Munroe提供了一个 basic overview .

我们假设您有Sage git存储库的副本,例如通过运行:

[user@localhost ~]$ git clone git://github.com/sagemath/sage.git
[user@localhost ~]$ cd sage
[user@localhost sage]$ git checkout develop
[user@localhost sage]$ make

注解

如果您的系统支持多处理,并且您希望使用多个处理器来构建Sage,请将上面最后一行替换为:

[user@localhost sage]$ MAKE='make -jNUM' make

告诉 make 要运行的程序 NUM 在建造Sage时并行作业。

Trac服务器

Sage-trac服务器还保存Sage存储库的副本,它通过ssh和git协议提供服务。要将其作为远程存储库添加到本地git存储库,请使用以下命令:

[user@localhost sage]$ git remote add trac git://trac.sagemath.org/sage.git -t master
[user@localhost sage]$ git remote set-url --push trac git@trac.sagemath.org:sage.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)

而不是 trac 当然,你可以用任何你想要的本地名字。有多个git远程存储库是非常好的,可以将它们看作书签。然后你可以使用 git pull 得到改变和 git push 要使用以下命令上载本地更改:

[user@localhost sage]$ git <push|pull> trac [ARGS]

注解

在上面的命令中,我们将遥控器设置为只跟踪 master trac服务器上的分支( -t master 选项)。这避免了混乱,因为不会自动下载曾经创建的所有分支。但这也意味着,默认情况下不会获取trac上的所有内容,并且需要显式地告诉git要从trac获取哪个分支。见 退票 部分为示例。

我们在这里设置远程以使用git协议执行只读操作(fetch)和使用ssh协议(由 git@ 部分)。要使用ssh协议,您需要有一个trac帐户并设置ssh公钥,如中所述 Trac authentication through ssh . 如果您想上传任何内容以确保它确实来自您,那么身份验证是必需的。

如果只想使用ssh,请使用以下命令:

[user@localhost sage]$ git remote add trac git@trac.sagemath.org:sage.git -t master
[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)

退票

已完成或正在处理的Trac票证可以附加git分支。这是票据描述中的“分支:”字段。分支名称的形式通常为 u/user/description 在哪里 user 是生成分支的用户的名称,并且 description 是一些自由格式的简短描述(可以包含更多斜杠)。

如果您想在远程分支中进行更改,则必须在远程分支中进行更改。特别是,git没有直接使用远程分支的概念,remote只是您可以从远程服务器获取的东西的书签。因此,您应该做的第一件事是将trac服务器的分支中的所有内容都放入本地存储库中。通过以下方式实现:

[user@localhost sage]$ git fetch trac u/user/description
remote: Counting objects: 62, done.
remote: Compressing objects: 100% (48/48), done.
remote: Total 48 (delta 42), reused 0 (delta 0)
Unpacking objects: 100% (48/48), done.
From trac.sagemath.org:sage
* [new branch]      u/user/description -> FETCH_HEAD

这个 u/user/description 分支现在临时存储在本地git数据库的别名下(直到您获取其他内容为止) FETCH_HEAD . 在第二步中,我们将它作为一个新的本地分支可用并切换到它。您的本地分支可以有不同的名称,例如:

[user@localhost sage]$ git checkout -b my_branch FETCH_HEAD
Switched to a new branch 'my_branch'

在本地git存储库中创建一个名为 my_branch 并将本地Sage文件系统树修改为该票据中文件的状态。现在可以编辑文件并将更改提交到本地分支。

将更改推送到罚单

要将本地分支添加到trac票证,您应该首先在Sage-trac存储库中决定一个名称。

有关git分支的读/写权限,请参阅 关于分支机构名称的说明

为了避免名称冲突,可以使用 u/your_username/a_description_of_your_branch (描述可以包含斜杠,但不能包含空格)。然后:

  • Fill 这个 Branch 具有该名称的trac票证字段。

  • Push 你的分支机构与trac的任何一个:

    [user@localhost sage]$ git push --set-upstream trac HEAD:u/user/description
    

    如果您自己启动分支而不遵循任何其他分支,或使用:

    [user@localhost sage]$ git push trac HEAD:u/user/description
    

    如果你的分行已经有一个上游分行。

在这里, HEAD 意味着您正在将当前本地分支的最新提交(以及其所有父提交)推送到远程分支。

这个 Branch trac票证上的字段可以显示为红色/绿色。看到了吗 售票区 学习它意味着什么。

正在获取更改

开发期间的一个常见任务是将分支的本地副本与trac上的分支同步。特别是,假设您下载了其他人的分支,并对trac票据提出了一些改进建议。现在,原始作者将您的建议合并到他的分支中,您希望获得添加的变更集来完成您的评审。假设你最初是在 退票 ,您只需发出:

[user@localhost sage]$ git pull trac u/user/description
From trac.sagemath.org:sage
 * branch            u/user/description -> FETCH_HEAD
Updating 8237337..07152d8
Fast-forward
 src/sage/tests/cmdline.py      | 3 ++-
 1 file changed, 2 insertions(+), 1 deletions(-)

现在在哪 user 是其他开发人员的trac用户名,并且 description 是他选择的一些描述。此命令将从最初使用的远程分支下载更改并将其合并到本地分支中。如果您还没有发布本地提交,那么您还可以通过以下方式对它们进行重新设置:

[user@localhost sage]$ git pull -r trac u/user/description
From trac.sagemath.org:sage
 * branch            u/user/description -> FETCH_HEAD
First, rewinding head to replay your work on top of it...
Applying: my local commit

合并和重基 部分,以深入解释合并与恢复基。

到目前为止,我们假设没有冲突。在分布式开发中,有时源文件中的同一位置被多个人更改是不可避免的。在这些冲突的编辑中进行了解释 冲突解决 部分。

正在更新主控形状

这个 master 可以像任何其他分支一样更新分支。但是,您的主分支机构的本地副本应该保留 完全相同的 到trac主分支机构。

如果意外地将提交添加到本地副本 master ,必须在更新分支之前删除它们。

确保通知您潜在问题的一种方法是使用 git pull --ff-only ,这将在需要非平凡合并时引发错误::

[user@localhost sage]$ git checkout master
[user@localhost sage]$ git pull --ff-only trac master

如果此拉操作失败,则主分支的本地副本有问题。要切换到正确的Sage主分支,请使用:

[user@localhost sage]$ git checkout master
[user@localhost sage]$ git reset --hard trac/master

合并和重基

有时,Sage的新版本会在您处理git分支时发布。

让我们假设你开始了 my_branch 提交时 B . 一段时间后,您的分支已经前进到提交 Z ,但你更新了 master (见 正在更新主控形状 )现在你的git历史是这样的(参见 历史 ):

      X---Y---Z my_branch
     /
A---B---C---D master

你应该如何处理这些变化?原则上有两种方法:

  • 回扣: 第一个解决办法是 重播 承诺 X,Y,Z 在新的 master . 这叫做 重碱 ,并重写当前分支:

    git checkout my_branch
    git rebase -i master
    

    根据提交图,这将导致:

                  X'--Y'--Z' my_branch
                 /
    A---B---C---D master
    

    请注意,此操作重写 my_branch (见 改写历史 ). 如果有人开始在提交的基础上编写代码,这可能会导致问题 X,Y,Z . 否则是安全的。

    替代地 ,您可以重新设置基址 my_branch 同时更新主机时(请参阅 正在获取更改 ):

    git checkout my_branch
    git pull -r master
    
  • 合并 你的分行 master 将在其中两个控件之上创建一个新的提交:

    git checkout my_branch
    git merge master
    

    结果是以下提交图:

          X---Y---Z---W my_branch
         /           /
    A---B---C-------D master
    
    • 赞成的意见: 你没有重写历史(见 改写历史 )。然后,可以轻松地将附加提交推送到git存储库并分发给您的协作者。

    • 欺骗: 它引入了一个额外的合并提交,如果您使用了rebase,就不存在了。

    替代地 ,可以合并 my_branch 同时更新主机时(请参阅 正在获取更改 ):

    git checkout my_branch
    git pull master
    

如有疑问 使用merge而不是rebase。风险较小,这种情况下的回扣只对历史悠久的分支机构有用。

最后, 除非有必要,否则什么也不做: 你的部门落后是很好的 master . 如果分支机构的名称在其trac页面上显示为红色,则始终可以合并/还原基(请参见 售票区 ),或当您真正需要仅在当前主控形状中可用的功能时。

合并工具

简单的冲突可以很容易地用git解决(参见 冲突解决

对于更复杂的项目,有一系列专门的项目可供选择。因为冲突标记包含最新公共父级的哈希,所以可以使用三向diff::

[alice@laptop]$ git mergetool

This message is displayed because 'merge.tool' is not configured.
See 'git mergetool --tool-help' or 'git help config' for more details.
'git mergetool' will now attempt to use one of the following tools:
meld opendiff kdiff3 [...] merge araxis bc3 codecompare emerge vimdiff
Merging:
fibonacci.py

Normal merge conflict for 'fibonacci.py':
  {local}: modified file
  {remote}: modified file
Hit return to start merge resolution tool (meld):

如果你没有喜欢的合并工具,我们建议你试试 meld (跨平台)。结果如下所示。

developer/static/meld-screenshot.png

中间的文件是最新的公共父文件;右边是Bob的版本,左边是Alice的冲突版本。单击箭头将标记的更改移动到相邻窗格中的文件。