Question: I have a pip requirements file that changes during development.

Can `pip` be made to **uninstall** packages that do not appear in the requirements file as well as installing those that do appear? Is there a standard method?

This would allow the pip requirements file to be the canonical list of packages - an 'if and only if' approach.

**Update**: I suggested it as a new feature at <https://github.com/pypa/pip/issues/716>

Answer: 
The short answer is no, you can't do that with pip.
Stephen's proposal is a nice idea, but unfortunately it doesn't work
if you include only direct requirements in your file, which sounds
cleaner to me.

All dependencies will be uninstalled,
including even `distribute`, breaking down `pip` itself.

### Maintaining a clean requirements file while version tracking a virtual environment

Here is how I try to version-track my virtual environment.
I try to maintain a minimal `requirements.txt`, including only
the direct requirements, and not even mentioning version constraints where
I'm not sure.

But besides, I keep, and include in version tracking (say git),
the actual status of my virtualenv in a `venv.pip` file.

Here is a sample workflow:

---

setup virtualenv workspace, with version tracking:

```
mkdir /tmp/pip_uninstalling
cd /tmp/pip_uninstalling
virtualenv venv
. venv/bin/activate

```

initialize version tracking system:

```
git init
echo venv > .gitignore
pip freeze > venv.pip
git add .gitignore venv.pip
git commit -m "Python project with venv"

```

install a package with dependencies, include it in requirements file:

```
echo flask > requirements.txt
pip install -r requirements.txt
pip freeze > venv.pip

```

Now start building your app, then commit and start a new branch:

```
vim myapp.py
git commit -am "Simple flask application"
git checkout -b "experiments"

```

install an extra package:

```
echo flask-script >> requirements.txt
pip install -r requirements.txt
pip freeze > venv.pip

```

... play with it, and then come back to earlier version

```
vim manage.py
git commit -am "Playing with flask-script"
git checkout master

```

Now uninstall extraneous packages:

```
pip freeze | grep -v -f venv.pip | xargs pip uninstall -y

```

I suppose the process can be automated with git hooks, but let's not go off topic.

Of course, it makes sense then to use some package caching system
or local repository like [pip2pi](https://github.com/wolever/pip2pi)