14

I am on a two-man team using Team Foundation Server for our source control. I started a new solution. For that solution I created several projects. In many of them I used NuGet to install AutoMapper and Unity. I then right clicked on the solution and selected "Add to Source Control". I then checked in the resulting pending changes.

The other person on my team did a get latest and all of the NuGet references are failing for him.

So, I figured I needed to add the packages folder. So I did that.

After I did that, the NuGet references are still failing (for him).

Also, when I try to add a NuGet Package to a file I get this error now:

Access to the path 'C:\src\MyPath\ToMySolution\packages\repositories.config' is denied.

I assume this is because the repositories.config file is now under source control (so it is read only until manually checked out).

So, here are my two questions:

  1. How or what do I check in so that the NuGet packages are valid for my coworker when he does a get latest?
  2. Is there a way to not have to manually check out the NuGet files when I need to use NuGet?

Am I doing this wrong? Or is NuGet not really meant for use with source control?

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Vaccano
  • 78,325
  • 149
  • 468
  • 850

6 Answers6

11

Edit 2014/03/31: The manual MSBuild-based package restore enablement is no longer needed, see also http://xavierdecoster.com/migrate-away-from-msbuild-based-nuget-package-restore.

Edit 2012/02/07: This is now a built-in feature of the NuGet vsix, called Enable Package Restore.

Obsolete Alternative

There is a NuGet package for that, it's called NuGetPowerTools. It adds two new commands to the NuGet Package Manager Console in Visual Studio, amongst which Enable-PackageRestore is the interesting one for you.

It will add a .nuget folder which contains nuget.exe, nuget.settings.targets and nuget.targets. When you run enable package restore, it will enumerate all projects in your solution and add an import nuget.targets statement in the project files (which are actually msbuild files themselves).

Whenever you build a project or the entire solution, nuget will fetch all packages for that project/solution, as defined in the packages.config file. This happens in a pre-build step.

So, in short:

  1. do not check-in packages
  2. do check-in the config files (repositories.config and packages.config files)
  3. use Enable Package Restore
  4. check-in the .nuget folder

Whenever someone gets the sources, whether that's another developer in the team or a build agent, the msbuild process will be instructed to fetch any required packages in a pre-build step.

Also, when the packages are not committed into TFS Source Control, you won't hit the read-only flag issues, or merge conflicts with binary files.

If you want, you can also check-out the underlaying reasoning for this approach on my blog.

Xavier Decoster
  • 14,580
  • 5
  • 35
  • 46
  • According to David Ebbo, **we don't need to store the entire [packages] folder** under version control. Please see his reply from Twitter. [https://twitter.com/#!/davidebbo/status/166707886003724290](https://twitter.com/#!/davidebbo/status/166707886003724290) – stun Feb 07 '12 at 17:27
  • Technically, he's right, although I would consider this a useful piece of metadata for let's say generating a NuGet dependency matrix, having an overview of which VS Solution Projects have NuGet dependencies (and which not), or even keeping track of who introduced the first NuGet package dependencies to a project (or removed all). It's not a big file to keep track of, at almost zero cost, with potential for some benefits. Only a matter of having your ignore files set up (once) or workspace initialized properly. – Xavier Decoster Feb 13 '12 at 10:50
  • Maybe you should first ask yourself why you still have to deal with shared external library projects? There is indeed a link with packaging and a proper release process. – Xavier Decoster Apr 18 '12 at 15:47
  • 1
    Small update: As of nuget 2.7 enabling package restore is 'obsolete' (http://blog.davidebbo.com/2014/01/the-right-way-to-restore-nuget-packages.html). When building from visual studio this happens automatically. When running from the command line (with msbuild) you should run 'nuget restore' manually. – Jaco Mar 31 '14 at 14:40
5

Don't check the packages folder in.

Add the following prebuild event to your project:

$(SolutionDir)build\nuget install $(ProjectDir)packages.config -source \\server\path\NuGetPackages -o $(SolutionDir)packages

Omit -source parameter if not using custom packages.

nuget.exe is checked into $(SolutionDir)build\nuget.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
BNL
  • 7,085
  • 4
  • 27
  • 32
  • 1
    This is nice, but I am architecting a large enterprise SOA Solution that must be highly modular. Because of that it has many projects (11 currently). And over time it will have many more (at least 10). Also, I will be making several Prism apps and those have a lot of projects in them as a matter of course. While what you suggest will work (and I will keep it as a backup plan), it will necessitate a manual step that must be remembered and performed on every project (by other developers). It would be really great if there were a One Time fix for this problem. – Vaccano Aug 10 '11 at 21:16
  • Packages can be updated at the solution level through the UI. I don't see a way do do it globally from the command line though. http://docs.nuget.org/docs/release-notes/nuget-1.4#Managing_Packages_at_the_Solution_Level – BNL Aug 11 '11 at 00:33
  • 2
    Creating the project is a manual step. Deciding to add the nuget package dependency is a manual step. Committing is a manual step. Getting latest is a manual step... it's all a manual step. – Ryan Cromwell Aug 11 '11 at 02:26
  • 1
    You could write a batch file to loop over all packages.config files in your solution and run the above command on them. – BNL Aug 11 '11 at 10:51
  • 1
    Just have your pre-build step check for the existence of the packages folder off the solution directory first. That way, they'll only pay the tax on the first build. – Jim Lamb Aug 11 '11 at 12:57
1

I have this issue also. I like the idea of NuGet restore, but I don't feel I should need it. I want my JR developers to be able to check out a solution and have everything they need.

So I put my packages folder under source control.

My solution to enabling NuGet in this circumstance was to take note of this from above:

"I assume this is because the repositories.config file is now under source control (so it is read only until manually checked out)."

I opened the repositories.config file and added a blank line. Then I added the NuGet packages I need. Problem solved.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Holt Mansfield
  • 119
  • 2
  • 2
1

I always check in just the packages.config folder and use a Rake task that the developer (and build server) can use to update packages locally.

The task looks like:

def nuget_for_project(project_dir)
  sh "tools\\NuGet.exe " +
    "i Source\\#{project_dir}\\packages.config " +
    "-o Source\\Packages"
end

namespace :nuget do
  desc "nuget for servicebus"
  task "ServiceBus" do
    nuget_for_project "SampleProject.ServiceBus"
  end

  desc "nuget for web"
  task "Web" do
    nuget_for_project "SampleProject.Web"
  end

  desc "nuget for all"
  task "all" => ["nuget:ServiceBus", "nuget:Web"]
end

Note that the above script uses a local version of NuGet.exe that is in a tools folder checked into source control.

You could write this for MSBuild or NAnt instead.

I wrote a longer blog post on this a while back that may be helpful.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Tim Hoolihan
  • 12,316
  • 3
  • 41
  • 54
0

I must give a shout-out to this article: http://www.jsinh.in/2013/11/enable-nuget-package-restore/ It describes exactly what to do and why.

The notion of versioning various packages may be required for some systems to maintain build consistency, however, if the packages.config file is version controlled and the package can be downloaded, then the build can take place at any time without versioning the actual package contents themselves. Caution: The builder of the package, could without your knowledge, add items to an older build.

Rare, but possible.

For example, a package of 'abc.package' at version 2.0.2 is built into your project. You do not version the 'abc.package' but do version the packages.config. A few months later you need to add a bug-fix to the build you made a few months back. You get the items out of version control. Visual Studio downloads version 2.0.2 of 'abc.package', but since your last build, the developer of the package inserted or fixed some code. This new code may behave differently in your application.

So, there are good reasons to version control the packages!

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
PCPGMR
  • 340
  • 2
  • 7
0

Just in case this helps anyone, my solution to this was very simple:

  1. Opened the target file in Notepad++
  2. In the edit menu, all the way at the bottom, click Clear Read-Only Flag
  3. Save the file
  4. Profit

This works for me on a solution with, at the time of this writing, 39 projects.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
CaptainMarvel
  • 417
  • 4
  • 19