您现在可能已经知道,Plastic SCM 是一个功能齐全的 DVCS(分布式版本控制软件)。而且,Plastic SCM 也使用 Git 网络协议。
Plastic SCM 能够将更改直接推送和拉取到任何远程 Git 服务器。这是因为 Plastic 支持通过 https:// 和 git:// 协议来推送和拉取变更集。
此功能立即将 Plastic SCM 转变为与 Git 完全兼容的 DVCS。这一优势意味着您可以在工作站上使用 Plastic 或 Git,并且仍然可以参与 Git 项目(GitHub、CodePlex 等等)。
这可以是第一种方法:GitSync 是连接到 GitHub 的本机 Windows DVCS。因此,它实际上会将 Plastic SCM 变成成熟的 Windows Git 客户端。
假设您是一名使用 GitHub(或 Bitbucket,或 CodePlex)的开发者。无论如何,总有一些方面是您喜欢的:使用基于 Cloud 的存储库存储您的代码,使用 Windows 进行开发。也有您不喜欢的一些方面:被迫使用 CLI,缺乏非常棒的 GUI 工具。
因此,您希望拥有一切:Cloud 存储库、DVCS 功能和适用于 Windows 的出色工具。
使用 GitSync,您就能获得这些。
GitSync 的功能如下:
由于一张图胜过千言万语,那就让我们一步一步,完成整个的推送和拉取过程。
您有一个 Git 仓库,然后您将其拉到 Plastic 上。结果,您将获得一个精确的克隆,其中位于 Git 中的分支和提交现在已转换到 Plastic,而这个过程中最出色的地方在于能够在分支资源管理器中进行呈现:
下一张图显示了在 Git 端创建新提交时会发生什么,以及从 Plastic SCM 进行的拉取如何检索该提交。
该图不只是执行简单的更改,而且显示了从 big_feature 分支到 master 的合并。Plastic SCM 中的结果模拟了 Git 端发生的情况,并在 Plastic 分支资源管理器上添加了合并链接(呈现为绿线):
下一步是在 Plastic SCM 中执行更改并将更改推送到 Git。为了创建更完整的示例,我们不仅会创建新的变更集,还会执行合并。
变更集 6 和 7 在 Plastic 端创建,然后推送到 Git。如下图所示,合并信息(Git 存储库上的多个父级)也会从 Plastic 发送到 Git。
到目前为止,更改是在一端或另一端进行的,但不是同时在两端进行的。
下图显示了当开发者同时在同一个分支上工作时会发生什么情况。在 Git(绿色)中创建了一个新提交,在 Plastic(橙色)中创建了另一个新提交:
如果 Plastic 开发者尝试推送到 Git,则会出现错误,因为存在冲突性更改(在纯 Plastic 或纯 Git 环境的类似场景中会发生相同的情况)。需要遵循的步骤如下:
在交互结束时,两个存储库将看起来相同,并允许开发者在两端协同工作。
GitSync 配置文件 (gitsync.conf
) 允许您包含将在 GitSync 操作期间自动使用的信息。
这些信息与两个 Plastic SCM 和 Git 对象之间的映射有关:
gitsync.conf
文件必须位于:
plastic4
目录中(Linux/Mac 系统上的 $HOME/.plastic4
下或 Windows 上的 C:\Users\user\AppData\Local\plastic4
下)。
在 gitsync.conf
文件中,我们可以定义 Plastic 和 Git(电子邮件地址)之间的映射。提交到 Git 时,此信息将用作作者和提交者。
此信息用以下格式添加到 email-mapping
部分中:
plastic_user = git_email_address
以下是 gitsync.conf
文件的一个示例:
[email-mapping] asalim = asalim@mymailprovider.com ubuntu = ubuntu@linuxprovider.com
Git 子模块只是一个指针,指向其他存储库中的提交。它不会在子模块之间传播操作或处理存储库之间的分支,因此这些非常基本的信息足以满足子模块的工作需求。
Plastic Xlink 对象比 Git 子模块更复杂:Xlink 允许用户设置相关服务器、设置分支扩展规则,以及定义 Xlink 是否可写。
一般而言,我们可以说 Git 子模块和 Plastic Xlink 具有相同的目标:指向其他存储库中的提交。因此可以在以下两者之间建立直接映射:
GitSync 允许用户从 Git 子模块创建 Plastic Xlink,反之亦然。Git 子模块和 Plastic Xlink 可以使用 GitSync 进行同步:
请注意,在将存储库与 Xlink/子模块同步之前,必须同步目标存储库。
要将存储库与 Xlink/子模块同步,必须在 gitsync.conf
文件中添加映射信息。此信息用以下格式添加到 submodules 部分中:
git_repository_url -> plastic_repository_spec [writable:true|false] [relativeserver:true|false]
writable:true
的形式包含 writable
字段。如果 writable
字段被省略或设置为 false,则 Xlink 将创建为只读。relativeserver:true
的形式包含 relativeserver
字段。如果 relativeserver
字段被省略或设置为 false,则会针对 Plastic 存储库服务器创建 Xlink(作为非相对 Xlink)。以下是一个有效的配置示例:
[submodules] git://localhost/code -> code@localhost:8084 writable:true relativeserver:true git://localhost/doc -> doc@localhost:8084 writable:false relativeserver:true
使用 GitSync 时,有两个 Git 操作受到限制:
rebase
命令merge
(fast-forward) 命令这些 Git 命令不会考虑您的更改历史记录。尽管用户可以并行工作,Git 展示的历史记录却是接近线性的。但是,Plastic 会优先考虑保留更改历史记录。
Plastic SCM 会考虑您所做的更改的完整历史记录。这意味着 Plastic 不会改写历史记录。我们并不反对这种方案,这是一项设计决策,一种哲学。
在处理分支和合并时会反映出更改历史记录。由于 Plastic SCM 能够解决并显示历史记录,我们建议您在使用 GitSync 时避免使用这些 Git 命令。
Plastic 具有分支资源管理器,可让您以图形方式了解正在发生的情况。这样就不会分心,也不会错过变基。
对具有多个合并的分支进行差异比较时,很难分辨出在分支上真正进行的更改,以及合并带来了什么... 这一问题也在 Plastic 中得到了解决:
正如我们之前了解到的,Plastic 可以使用原生 Git 和 https 协议直接进行与远程 Git 服务器之间的推送和拉取操作,其中包括 GitHub、BitKeeper、CodePlex 等知名站点。
当我们最初开发 Plastic SCM 与 Git 双向同步功能时,我们考虑了以下场景:
我们克服万难找到了解决方案:我们没有考虑使用某种中间脚本将更改从一个系统转换到另一个系统,也没有考虑进行快速导入/导出(这种方案会施加大量限制),而是选择将 Git 网络协议实现为 Plastic 中的一个层,这个层支持与 Git 之间的直接拉取和推送。
Plastic 使用 Git 协议启动与远程 Git 服务器的协商阶段,就像 Git 命令所做的那样。这是一个核心功能,而不是附加脚本。
正如我们所说,GitSync 实现了智能协议并且:
让我们首先连接到 GitHub 存储库。
现在,为了将该存储库拉取到 Plastic,我创建了一个存储库来“托管它”(也命名为 corefx)并转到最初为空的分支资源管理器,然后转到上下文菜单选项以启动与 Git 同步:
现在不需要凭据,因为我们只是从公共存储库进行拉取(克隆)。如果您需要推送,然后服务器会要求您是经过身份验证的用户,那么您就需要指定凭据。
假设本地 corefx 存储库是空的,它将计算需要从远程 GitHub 存储库拉取的变更集和分支,并将拉取它们:
为了拉取在 GitHub 端完成的新更改,您只需重新运行相同的命令:
cm sync corefx git https://github.com/corefx/corefx.git现在它只会计算和拉取在 Git 端所做的新更改(如果有)。
您目前正在将 Git 变更集和分支直接拉取到您的本地 Plastic SCM 存储库:
现在,只需右键单击任何变更集(Git 中的说法是提交),您将能够使用我们的内置差异比较系统查看差异:
现在您已准备好在 Plastic 中进行更多更改,无论是分支、合并还是任何其他操作。然后,重复相同的过程以同步到 Git(这将依次推送或拉取更改,如果并发更改是在同一分支上完成的,甚至会要求您在推送回 Git 之前解决合并问题)。
我们将把我们的 Plastic 存储库之一推送到 GitHub。您会看到此过程与前一个过程类似。
好的!让我们开始吧!
随即将启动“同步”对话框。
我们目前正在将 Plastic SCM 变更集和分支直接推送到我的 GitHub 存储库。
假设 GitHub dokancode 存储库是空的,GitSync 将计算它需要从 Plastic 存储库推送的变更集和分支,并将推送它们:
推送操作完成后,我们可以看到已导出对象的摘要:
现在我们已准备好使用 Plastic SCM 和 GitHub 这两端的存储库。我们将能够创建分支,进行更改... 以及通过拉取/推送再次同步。
在本章中,我们将向您展示如何在 GitHub 和 Plastic 端使用 dokancode 存储库,并应用一些基本操作。
现在我要在 master 分支上运行一些操作:
提交已经完成,现在我们准备好了在 Plastic 端查看它们。
我们在本指南中已经了解 GitSync 能够计算出另一端的更改,与远程服务器协商,并推送更改。
同步完成后:
现在我们可以继续在 Plastic 端执行更改。
我将在 scm005 分支上执行一些更改。此时,Git 端和 Plastic 端的内容相同。我们可以在两端检查这一点:
在此分支中,我将:
新的更改如下:
通过摘要可以知道,同步过程发送了一个分支中涉及的两个变更集:
如果您注意观察,就会发现 Plastic main 分支已映射到 Git master 分支。Plastic 上 main 分支的子分支也可能存在此类映射。这意味着会通过删除层次结构并将 / 替换为 -,将 Plastic 分支转换为 Git 分支。同样,当 Git 分支转换为 Plastic 分支时,此规则也有效:- 字符用于在 Plastic 中重新创建层次结构。
在前面的示例中,Plastic 分支 /main/scm005 将转换为 master-scm005。此外,master 下的 Git 分支 scm007 将转换为 /main/scm007:
- 字符也可以作为分支名称的一部分,如以下这些示例所示:
分支 - Git 端 | 分支 - Plastic 端 |
---|---|
master | /main |
master-fix-5.0 | /main/fix-5.0 |
master-fix-5.0-task1 | /main/fix-5.0/task1 |
由于 Plastic SCM 采用与 Git 相同的概念(DAG、提交、合并链接等),因此共享合并跟踪相当容易。可以在 Git 中进行合并,然后推送回 Plastic 中。在 Plastic 中进行合并也没有问题,甚至可以将合并链接推送回 Git 中。
我们最难处理的功能与“项的精准跟踪”相关;我们有这项功能,而 Git 没有。Plastic 有一个与每个文件和目录相关联的内部 ID。这意味着我们可以轻松处理大量 Git 难以跟踪的合并冲突(例如分歧移动,这对于 Plastic 来说易如反掌)。
在以下示例中,我们将看到使用 GitSync 时是如何处理合并跟踪的。
我们将创建两个新分支:
新分支已被推送,Git 端的合并跟踪如下所示:
现在我们将了解在 Plastic 端跟踪 Git 端的合并。
合并完成,现在我们要将这些更改拉取到远程 Git 存储库:
我们在工作原理一章中了解到,我们可以同时在 Plastic 和 Git 端进行更改。这意味着您可以处理这两个系统上的同一分支,并协调更改(操作方式与使用纯 Plastic 环境或纯 Git 环境类似)。
我们将了解如何使用 GitSync 和 Plastic 管理这种情况。
让我们首先回顾一下前面的一个示例。在 Git 端的更改一节中,我们在 GitHub 端进行了一些更改。以下是我所做的操作:
现在,我将在 Plastic 端执行一些更改:
更改完成后,我决定使用与 Git 同步操作来同步两个存储库:
同步完成后,有一条消息会告诉我们需要合并!
这是因为我们在 Git 和 Plastic 端的同一分支中都进行了一些更改。
在摘要中,我们将看到需要合并操作的分支是 main(或 master)分支:
这是事实:我们在 Git 端的 master 分支中应用了一些更改,在 Plastic 端的 main 分支中应用了另外一些更改。请注意,main 和 master 是同一个分支,但使用不同的名称(有关更多信息,请参阅 Git-Plastic 字典)。
如工作原理一节中所述,我们必须解决 Plastic 端的合并冲突。所以让我们来完成这一操作吧!
我们将看到即将合并的更改:
此操作完成后,两个存储库将完全同步。这意味着我们在这两端具有相同的内容。
GitSync 支持使用 SSH 协议与 Git 存储库同步。
SSH 协议允许您连接到远程服务器和服务并进行身份验证。
要使用此功能,必须满足以下要求:
SSH 代理现在会管理您的 SSH 密钥并记住您的密码短语。
现在可以使用 Plastic GUI 或 CLI,按照与通常使用 HTTP 协议相同的方式使用 GitSync。
让我们看一个示例。如果使用命令行,则必须相应地为 SSH 协议指定 URL:
$ cm sync rep2 git git@github.com:PlasticSCM/Myrepo.git而不是使用 HTTPS 版本:
$ cm sync rep2 git https://github.com/PlasticSCM/Myrepo.git