(As mentioned in the next section you can use a location other than
~/.config/emacs (or ~/.emacs.d). Nevertheless most of the subsequent
examples just talk about ~/.config/emacs and if you use something
else, then obviously have to substitute that. The same applies to the
string lib and the variables user-init-file and user-emacs-directory,
which also might not be appropriate depending on your choices.)
To get started clone the repository of the emacs.g collective. A
"collective" is a starter-kit and/or configuration seed that relies on
Borg as the package manager. Most users end up using emacs.g merely
as a bootstrapping seed and do not merge upstream changes after that.
This collective already assimilates a few drones in addition to borg
itself, namely magit, epkg, use-package, auto-compile, git-modes and
diff-hl, as well as their dependencies. These drones are not required
by borg but their use is highly recommended.
Clone the emacs.g repository to either ~/.config/emacs, or for testing
purposes to any other location. This repository contains a Makefile
that imports lib/borg/borg.mk and defines an additional target whose
purpose is to make that file and lib/borg/borg.sh available. Run make
bootstrap-borg to clone the borg repository. That does not completely
setup borg but it makes the latest version of the mentioned files
available.
Now that these files are available you can run make bootstrap to get
and configure all submodules (including the borg submodule) and to
build all drones.
git clone git@github.com:emacscollective/emacs.g.git ~/.config/emacs cd ~/.config/emacs make bootstrap-borg make bootstrap
If you have assimilated many packages, you might want to use make
bootstrap | tee bootstrap.log.
The last command run during bootstrap is git submodule status, which
prints one line per module. If a line is prefixed with ‘+’, that means
that it was not possible to checkout the recorded commit, and - means
that the module could not be cloned. Even if some module could not be
cloned, that usually does not render a configuration unusable, so just
run emacs now, and then investigate any issues from the comfort of
Magit.
If you cloned to somewhere other than ~/.config/emacs, then you can
use that configuration using emacs --init-directory /path/to/emacs.g/,
provided you are using Emacs 29 or later. Otherwise you have to
resort to emacs -Q -l /path/to/emacs.g/early-init.el -l
/path/to/emacs.g/init.el.
For drones whose upstream repositories are located on Github or Gitlab
the emacs.g collective uses the ssh protocol by default, which is a
problem if you don’t have accounts there and have not properly setup
your keys. See Using https URLs.
During package compilation you may notice the submodules relating to
those packages become dirty due to the compilation outputs not being
ignored in those submodules. For this reason it is useful to ignore
these outputs globally, for example in your ~/.config/git/ignore
file:
*.elc *-autoloads.el dir
You may discover more things that you’ll want to ignore this way as
you use borg.
If you don’t want to base your configuration on the emacs.g
starter-kit described in the previous section, then you have
to do a few things manually.
git init ~/.config/emacs cd ~/.config/emacs
By default Borg installs packages inside the lib/ subdirectory, but
since you are starting from scratch, you may choose something else
by setting the Git variable borg.drones-directory locally for this
repository.
Then you should add a Makefile containing at least:
DRONES_DIR = $(shell git config "borg.drones-directory" || echo "lib")
-include $(DRONES_DIR)/borg/borg.mk
bootstrap-borg:
@git submodule--helper clone --name borg --path $(DRONES_DIR)/borg \
--url git@github.com:emacscollective/borg.git
@cd $(DRONES_DIR)/borg; git symbolic-ref HEAD refs/heads/main
@cd $(DRONES_DIR)/borg; git reset --hard HEAD
Now you are probably tempted to run make bootstrap-borg, but that is
for bootstrapping from a seed, and what we are doing right now is to
bootstrap from scratch. In the process we are creating a seed but we
are not there yet. Instead run this:
git submodule add --name borg git@github.com:emacscollective/borg.git lib/borg
Now that borg is available we can build all the assimilated packages (currently
just borg itself) using make bootstrap.
Now it is time to tell Emacs to initialize Borg instead of Package by
adding a simple init.el file containing at least:
(when (< emacs-major-version 27) (setq package-enable-at-startup nil)) (add-to-list 'load-path (expand-file-name "lib/borg" user-emacs-directory)) (require 'borg) (borg-initialize)
Beginning with Emacs 27.1, package-enable-at-startup has to be
disabled earlier, in early-init.el:
(setq package-enable-at-startup nil)
Now you could create the initial commit but you could also delay that.
git commit -m "Assimilate borg"
Now it is time to assimilate some other essential packages. You could
do so using M-x borg-assimilate, but you would quickly notice that
doing so without the help of the epkg package is quite cumbersome,
so lets manually install that and its dependency first:
git submodule add --name closql git@github.com:emacscollective/closql.git lib/closql git submodule add --name emacsql git@github.com:magit/emacsql.git lib/emacsql git submodule add --name compat git@github.com:emacs-compat/compat.git lib/compat git submodule add --name llama https://git.sr.ht/~tarsius/llama lib/llama git submodule add --name epkg git@github.com:emacscollective/epkg.git lib/epkg git config -f .gitmodules submodule.emacsql.no-byte-compile emacsql-pg.el echo /epkgs/ >> .gitignore git add .gitignore .gitmodules make build git commit -m "Assimilate epkg and dependencies"
Once you have done that and have restarted Emacs, you can install Magit using Borg, as described in Assimilation. You should also configure Magit status buffers to display submodules:
(with-eval-after-load 'magit
(magit-add-section-hook 'magit-status-sections-hook
'magit-insert-modules
'magit-insert-stashes
'append))
Finally (look, nobody forced you to do this from scratch ;-) I
strongly suggest that you make yourself familiar with my auto-compile
package.
If you are currently using Package and want to gently ease into using Borg alongside that, then you can proceed as described in Use as secondary package manager.
If on the other hand you are already manually using Git modules,
then you should proceed as described in Bootstrapping from scratch.
Obviously "from scratch" does not apply this time around, so just skip
steps like git init.
Getting started using your existing configuration on another machine works the same way as described in Bootstrapping using a seed. The only difference is that instead of starting by cloning someone else’s repository you start by cloning your own repository.
For drones whose upstream repositories are located on Github or Gitlab
the emacs.g collective uses the ssh protocol by default, which is a
problem if you don’t have accounts there and have not properly setup
your keys.
Luckily this can easily be fixed using the following global rules.
git config --global url.https://github.com/.insteadOf git@github.com: git config --global url.https://gitlab.com/.insteadOf git@gitlab.com:
If you don’t want to configure this globally, then you can also configure
Borg itself to prefer the https URLS.
(setq borg-rewrite-urls-alist
'(("git@github.com:" . "https://github.com/")
("git@gitlab.com:" . "https://gitlab.com/")))
This does not affect packages that have already been assimilated. During bootstrapping you have to change the URLs for packages that are assimilated by default.
cd ~/.config/emacs sed -i "s|git@github.com:|https://github.com/|g" .gitmodules sed -i "s|git@gitlab.com:|https://gitlab.com/|g" .gitmodules git commit -m "Use https URLs for Github and Gitlab"
If you have already run make bootstrap, then you also have to edit
.git/config.
cd ~/.config/emacs sed -i "s|git@github.com:|https://github.com/|g" .git/config sed -i "s|git@gitlab.com:|https://gitlab.com/|g" .git/config