SQL源代码管理(SoC)直接插入到SQL Server Management Studio (SSMS),其构建的唯一目的是在每个开发人员在SSMS的本地数据库工作副本和源代码管理存储库之间提供一个高效的接口。
它允许每个开发人员在他们自己的沙箱数据库上自由地工作,频繁地将测试过的变更提交到他们的本地,然后直接从SSMS内部提交到共享的团队存储库,以及频繁地用其他人的变更更新他们自己的工作。
但是,如果一个数据库开发人员更改了一个列的名称,而另一个团队成员更新了它的数据类型,会发生什么情况呢? 还是两个开发人员意外地在同一个存储过程上工作,做出了冲突的更改? 源代码管理系统将提醒团队注意冲突,并允许他们通过 合并 操作。
当需要解决冲突的变更时,在合并操作期间,一个好的策略是切换到专用于处理合并操作的工具,例如 无可比拟,或 KDiff3,两者都直接与SoC集成。
本文描述了在SQL源代码管理中合并冲突的一个简单示例。 您将需要安装超越比较,其中一个工具,与SQL源代码管理集成,以解决冲突。
当在同一个分支上工作的开发人员对共享存储库中的同一个版本的文件进行冲突性的更改时,人们将不得不执行合并来解决它。 类似地,在一个分支中工作的开发人员需要定期将他们的变更合并到主线中,并处理任何出现的冲突。 为了最大限度地减少这些冲突,以及对其他人工作的任何干扰,他们应该定期合并从主干到分支的相反方向的变化,这样两者就不会偏离太远。
在任一方向上的合并都可能是一个复杂的过程,尤其是当许多项目文件之间出现冲突时。 良好的团队沟通、良好的数据库开发实践以及模式的合理使用将有助于最大限度地减少合并冲突的数量和复杂性,但它们不会彻底消除冲突。
假设我们有两个开发人员,每个人都在开发同一个文件的本地副本 demo_db 数据库。 每个开发人员都使用SoC将他和她的数据库本地副本链接到本地Git存储库。 每个本地回购都有相同的来源, 我……e。 团队的共享报告,在本例中托管在Azure DevOps(以前的Visual Studio团队服务)上。 该设置与Sjors Takes在他的文章《如何使用GitHub和SQL源代码控制对数据库进行版本控制》中描述的非常相似,我将在那里查阅更多细节。
图1两个开发者都退出了共享回购,所以三个回购目前都在同一个版本中(比如R5)。 同样,每个人都用R5的变化更新了他们的本地沙箱数据库。
在分布式版本控制系统(VCS)中,每个用户都有一个本地存储库,可以在本地提交,然后从远程回购中“提取”最新的更改,并在必要时进行合并。 合并操作更安全,因为在合并失败的情况下,每个开发人员总是有他们本地的、提交的更改可以依靠。 合并操作包括一个本地提交和一个远程提交,我们需要创建第三个将两者结合起来的提交。 我们在本地提交合并版本,最后将合并版本推送到远程存储库。 如果合并失败,我们可以简单地再试一次。
不幸的是,SoC不支持这种模式。 假设两个开发人员都开始创建或修改存储过程, dbo。计算在本地,似乎对谁将编写新代码存在误解。
Dev1在上完成工作 计算 存储过程,并准备好共享他的更改。 他在本地提交更改,然后从远程获取,用在此期间所做的任何更改更新他的本地回购。 假设没有问题,他将他的更改推给远程回购。 他的本地和远程回购现在都在R6。
Dev2现在也在她的本地沙箱中完成了她的程序工作。 她再次承诺,将她的本地回购转移到R6,然后从偏远地区撤出。 此时,在SoC中,她将收到一个错误。
图2问题是现在基本上有两个互相矛盾的R6版本;Dev2的本地R6和共享远程的R6。 SoC无法处理这种情况,并邀请Dev2在外部Git工具中解决冲突。
开发者2可以打开她选择的工具,比如超越比较、KDiff3或者gmaster。 她需要从共享回购中提取最新的变更,其中包括与她在本地提交的变更冲突的已提交变更,提取操作将要求她合并本地提交和远程提交,以创建将两者结合的第三个提交(R7)。 然后,她可以在本地提交合并版本,最后,将合并版本推送到共享存储库。
值得重申的是,SoC既不是为了也不是为了处理分支和合数据同步 并而设计的;这方面有很多专用工具。 虽然可以使用超越比较来解决SoC中的简单合并冲突,但是这种集成是非常基本的,并且只是为了让您能够方便地直接在SSMS内部处理非常简单的合并。
它倾向于更好地适用于集中式源代码控制系统(如SVN),而不是分布式系统(如Git),并且合并过程更适合于集中式模型,即使是在使用Git的时候。
为了使它能够工作,开发人员必须采用从共享远程拉取的工作流程 以前 将他们在沙箱数据库中所做和测试的任何更改提交给他们的本地repo。
让我们回到之前的起点,两个开发者都退出了共享回购,所以三个回购都在R5。 Dev1在他的本地数据库中完成存储过程的工作,但是在本地提交之前,他使用 从远程存储库中提取在SoC中,用自他上次退出以来其他人所做的任何更改来更新他的本地回购。
这 推 和 拉 SoC中的按钮 犯罪 和 获取最新信息 选项卡,选项卡可能不工作。 这是TFS/VSTS/azuredvops托管的Git回购的一个已知问题。 它目前仅在您拥有VSTS/azuredvops的用户名/密码认证时有效。 大多数人使用活动目录或集成身份验证,这在目前根本不起作用。
我们将假设在此期间没有向远程提交任何更改。 完成后,他在本地提交更改,然后使用 推 把他们推进远程回购。 他的本地和远程回购现在都在R6,包含一个 计算 数到7的过程。
Dev2现在也在她的本地沙箱中完成了她的程序工作。 她的版本数到8。 同样,在本地提交新代码之前,她使用 从远程存储库中提取 得到任何改变。 使用这个过程,SoC检测到一个冲突,如图3所示。
图3在幕后,SoC已经立即将R6从远程服务器中拉出,并将她的本地报告更新为这个版本(从R5),因此现在包含一个 计算 计数为7的存储过程。 她现在需要解决这个版本和她本地沙盒数据库中的版本之间的冲突,沙盒数据库中的版本计数为8。
当然,这样做的缺点是,她的本地沙箱更改不能安全地在本地提交,所以如果合并操作出现问题,恢复到那个状态就不那么容易了。
如果她决定简单地接受远程报告中的修订,她可以选择 拿走他们的。 这 应用更改 按钮将被激活,她可以将该版本直接应用到她的本地数据库。 她的本地数据库和回购现在将有一个计数为7的程序,她以前的更改将丢失。
如果她决定保留她的版本,她可以选择 保留我的,然后切换到 犯罪 选项卡将她的新版本提交给本地repo(创建R7),然后她可以推送至远程。
然而,在这个例子中,假设Dev2在与Dev1讨论之后,决定了一个新版本的代码,其计数为9。 她点击了 合并。 按钮,SoC启动 无可比拟 帮助她解决冲突并创建新的合并文件。
图4显示了超越比较中的合并冲突。
图4左边的面板显示了她本地数据库中的冲突版本,右边的面板显示了她本地报告中的当前版本(与远程报告中的版本相匹配, 我……e. 他们都在R6)。 Dev2使用底部面板来创建新版本的代码,该版本的代码计数为9,并点击 保存文件 图标保存合并文件。
图5当你点击 救援在合并工具中,更改会立即应用到您正在使用的本地数据库中,这就是为什么当我们关闭超越比较并返回SSMS时,它会出现在演示的左窗格中,如图6所示。
图6请注意 保留我的 因为合并的版本不同于本地和远程repo中的版本。
她的本地沙箱中的存储过程现在将计数为9,她需要将该更改提交给她的本地repo,因此她切换到 犯罪 选项卡,并提交合并的文件。
图7Dev2可以做最后的检查,并决定是否要将合并的代码推送到共享存储库。
图8这将在远程代理中创建新的修订版,然后Dev2可以将它拉至本地代理,然后使用更新他的沙箱数据库 获取最新信息,然后 应用更改. 图9显示了远程回购中的新版本(在本例中是Azure DevOps)。 冲突解决了!
图9团队能够轻松地协调源代码控制操作,包括分支和合并的处理,这将对开发过程的速度和效率产生很大的影响。
在SSMS,SoC为本地和远程存储库提供了一个很好的接口,允许开发人员处理他们自己的本地数据库副本,并频繁提交更改。 有了好的实践,团队成员可以并行地在数据库上工作,而不用担心会造成彼此的干扰。 但是,当出现合并冲突时,最好使用为该任务构建的合并工具来解决它们。
我喜欢SoC与超越比较合并工具的集成所允许的灵活性。 这意味着我可以从冲突双方获取组件,甚至添加额外的代码。 然而,鉴于我们失去了能够首先在当地作出承诺的安全网,而且 然后 合并,我仍然建议在SoC之外使用一个专用工具进行大多数合并操作。
想看更多关于如何使用SQL源代码管理的演示吗? 请查看雷德盖特大学的SQL源代码管理课程。