87

Prior to NuGet, it was common accepted 'best practice' to check-in all external DLLs used on a project. Typically in a Libs or 3rdParty directory.

When working with NuGet, am I supposed to check-in the packages directory, or is there a way for MSBuild to auto download the needed packages from the nuget feed?

casperOne
  • 73,706
  • 19
  • 184
  • 253
Scott Weinstein
  • 18,890
  • 14
  • 78
  • 115
  • 2
    The answer to this a matter of opinion. The "exclude/No" camp maintains that because the provided feature set makes it easy during development and build to just pull from the package repository (e.g. nuget.org), it can just be done at build time. The "include/Yes" camp maintains that the code wouldn't build without the packages should the external repository become unavailable. Read both sides before making a decision. Also see: http://softwareengineering.stackexchange.com/questions/301547/should-we-include-nuget-package-folder-in-version-control – CJBS Oct 21 '16 at 18:17

7 Answers7

68

No

Since this question was asked there is now an easy workflow to use NuGet without commiting packages to source control

From your package manager console you need to install the 'NuGetPowerTools':

Install-Package NuGetPowerTools

Then to enable your projects to support pack restore you need to run another command:

Enable-PackageRestore

Now you are ready to commit your code base without the packages folder. The previous command changed your project files so that if packages are missing they get automatically downloaded and added.

Source

Using NuGet without committing packages to source control

Edward Wilde
  • 25,967
  • 8
  • 55
  • 64
  • 41
    As of NuGet-1.6, you no longer need NuGetPowerTools to do this. Simply right click on the Solution in Solution Explorer and choose, `Enable NuGet Package Restore`. See [the docs](http://docs.nuget.org/docs/workflows/using-nuget-without-committing-packages). – Kaleb Pederson Feb 16 '12 at 16:48
  • 1
    OK, I understand by following these steps I do not have to check in the `packages` folder anymore. What about the `.nuget` folder this creates? Do I have to check that in? – Christian Feb 05 '13 at 14:13
  • 3
    Yes, you must check in the .nuget folder and files underneath it. – absynce Mar 05 '13 at 18:57
  • 11
    @Edward - Philosophically, why wouldn't you include NuGet packages in source control given that they are dependencies? What's checked into source control should be 100% of the code sufficient for a build. By not including NuGet packages there are external dependencies created, eg. what if the package download location changes, or for some odd reason it is no longer available, etc. Or more likely what if there is some slight change to the package that is later re-downloaded and it breaks the build? That would have been avoided if everything needed to build the project was in source control. – Howiecamp Jul 16 '14 at 18:13
  • 1
    @Howiecamp totally agree with your points. It's a risk you take. However the pay off is smaller faster source control repositories without lots of binary assets – Edward Wilde Jul 17 '14 at 07:43
  • 5
    @Howiecamp I couldn't agree more. I don't understand the logic. I want source control to be a fully self contained system. Especially if the project is somewhat legacy and not accessed for a while. I want to come back and have it work with no modifications. Nuget is a single point of failure that I don't want to have. – Telavian Feb 05 '15 at 18:20
  • 1
    @Howiecamp - I also couldn't agree more. Having external dependencies to build my own code? You'd have to be crazy. Can't believe people are pushing this like it's a good idea. – Rocklan Feb 25 '15 at 23:10
  • @Howiecamp the reason is that DVCS systems (or maybe just git) can't handle big binary files. http://docs.nuget.org/consume/package-restore/msbuild-integrated – Andy May 28 '15 at 09:59
  • 1
    @Howiecamp I too agree. Checking in all your dependencies is an absolute necessity if you have a requirement that you need to be able to pull a specific release out of source control and be able to build an application that behaves exactly as the version originally released. – Mick Jul 20 '15 at 05:55
  • 1
    @Howiecamp I'm also with you on this. Having your build have a critical dependency on some server across the internet seems like a bad idea. You don't want to be in a position where you can't build a release because your internet connection is down or your CI builds start failing because the nuget repositories are off line. – 1adam12 Nov 05 '15 at 11:18
  • 2
    @Howiecamp Our solution is to host our own nuget server - and put all nuget packages, internal as external, into GIT-LFS. This removes the single point of failure and keeps everything nicely under version control. But we still do not checkin the packages folder - and we still use automatic package restore – Casper Leon Nielsen Mar 18 '16 at 14:14
  • @casper Great idea. There's obviously pros and cons to it but I like it overall. – Howiecamp Mar 20 '16 at 00:27
  • Hosting your own nuget server is a nice idea, but it is costly - there is no open source solution, and you can not guarantee that Microsoft will support nuget (or anything for that matter) in the future. You have to ask yourself the question that way too many developers appear to completely ignore - will my code be build-able for future maintenance engineers? – Malcolm O Jul 22 '19 at 21:24
30

Yes. Consider the "packages" directory to be equivalent to your "libs" directory that you mentioned in your question. This is the approach I personally take with my OSS projects.

We are investigating features that would allow MSBuild to auto download the needed packages, but that hasn't been implemented (as of NuGet 1.1).

I think some people may have already implemented such features on their own, but our plan is to look at having that feature built in to NuGet 1.2 or 1.3 hopefully.

Haacked
  • 58,045
  • 14
  • 90
  • 114
  • 10
    I'd definitely like to see that feature added. It would be nice to be able to have packages pulled down as necessary to a CI server or dev PC, so that you can avoid bloating the source control repository with third party DLLs. – John Mills Feb 13 '11 at 03:05
  • Should I check in all files? Or is it sufficient to only check in the dlls and the NuGet config (whatever it's called). – Rene Schulte Mar 20 '11 at 20:47
  • Safest to check in all files. If you ever need to uninstall the package, we need the original package so we can determine what changed. Also, when we do an upgrade, that's equivalent to uninstall followed by an install of the newer version. – Haacked Apr 27 '11 at 15:54
  • 2
    If package manager in visual studio and the command-line tool both could "repair Packages" that would be awesome. – Shaun Wilson Apr 30 '11 at 03:33
  • @Jose it's not required, but we recommend it for now for all the reasons discussed already. – Haacked May 17 '11 at 17:50
  • 1
    Perhaps it would be good to remove/edit this answer now it is obsolete – Lex Oct 28 '11 at 10:36
  • 1
    Is this answer still current? – Tim Post Nov 22 '11 at 08:46
  • 3
    @Tim answer is not current imho – Edward Wilde Nov 23 '11 at 11:15
  • 4
    This answer IS still current. Consider packages which are not in global repository (no way to repair/download them). IMHO it is good practice to store packages in versioning system. – Pavel Hodek Nov 06 '12 at 15:47
  • Having everything which is critical to build your application in source control sounds like a good idea to me. Packages are the exact same as libs, but they can hopefully be download online. They still are a critical dependency. – Telavian Feb 05 '15 at 18:23
7

Despite all the answers here, it is still a plain ole' horrible solution to not have all your dependencies under "some kind" of version control.

For GIT, this would mean GIT-LFS.

The recent episode with NPM shows why: If the internet repository of which you depend breaks, are unavailable etc., well then you're screwed aint you?

You are no longer able to build your stuff - and therefore not able to deliver.

Casper Leon Nielsen
  • 2,528
  • 1
  • 28
  • 37
  • 2
    This is a VERY good point. Even if we have our own internal NuGet server, can we rely on it to always be available during the build? Also, how often do our packages change that we'd always need to get a fresh copy for every build? – Josh P Apr 20 '16 at 15:53
  • `npm` broke because it didn't unlist packages, it actually deleted them. NuGet doesn't do this; if at any point you cannot access NuGet something is terribly wrong. I don't think that storing a craptonne of dependencies in git is a good solution: just lock your dependencies to a specific version and have a mirror in between you and in the internet if that matters to you. – Dan May 06 '16 at 07:31
  • 3
    "NuGet doesnt do this". Well hudiluhu you just made promises for the the future of a domain that is completely out of your control. In the real world things out of your area of control, well they are out of your area of control. This goes for NuGet, as well as Npm. Furthermore your idea of a "mirror" is exactly what I propose here, but in your world the "mirror" is not backed by any kind of version controlled scheme. Again you have not solved the problem you set out to. – Casper Leon Nielsen May 06 '16 at 12:20
5

Since asking the question, I've put in the following approach so that I do not have to check in the toplovel Packages directory.

In a toplevel build.msbuild file:

<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>

In each project.csproj file

<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>
Scott Weinstein
  • 18,890
  • 14
  • 78
  • 115
4

I realize the reality was different when this question has been originally posted and answered, but fortunately the answer changed a bit. It is now possible to use NuGet to download dependencies via MSBuild using a Pre-Build event. You don't need to put the packages folder in your code repository, all dependencies will be downloaded and/or updated on build. It may a workaround, but it looks decent enough. See the following blog post for details: http://blog.davidebbo.com/2011/03/using-nuget-without-committing-packages.html

Pawel Krakowiak
  • 9,940
  • 3
  • 37
  • 55
  • 4
    I was excited till I remembered that this requires the build server to access the NuGet repository, and this is not the only place I've worked at where the build servers can't see the internet. I'll just go back to checking the packages tree in... – piers7 Jul 27 '11 at 02:40
3

AS of 09/20/13, there is something called "Nuget Restore". You actually don't have to check in package folder if you wish to do so. (Especially if you are using DVCS)

Check out this: Using NuGet Without commiting packages to source control http://docs.nuget.org/docs/workflows/using-nuget-without-committing-packages

Matt W
  • 185
  • 1
  • 6
3

This post has become very outdated. The answer is still NO, but the solution has changed. As of NuGet 2.7+ you can enable automatic package restore without including the NuGet.exe file in your source (this is undesirable to say the least) and if you use any modern DVCS you can ignore the packages folder. If you need any special customizations you can create a nuget.config file in the solution root.

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

Also, with the new csproj format you can avoid the extra nuget.config files as well since that is integrated now. Please check out this post which explains that better:

Should .nuget folder be added to version control?

Jeremy
  • 843
  • 11
  • 16