Question: Sometimes, package updates from MELPA can break some part of emacs and when that happens I'd like to be able to revert back to using an older version of the package.

Right now, I can do it in two ways:

* I've set emacs to delete files by moving to trash and when I update a package, the older version is trashed. I can retrieve the older version and replace the one in `~/.emacs.d/elpa`.
* Go to the github repo of the package that broke functionality, fetch an older version of the package, replace the one in `~/.emacs.d/elpa` with the one from gitub, byte-recompile the file(s).

Both these ways involve a lot of manual work moving things around. Is there an easier(preferably automatic) way to downgrade packages installed from MELPA?

Answer: 
When you update your packages through the `M-x list-packages` interface, after the successful installation of the package, you'll get asked if you want to remove the old package. Don't delete them so they stay in place and you could then later remove the newer package through this interface.

My current package list shows 4 versions of magit installed in my ~/.emacs.d/elpa/ directory tree.

```
  magit              20160827.1549 obsolete              A Git porcelain inside Emacs
  magit              20160907.945  obsolete              A Git porcelain inside Emacs
  magit              20161001.1454 obsolete              A Git porcelain inside Emacs
  magit              20161123.617  installed             A Git porcelain inside Emacs

```

You can clean-up old versions later with the key `~` (package-menu-mark-obsolete-for-deletion) to mark all obsolete packages. To delete a certain old version move to its line and press `d` to mark them for deletion. After you marked the packages you'd use `x` to execute the actions as usual.

In **Emacs 25** the mark all packages for `U`pgrade functionality automatically sets all old packages for deletion, and doesn't prompt for confirmation after installing. You have to look for lines that start with a capital "D", which you can just unmark (best with the following macro)

Type the key or chord on the left of the dash from the following lines.

```
<F3>  - start macro recording
C-s   - isearch-forward
C-q   - quoted-insert
C-j   - linefeed character
D     - the mark at the start of the line
<Ret> - stops the isearch on the line with the "D"
u     - unmark the package for deletion
<F4>  - stops macro recording - the first package is now unmarked
<F4>  - executes the macro for the next upgraded package

```

If there are no further matches for the search the macro will ring the bell and stop, so you could `C-u 0 <F4>` to unmark all packages marked for deletion. After this you can e`x`ecute the installations.

The function I declared to be changed in my comment has to be changed in a way I cannot grasp yet, as it's important that the last (cond) block has to be successful in order to not loop endlessly.
I find an easy way to downgrade: managing your own melpa archive.

1. Clone [melpa](https://github.com/melpa/melpa) repo.
2. Follow [melpa's custom melpa archive wiki page](https://github.com/melpa/melpa/wiki/Custom-Melpa-Archive) to remove all recipes.
3. Find the commit of the package you want to down grade to, and create a new recipe with that commit for the package. (see [melpa's readme](https://github.com/melpa/melpa#recipe-format) about how to specify the commit)
4. Run `make` to build the downgraded package
5. Add your own melpa archive, which can be a local directory, to the `package-archives` list.
6. Install the downgraded package using the package menu. Or you can use `package-pinned-packages` to restrict the archive where the package should be downloaded from.