【问题标题】:Checking in packages from NuGet into version control?将 NuGet 中的包签入版本控制?
【发布时间】:2011-06-26 02:37:04
【问题描述】:

在 NuGet 之前,签入项目中使用的所有外部 DLL 是普遍接受的“最佳实践”。通常在Libs3rdParty 目录中。

使用 NuGet 时,我应该签入 packages 目录,还是 MSBuild 有办法从 nuget 提要自动下载所需的包?

【问题讨论】:

  • 这个问题的答案见仁见智。 “排除/否”阵营坚持认为,因为提供的功能集在开发和构建过程中很容易从包存储库(例如 nuget.org)中提取,所以它可以在构建时完成。 “包含/是”阵营坚持认为,如果外部存储库变得不可用,则代码不会在没有包的情况下构建。在做出决定之前阅读双方。另见:softwareengineering.stackexchange.com/questions/301547/…

标签: version-control msbuild nuget


【解决方案1】:

这篇文章已经过时了。答案仍然是否定的,但解决方案已经改变。 从 NuGet 2.7+ 开始,您可以启用自动包还原,而无需在源中包含 NuGet.exe 文件(至少可以说这是不可取的),如果您使用任何现代 DVCS,您可以忽略包文件夹。如果您需要任何特殊自定义,可以在解决方案根目录中创建一个 nuget.config 文件。

http://docs.nuget.org/docs/reference/package-restore

此外,使用新的 csproj 格式,您还可以避免额外的 nuget.config 文件,因为它现在已集成。请查看这篇解释得更好的帖子:

Should .nuget folder be added to version control?

【讨论】:

    【解决方案2】:

    尽管此处提供了所有答案,但在“某种”版本控制下没有所有依赖项仍然是一个简单的可怕解决方案。

    对于 GIT,这意味着 GIT-LFS。

    最近与 NPM 的一集说明了原因:如果您所依赖的 Internet 存储库中断、不可用等,那么您是不是被搞砸了?

    您不再能够构建自己的东西 - 因此无法交付。

    【讨论】:

    • 这是一个非常好的观点。即使我们有自己的内部 NuGet 服务器,我们能否依赖它在构建期间始终可用?此外,我们的包多久更改一次,我们总是需要为每个构建获取一个新副本?
    • npm 坏了,因为它没有取消列出包,它实际上删除了它们。 NuGet 不这样做。如果在任何时候您都无法访问 NuGet,那就大错特错了。我不认为在 git 中存储大量依赖项是一个好的解决方案:只需将您的依赖项锁定到特定版本,并在您和互联网之间建立一个镜像(如果这对您很重要)。
    • “NuGet 不这样做”。嗯 hudiluhu 你刚刚对一个完全不受你控制的域的未来做出了承诺。在现实世界中,事情超出了您的控制范围,那么它们就超出了您的控制范围。这适用于 NuGet 和 Npm。此外,您对“镜像”的想法正是我在这里提出的,但是在您的世界中,“镜像”不受任何版本控制方案的支持。同样,您还没有解决您要解决的问题。
    【解决方案3】:

    截至 2013 年 9 月 20 日,有一种叫做“Nuget 恢复”的东西。如果您愿意,您实际上不必检查包文件夹。 (特别是如果您使用 DVCS)

    查看此内容:使用 NuGet 而不将包提交到源代码管理 http://docs.nuget.org/docs/workflows/using-nuget-without-committing-packages

    【讨论】:

      【解决方案4】:

      没有

      自从提出这个问题以来,现在有了一个简单的工作流程来使用 NuGet,而无需将包提交到源代码管理

      您需要从包管理器控制台安装 'NuGetPowerTools'

      Install-Package NuGetPowerTools
      

      然后,要使您的项目支持包还原,您需要运行另一个命令:

      Enable-PackageRestore
      

      现在您已准备好在没有包文件夹的情况下提交您的代码库。上一条命令更改了您的项目文件,因此如果缺少包,它们会自动下载并添加。

      来源

      Using NuGet without committing packages to source control

      【讨论】:

      • 从 NuGet-1.6 开始,您不再需要 NuGetPowerTools 来执行此操作。只需在解决方案资源管理器中右键单击解决方案并选择Enable NuGet Package Restore。见the docs
      • 是的,您必须签入 .nuget 文件夹及其下的文件。
      • @Edward - 从哲学上讲,既然 NuGet 包是依赖项,为什么不将它们包含在源代码管理中?检查到源代码控制的内容应该 100% 的代码足以用于构建。通过不包括 NuGet 包,会创建外部依赖项,例如。如果包下载位置发生变化,或者由于某种奇怪的原因它不再可用等怎么办?或者更有可能的是,如果稍后重新下载的包有一些细微的变化并且它破坏了构建,该怎么办?如果构建项目所需的一切都在源代码控制中,那本可以避免。
      • @Howiecamp 我完全同意。我不明白其中的逻辑。我希望源代码控制成为一个完全独立的系统。特别是如果该项目有些遗留并且有一段时间没有访问过。我想回来让它不加修改地工作。 Nuget 是我不想拥有的单点故障。
      • @Howiecamp 我们的解决方案是托管我们自己的 nuget 服务器 - 并将所有 nuget 包(内部和外部)放入 GIT-LFS。这消除了单点故障并使一切都很好地处于版本控制之下。但是我们仍然没有检查包文件夹 - 我们仍然使用自动包恢复
      【解决方案5】:

      自从提出问题以来,我采用了以下方法,这样我就不必检查 toplovel Packages 目录。

      在顶层 build.msbuild 文件中:

      <Target Name="NuGet">
          <ItemGroup>
             <NuGetPackage Include="*\packages.config" />
          </ItemGroup>
          <Exec Command='libs\NuGet.exe install "%(NuGetPackage.FullPath)" -o Packages'  />
      
          <!-- optional for project that has JavaScript content -->
          <CreateItem Include="Packages\*\Content\Scripts\*">
             <Output TaskParameter="Include" ItemName="NuGetJSFiles"/>
          </CreateItem>
          <Copy SourceFiles="@(NuGetJSFiles)" DestinationFolder="MainProj\Scripts\" OverwriteReadOnlyFiles="true" SkipUnchngedFiles="true" />
          <Delete Files="MainProj\Scripts\.gitignore" />
          <WriteLinesToFile File="MainProj\Scripts\.gitignore" Lines="%(NuGetJSFiles.Filename)%(NuGetJSFiles.Extension)" /
          <Delete Files="@(PostNuGetFiles)" />
      </Target>
      

      在每个project.csproj文件中

      <Target Name="BeforeBuild">
          <Error Condition="!Exists('..\Packages\')" Text="You must run &gt; msbuild build.msbuild to download required NuGet
      Packages" />
      
          <!-- optional for project that has JavaScript content -->
         <ReadLinesFromFile File="Scripts\.gitignore">
           <Output TaskParameter="Lines" ItemName="ReqJSFiles" />
         </ReadLinesFromFile>
         <Message Text="@(ReqJSFiles)" />
         <Error Condition="!Exists('Scripts\%(ReqJSFiles.Identity)')" Text="You must run &gt; msbuild build.msbuild to download required NuGet JS Package - Scripts\%(ReqJSFiles.Identity)" />
       </Target>
      

      【讨论】:

      • 这可行,但现在最好只使用内置的启用包恢复
      【解决方案6】:

      当这个问题最初被发布和回答时,我意识到现实有所不同,但幸运的是答案发生了一些变化。现在可以使用 NuGet 使用 Pre-Build 事件通过 MSBuild 下载依赖项。您不需要将包文件夹放在代码存储库中,所有依赖项都将在构建时下载和/或更新。这可能是一种解决方法,但它看起来足够体面。详情见以下博文:http://blog.davidebbo.com/2011/03/using-nuget-without-committing-packages.html

      【讨论】:

      • 我很兴奋,直到我想起这需要构建服务器才能访问 NuGet 存储库,而这并不是我工作过的唯一一个构建服务器无法访问 Internet 的地方。我会回去检查包树...
      【解决方案7】:

      是的。考虑将“packages”目录等同于您在问题中提到的“libs”目录。这是我个人在我的 OSS 项目中采用的方法。

      我们正在研究允许 MSBuild 自动下载所需包的功能,但尚未实现(从 NuGet 1.1 开始)。

      我认为有些人可能已经自己实现了这些功能,但我们的计划是考虑将这个功能内置到 NuGet 1.2 或 1.3 中。

      【讨论】:

      • 我绝对希望看到添加该功能。如果能够根据需要将包下载到 CI 服务器或开发 PC,那就太好了,这样您就可以避免使用第三方 DLL 使源代码控制存储库膨胀。
      • 如果 Visual Studio 中的包管理器和命令行工具都可以“修复包”,那就太棒了。
      • 也许现在删除/编辑这个答案已经过时了
      • @Tim 回答不是当前恕我直言
      • 这个答案仍然是最新的。考虑不在全局存储库中的软件包(无法修复/下载它们)。恕我直言,将包存储在版本控制系统中是一种很好的做法。
      猜你喜欢
      • 1970-01-01
      • 2019-08-22
      • 2019-04-07
      • 2016-07-21
      • 1970-01-01
      • 2018-04-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多