如何在不同存储库中的多个解决方案之间共享源代码库?

时间:2017-04-02 03:26:34

标签: git visual-studio nuget-package projects-and-solutions

我有一个公共库,我想在几个解决方案之间共享,存储在不同的github存储库中。我们将共享库放在单独的GitHub存储库中并创建了nuget包,它可以安装在每个所需的项目/解决方案中。缺点是更改库中的代码涉及几个步骤(更改代码,推送到库存储库,创建nuget包,安装包)这很烦人。

我想使用git subtree创建带有库项目的子目录,并在我的解决方案中将其用作本地项目,并且可以轻松更改代码/测试/调试。 " Main"的开发人员解决方案将选择包含库作为二进制nuget包或作为子目录中的源项目。

问题:当我尝试git subtree时,我发现了一个问题:csproj文件包含对包文件夹的相对引用,它们位于不同级别,当包含在独立库解决方案中时包含在主要解决方案中。 在MyLib.sln中,路径为" .. \ Packages" ,但是在Main.sln中,路径应该是" .. \ .. \ Packages" 。
Main GitHub Repository(和OtherUserOfMyLib GitHub Repository(is))的结构:

Main.sln
LibSubfolder
-----------------| MyLib.sln
-----------------| MyLibSource
--------------------------| myLib.csproj
--------------------------| myLib code
-----------------| (expected Packages from lib solution)
Packages.  (From main solution)

MyLib GitHub存储库的结构:

MyLib.sln
MyLibSource
--------------| myLib.csproj
--------------| myLib code
Packages.  (From lib solution)

我尝试git subtree只从Lib库中复制MyLibSource子目录(这样可以使packages文件夹的相对位置相同)。不幸的是,我没有找到从另一个repo复制子目录的方法,后来支持将更改恢复到原始仓库。答案 Add subdirectory of remote repo with git-subtree有几个选项,但所有这些选项似乎只讨论了单向(拉)同步。 从我看来,git submodule和git subrepo不支持从源存储库复制子文件夹。

我错过了什么吗?任何人都可以建议,如何从库存储库复制到我的存储库文件夹的子文件夹,这将允许以后的双向(拉/推)同步?

我考虑的其他选项是更改packages文件夹的位置。但我不确定,为main.sln和MyLib.sln选择哪种路径是一致的。

第三种方法是不要在MyLib存储库中使用MyLib.sln;仅将存储库用作库源代码的主存储。而是在主存储库中创建MyLib.sln并使用它来构建NuGet包。我将能够使用MyLibSource项目的git子树拉/推送内容。 OtherUserOfMyLib存储库只是引用子文件夹中的项目,并在需要时调用git子树pull / push

Main.sln
MyLib.sln       ( locate in Main repository instead of MyLib repository)
LibSubfolder
-----------------| MyLibSource
--------------------------| myLib.csproj
--------------------------| myLib code
Packages

我的问题是尝试哪种方法:

  • 花时间试图找回一种方法来推回创建的git子树 子文件夹?
  • 尝试更改包文件夹的位置?
  • 保留解决方案以在存储库之外构建nuget包 有包(第3种方法)?
  • 其他什么?

我看过类似的问题 Best practice to share common libraries between solutions in .NETHow do you share code between projects/solutions in Visual Studio? 但没有找到令人满意的解决方案。

1 个答案:

答案 0 :(得分:1)

我能够使用git子树来共享公共存储库(例如源代码库)作为不同客户端解决方案(存储库)的子文件夹,并允许将更改推回共享存储库。

我们对c#库(Powershell psm模块的文件夹)使用类似的方法,考虑将其用于React jsx组件的收集。对于c#库,客户端存储库之一将构建NuGet软件包,任何喜欢引用NuGet软件包而不是源代码的解决方案都可以使用它。

如果需要包含一些开源github库的源代码(例如,如果我们希望在新版本发布之前进行更改),我们将使用相同的方法。

在每个应用程序存储库中,我们需要自定义两个批处理文件(对于每个公共存储库):subtreePull和subtreePush。

批处理文件示例(基于Add subdirectory of remote repo with git-subtree答案的选项4):
MyCommonLib-SubtreePull.cmd

@rem Template Pull and Push  are located in SubTreeCommands folder
@Rem from https://developer.atlassian.com/blog/2015/05/the-power-of-git-subtree
@set remoteBranch=master
@set RelativeTarget=src/MyApplicationProject/LibSource/MyCommonLib
@echo If you have errors "Working tree has modifications.  Cannot add." uncomment stash before command and stash apply after command
@REM git stash 
@rem run this command from the toplevel of the working tree 
@for /f %%i in ('git rev-parse --show-toplevel ') do set GitRoot=%%i
CD %GitRoot%
IF EXIST %RelativeTarget% (
set gitCmd=pull
) ELSE (
set gitCmd=add  
)
@rem if you want to have full history, do not include  --squash
git subtree %gitCmd%  --prefix %RelativeTarget% https://github.com/MyCompany/MyCommonLib.git %remoteBranch% --squash
@REM git stash apply
@pause

MyCommonLib-SubtreePush.cmd

@Rem from https://medium.com/@v/git-subtrees-a-tutorial-6ff568381844#.a2ne9vlve
set remoteBranch=master
@rem run this command from the toplevel of the working tree 
@for /f %%i in ('git rev-parse --show-toplevel ') do set GitRoot=%%i
CD %GitRoot%
git subtree push --prefix=src/MyApplicationProject/LibSource/MyCommonLib https://github.com/MyCompany/MyCommonLib.git  %remoteBranch%
@pause

在工作期间,您需要进行常规的git commit / git push来更改应用程序存储库中的更改,包括LibSource公共库子文件夹中的更改。

要同步公共库更改,请运行subtreePush / subtreePull命令。
请注意,建议subtreePush在库中进行重大更改后运行(例如在每个相关项目的末尾)。
subtreePull可由不同存储库中的不同人员完成,建议在存储库的主要工作之前运行(例如在项目开始时)。
子树的pull和push批处理都需要一些时间才能运行,但是您可以启动它们并执行其他任何操作。