Skip to content


Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Emacs Lisp Perl Ruby Standard ML Python Makefile Other
branch: master

Fetching latest commit…

Cannot retrieve the latest commit at this time

Failed to load latest commit information.


Copyright (C) 2010-2011, 2014 Free Software Foundation, Inc.
See the end of the file for license conditions.

This branch contains the sources, deployment scripts, and auxilliary
files for the Emacs Lisp package archive (

This file explains the branch layout, how to add and edit packages,
and how to deploy the archive (either on, or a local copy
for testing purposes).


** admin/    -- scripts for administering the package archive.
** html/     -- HTML for the website.
** packages/ -- source code for the packages.


** Contents of the packages/ directory:
This directory holds the package sources, with one subdirectory for
each package.

Each directory in here corresponds to a package, which can be
either a single-file package or a multifile package.

A nightly cron job refreshes the GNU ELPA archive from this repository.

This cron job only creates a new package when the "version" (as specified in
the "Version:" header) of a package is modified.  This means that you can
safely work on the next version here without worrying about the unstable
code making it to GNU ELPA, and simply update the "version" when you want to
release the new code.

** To add a package:

*** Add a simple (1-file) package as packages/NAME/NAME.el.

The file needs to follow the usual coding conventions (most importantly
start with ";;; <file> --- <description>") and have a "Version:" and
"Maintainer:" pseudo-header.

*** Add a multi-file package as a directory, packages/NAME.

It needs to have a file named packages/NAME/NAME.el which follows the same
rules as above.

*** Commit your changes the usual way ("git add", "git commit", etc).

Changes in the Git repository do not immediately propagate to the
user-facing archive (what users see when they do `M-x list-packages').
That is done by deploying the archive, which happens automatically
once a day, and the changes are only reflected when the "Version:"
header changes.

** Format

Each package should follow the ELPA packaging conventions, but there are
some differences due to the way the deployment script creates the packages
and the web-pages from this source code:
- Multi-file packages put the package metadata in the main <pkg>.el file
  in the format used for single-file packages: the <pkg>-pkg.el file is
  auto-generated from it.
- Every package should have both a "Version:" *and* a "Maintainer:".
- the "URL:" header can be used to specify the home page
  of the package, if it's maintained externally.
- A "News:" section (or "NEWS" file) can/should be used to list the
  user-visible changes of each version.
- The "Package-Type:" header can be used to force the type of package
  created (can be either `simple' for single-file packages or `multi' for
  tarballs).  By default the type is decided based on whether there are
  several Elisp files in the source.
- If you want some files to not be included in the tarball, you can
  put a `.elpaignore' file in the root of your package directory, where you
  can list patterns of files to ignore (this file is passed to tar's -X).

** External branches

Some packages are maintained in external branches.  These should be
appropriately listed in the `externals-list' file.
There are two different cases: subtrees and externals.

In both cases, a copy of the code is kept in the `elpa' repository and
should be sync'd with the upstream every once in a while.  This copy may
include local changes, tho ideally these should be kept to a minimum.

In the `subtree' case, the copy of the code is kept here in the
corresponding `packages/<pkg>' directory.  You should be able to "git
merge -s subtree" from the upstream branch.

In the `external' case, the copy of the code is not kept here but in the
`externals/<pkg>' branch in the `elpa' repository.

You can check out all the external packages into the `packages' directory
with the command:

   make externals

You can check out a specific external PACKAGE into the `packages'
directory with these commands:

   cd packages
   git clone --reference .. --single-branch --branch externals/PACKAGE $(git config remote.origin.url) PACKAGE

If you already have a packages/PACKAGE directory with a previous
checkout, you can update it like this:

   cd packages/PACKAGE
   git pull

** Public incubation

If you want to develop a package publicly prior to its first release (to
benefit from others' feedback, primarily), but not in an external repo,
you have 2 choices:
- you can simply put "Version: 0" to indicate that this should not be
  released yet.
- or you can push to an "ephemeral" branch -- subject to rebase and eventual
  removal upon finishing merge -- for the duration of the incubation.


** To install all the packages "in place":

   make externals

This compiles and generates autoloads for all the packages in the
packages/ directory.  You can then add that directory, e.g. with:

(eval-after-load 'package
  '(add-to-list 'package-directory-list ".../elpa/packages"))

** To deploy the package repository as a remotely-accessible archive:

   git clone .../elpa
   mkdir build
   cd build
   (cd ../elpa; git log --format=%H | tail -n 1) >.changelog-witness
   ln -s ../elpa/admin
   ln -s ../elpa/GNUmakefile

This deploys the packages to the staging/ directory (sibling of "build").
Unlike "make", this makes a full copy of the packages, tars up
multi-file packages, and doesn't byte-compile any files.

** To access a deployed archive

To access the archive via HTTP, have a symlink (say) /var/www/packages
pointing to DEST/packages, and set up Emacs with

  (setq package-archives '(("new-elpa" . "")))

You can also access the archive via normal file access.  Such "local
archives" are useful for debugging:

  (setq package-archives '(("local-elpa" . ".../elpa/packages")))

** Notes specific to

The way things are set up on this machine, we refresh the archive by
a cron job.  You can do it by hand by logging in (access set up by FSF
admins), and

   su elpa
   cd ~elpa/build

Which makes a full archive deployment, as discussed above.  The symlink
/var/www/packages points to the staging package directory under

The Org mode dailies are also fetched and added by the script
admin/, run as a cron job.

This file is part of GNU Emacs.

GNU Emacs is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

GNU Emacs is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with GNU Emacs.  If not, see <>.

Local variables:
mode: outline
paragraph-separate: "[ 	]*$"
Something went wrong with that request. Please try again.