microsoft / microsoft/winget-cli

📌 Pin a directory (exclude folder from upgrades)

Open
#2,749 6 comments 4 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Issue-Feature
Dominant language
C++
Stars
26.4k
Forks
1.8k
Avg merge
1d 11h
Merged PRs (30d)
15

Description

This proposal is an extension of Pin a package (#476) by @denelon.

Description of the new feature / enhancement

Users should be able to "pin" not only packages, but also directories (exclude folders from winget upgrade --all).

This can come in handy in many different scenarios, especially:

  • Preventing conflicts between multiple package managers (Scoop, Chocolatey, etc).
    By pinning C:\choco or %PROGRAMDATA%\scoop winget upgrades will be disabled automagically for software installed through other means.

  • Preventing accidental upgrades within development environments.
    By pinning C:\Dev developers can install their tools safely and not worry about accidental upgrades from winget. Developers can even install multiple versions of same program using winget itself, without conflicts!

  • Excluding entire game drives.
    Games are installed and maintained through self-updating launchers (Steam, Epic, etc.). There are many reasons why users like to keep their game libraries, mods and launchers separate from the rest of their system. Those softwares are often installed on a dedicated game drive, physically separate from the rest of the system. Pinning a game drive, e.g. E:\ will automatically exclude all games and related software from unwanted updates and potential conflicts, including all future installs.


Proposed technical implementation details

The list of pinned packages and directories should be included in settings.json and should support the usage of default environment variables (%PROGRAMDATA%\scoop, $Env:SYSTEMDRIVE\MyApps, etc.) — making it easy to edit, export and import configuration.

When upgrade or list command is initiatied, Winget can simply check the settings file and either perform or not perform an action on certain packages by matching their name and containing directory against the list in settings.json. This can easily be achieved by an IF/ELSE expression.

PROPOSED COMMANDS
  • winget pin --directory "C:\MyApps" should exclude all applications installed into C:\MyApps and all of its subfolders from winget upgrade --all command.
  • winget unpin --directory "C:\MyApps" should unpin that directory, making all the applications installed into C:\MyApps and all of its subfolders upgradable using winget upgrade --all command.
  • winget list --pinned should list all pinned directories, plus packages that have explicitly been pinned using winget pin <package>. It should not list packages that haven't explicitly been pinned using winget pin <package>.

Remarks

  • winget [un]pin <package> should have prevalence over winget [un]pin --directory. Meaning that if an application has explicitly been (un)pinned using winget [un]pin <package>, it's pinned state should remain unchanged by pinning or unpinning it's containing directory.
  • If an application installed in a pinned directory is detected by winget list command, a user should still be able to update that particular application using winget upgrade <package> explicitly.
EXAMPLE
  1. User installs VSCode in C:\MyApps\VSCode manually (not using Winget).
  2. User installs Firefox in C:\MyApps\Firefox using winget install firefox --location "C:\MyApps\Firefox".
  3. winget upgrade --all upgrades both VSCode and Firefox.
  4. User pins VSCode using winget pin vscode.
  5. User pins C:\MyApps using winget pin --directory "C:\MyApps".
  6. winget list --pinned lists:
    C:\MyApps
    Microsoft Visual Studio Code
  7. winget upgrade --all upgrades neither VSCode nor Firefox.
  8. User unpins C:\MyApps using winget unpin --directory "C:\MyApps".
  9. winget list --pinned lists:
    Microsoft Visual Studio Code
  10. winget upgrade --all upgrades only Firefox.
  11. winget upgrade vscode upgrades VSCode.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by tracing the existing winget pin, unpin, list, and upgrade command entry points and how pinned packages are represented in settings.json. Define the directory-matching, environment-variable, precedence, and explicit-upgrade behavior, then add coverage showing that directory pins affect upgrade --all and list --pinned while explicit package pins remain effective.

Written by the indexing model from the issue text.

Assessment

Tech stack
cpp
Domain
cli, tooling
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.