forked from emacscollective/borg
-
Notifications
You must be signed in to change notification settings - Fork 0
/
borg.texi
1322 lines (1010 loc) · 46.5 KB
/
borg.texi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
\input texinfo @c -*- texinfo -*-
@c %**start of header
@setfilename borg.info
@settitle Borg User Manual
@documentencoding UTF-8
@documentlanguage en
@c %**end of header
@copying
@quotation
Copyright (C) 2016-2021 Jonas Bernoulli <jonas@@bernoul.li>
You can redistribute this document 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.
This document is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE@. See the GNU
General Public License for more details.
@end quotation
@end copying
@dircategory Emacs
@direntry
* Borg: (borg). Assimilate Emacs packages as Git submodules.
@end direntry
@finalout
@titlepage
@title Borg User Manual
@subtitle for version 3.1.2 (v3.1.2-54-gb210e4a+1)
@author Jonas Bernoulli
@page
@vskip 0pt plus 1filll
@insertcopying
@end titlepage
@contents
@ifnottex
@node Top
@top Borg User Manual
The Borg assimilate Emacs packages as Git submodules. Borg is a
bare-bones package manager for Emacs packages.
@noindent
This manual is for Borg version 3.1.2 (v3.1.2-54-gb210e4a+1).
@quotation
Copyright (C) 2016-2021 Jonas Bernoulli <jonas@@bernoul.li>
You can redistribute this document 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.
This document is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE@. See the GNU
General Public License for more details.
@end quotation
@end ifnottex
@menu
* Introduction::
* Installation::
* Startup::
* Assimilation::
* Updating drones::
* Patching drones::
* Make targets::
* Variables::
* Low-level functions::
* Command Index::
* Function Index::
* Variable Index::
@detailmenu
--- The Detailed Node Listing ---
Installation
* Use as secondary package manager::
* Bootstrapping::
Bootstrapping
* Bootstrapping using a seed::
* Bootstrapping from scratch::
* Migrating a legacy configuration::
* Using your configuration on another machine::
* Using https URLs::
* Missing commits and repositories::
@end detailmenu
@end menu
@node Introduction
@chapter Introduction
The Borg assimilate Emacs packages as Git submodules.
Borg is a bare-bones package manager for Emacs packages. It provides
only a few essential features and should be combined with other tools
such as Magit, @code{epkg}, @code{use-package}, and @code{auto-compile}.
Borg assimilates packages into the @code{~/.emacs.d} repository as Git
submodules. An assimilated package is called a drone and a borg-based
@code{~/.emacs.d} repository is called a collective.
It is possible to clone a package repository without assimilating it.
A cloned package is called a clone.
To learn more about this project, also read the blog post @footnote{@uref{https://emacsair.me/2016/05/17/assimilate-emacs-packages-as-git-submodules}.} in
which it was announced.
@node Installation
@chapter Installation
Borg can be used by itself, in which case it has to be bootstrapped.
This is how Borg originally was intended to be used exclusively but
nowadays you may also choose to use it merely as a secondary package
manager, in which case Borg itself is installed using Package.
@menu
* Use as secondary package manager::
* Bootstrapping::
@end menu
@node Use as secondary package manager
@section Use as secondary package manager
To use Borg as a secondary package manager alongside Package, begin by
installing the former using the latter. Borg is only available from
Melpa, so you have to add that first.
@lisp
(add-to-list 'package-archives
(cons "melpa" "https://melpa.org/packages/")
t)
@end lisp
Then you have to @code{M-x package-refresh-contents RET} before you can @code{M-x
package-install RET borg RET}. Doing that should add a verbose variant
of this to your init file:
@lisp
(custom-set-variables
'(package-selected-packages '(borg)))
@end lisp
Then you have to make the two package managers aware of one another by
replacing the call to @code{package-initialize} in your init file with this:
@lisp
(if (require 'borg-elpa nil t)
(borg-elpa-initialize)
(package-initialize))
@end lisp
Just like Package (aka Elpa) defaults to installing packages in @code{elpa/},
Borg defaults to installing them in @code{borg/}. (When using both package
managers, that is. If used by itself, then Borg defaults to using
@code{lib/}.) If you want to use another directory, then you can do so by
setting the Git variable @code{borg.drones-directory}.
You should also add a @code{Makefile} containing:
@example
BORG_SECONDARY_P = true
include $(shell find -L elpa -maxdepth 1 -regex '.*/borg-[.0-9]*' |\
sort | tail -n 1)/borg.mk
@end example
Despite its title, many things mentioned in the next section are
relevant even when Borg was installed the way we just did. Just
saying.
@node Bootstrapping
@section Bootstrapping
(As mentioned in the next section you can use a location other than
@code{~/.emacs.d}. Never-the-less most of the subsequent examples just talk
about @code{~/.emacs.d} and if you use something else, then obviously have to
substitute that. The same applies to the string @code{lib} and the variables
@code{user-init-file} and @code{user-emacs-directory}, which also might not be
appropriate depending on your choices.)
@menu
* Bootstrapping using a seed::
* Bootstrapping from scratch::
* Migrating a legacy configuration::
* Using your configuration on another machine::
* Using https URLs::
* Missing commits and repositories::
@end menu
@node Bootstrapping using a seed
@subsection Bootstrapping using a seed
To get started clone the repository of the @code{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 @code{emacs.g} merely
as a bootstrapping seed and do not merge upstream changes after that.
This collective already assimilats a few drones in addition to @code{borg}
itself, namely @code{magit}, @code{epkg}, @code{use-package}, @code{auto-compile}, @code{git-modes} and
@code{diff-hl}, as well as their dependencies. These drones are not required
by @code{borg} but their use is highly recommended.
Clone the @code{emacs.g} repository to either @code{~/.emacs.d}, or for testing
purposes to any other location. This repository contains a @code{Makefile}
that imports @code{lib/borg/borg.mk} and defines an additional target whose
purpose is to make that file and @code{lib/borg/borg.sh} available. Run @code{make
bootstrap-borg} to clone the @code{borg} repository. That does not completely
setup the @code{borg} repository but it makes the latest version of the
mentioned files available. Now that these files are available you can
run @code{make bootstrap} to get and configure all submodules (including the
@code{borg} submodule) and to build all drones.
@example
git clone git@@github.com:emacscollective/emacs.g.git ~/.emacs.d
cd ~/.emacs.d
make bootstrap-borg
make bootstrap
@end example
If you cloned to somewhere other than @code{~/.emacs.d}, then you can use
that configuration using @code{emacs -Q --load /path/to/emacs.g/init.el}.
For drones whose upstream repositories are located on Github or Gitlab
the @code{emacs.g} collective uses the @code{ssh} protocol by default, which is a
problem if you don't have accounts there and have not properly setup
your keys. See @ref{Using https URLs}.
When running the @code{bootstrap} target you might get errors about certain
commits not being available, but fear not! In @ref{Missing commits and repositories} we discuss these complications.
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 @code{~/.config/git/ignore}
file:
@example
*.elc
*-autoloads.el
dir
@end example
You may discover more things that you'll want to ignore this way as
you use @code{borg}.
@node Bootstrapping from scratch
@subsection Bootstrapping from scratch
If you don't want to base your configuration on the @code{emacs.g}
starter-kit described in the previous section, then you have
to do a few things manually.
@example
git init ~/.emacs.d
cd ~/.emacs.d
@end example
By default Borg installs packages inside the @code{lib/} subdirectory, but
since you are starting from scratch, you may choose something else
by setting the Git variable @code{borg.drones-directory} locally for this
repository.
Then you should add a @code{Makefile} containing at least:
@example
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/master
@@cd $(DRONES_DIR)/borg; git reset --hard HEAD
@end example
Now you are probably tempted to run @code{make bootstrap-borg}, but that is
for bootstrapping @emph{from a seed}, and what we are doing right now is to
bootstrap @emph{from scratch}. In the process we are creating a seed but we
are not there yet. Instead run this:
@example
git submodule add --name borg git@@github.com:emacscollective/borg.git lib/borg
@end example
Now that @code{borg} is available we can build all the assimilated packages (currently
just @code{borg} itself) using @code{make bootstrap}.
The final obligatory step is to tell Emacs to initialize Borg by
adding a simple @code{init.el} file containing at least:
@lisp
(add-to-list 'load-path (expand-file-name "lib/borg" user-emacs-directory))
(require 'borg)
(borg-initialize)
@end lisp
Now you could create the initial commit but you could also delay that.
@example
git commit -m "Assimilate borg"
@end example
Now it is time to assimilate some other essential packages. You could
do so using @code{M-x borg-assimilate}, but you would quickly notice that
doing so without the help of the @code{epkg} package is quite cumbersome,
so lets manually install that and its dependency first:
@example
git submodule add --name closql git@@github.com:emacscollective/closql.git lib/closql
git submodule add --name emacsql git@@github.com:skeeto/emacsql.git lib/emacsql
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 all
git commit -m "Assimilate epkg and dependencies"
@end example
Once you have done that and restarted Emacs, then you can Magit using
Borg as described in @ref{Assimilation}. As part of that you should tell
Magit status buffers to display submodules:
@lisp
(with-eval-after-load 'magit
(magit-add-section-hook 'magit-status-sections-hook
'magit-insert-modules
'magit-insert-stashes
'append))
@end lisp
Finally (look, nobody forced you to do this from scratch ;-) I
strongly suggest that you make yourself familiar with my @code{auto-compile}
package.
@node Migrating a legacy configuration
@subsection Migrating a legacy configuration
If you are currently using Package and want to gently ease into using
Borg alongside that, then you can proceed as described in @ref{Use as secondary package manager}.
If on the other hand you are already manually using Git modules,
then you should proceed as described in @ref{Bootstrapping from scratch}.
Obviously "from scratch" does not apply this time around, so just skip
steps like @code{git init}.
@node Using your configuration on another machine
@subsection Using your configuration on another machine
Getting started using your existing configuration on another machine
works the same way as described in @ref{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.
@node Using https URLs
@subsection Using https URLs
For drones whose upstream repositories are located on Github or Gitlab
the @code{emacs.g} collective uses the @code{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.
@lisp
git config --global url.https://github.com/.insteadOf git@@github.com:
git config --global url.https://gitlab.com/.insteadOf git@@gitlab.com:
@end lisp
If you don't want to configure this globally, then you can also configure
Borg itself to prefer the @code{https} URLS@.
@lisp
(setq borg-rewrite-urls-alist
'(("git@@github.com:" . "https://github.com/")
("git@@gitlab.com:" . "https://gitlab.com/")))
@end lisp
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.
@example
cd ~/.emacs.d
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"
@end example
If you have already run @code{make bootstrap}, then you also have to edit
@code{.git/config}.
@example
cd ~/.emacs.d
sed -i "s|git@@github.com:|https://github.com/|g" .git/config
sed -i "s|git@@gitlab.com:|https://gitlab.com/|g" .git/config
@end example
@node Missing commits and repositories
@subsection Missing commits and repositories
While bootstrapping it can happen that a commit or even a complete
repository is missing. That can be scary but understanding what is
going on and how to deal with it goes a long way.
So what does it look like when that happens? Here are two typical
examples that you might see when run @code{make bootstrap}.
Some commit is missing:
@example
--- [hl-todo] ---
Cloning into '/home/you/.emacs.d/lib/hl-todo'...
remote: Enumerating objects: 44, done.
remote: Counting objects: 100% (44/44), done.
remote: Compressing objects: 100% (29/29), done.
remote: Total 367 (delta 23), reused 36 (delta 15), pack-reused 323
Receiving objects: 100% (367/367), 71.98 KiB | 837.00 KiB/s, done.
Resolving deltas: 100% (158/158), done.
fatal: Could not parse object '02bda39bf2d2b77168255d9e49c78b95b0bd314a'.
futile: Checkout of '02bda39bf2d2b77168255d9e49c78b95b0bd314a' into submodule path 'lib/hl-todo' failed
HEAD is now at 3bba459 README.md: Cosmetics
@end example
Some repository is missing:
@example
--- [paren-face] ---
Cloning into '/home/you/.emacs.d/lib/paren-face'...
ERROR: Repository not found.
fatal: Could not read from remote repository.
Please make sure you have the correct access rights
and the repository exists.
fatal: clone of 'git@@github.com:tarsius/broken-url.git' into submodule path '/home/you/.emacs.d/lib/paren-face' failed
futile: Clone of any remote into submodule path 'lib/paren-face' failed
@end example
Both of these packages are not essential and I recommend that you
delay figuring out what is going on exactly and that you instead
proceed bootstrapping the rest of your configuration. Once you are
done with, then you have an Emacs setup that allows you to be
efficiently investigate the above issues.
To skip a package you have to "deinit" the submodule and also remove
the empty directory that represents the no longer initialized module:
@example
$ git submodule deinit lib/paren-face/
Cleared directory 'lib/paren-face'
error: could not lock config file .git/modules/paren-face/config: No such file or directory
warning: Could not unset core.worktree setting in submodule 'lib/paren-face'
Submodule 'paren-face' (git@@github.com:tarsius/broken-url.git) unregistered for path 'lib/paren-face'
$ rm -r lib/paren-face
$ git status
On branch master
Your branch is up to date with 'origin/master'.
Changes not staged for commit:
deleted: lib/paren-face
no changes added to commit
@end example
Ignore the irrelevant warnings and that the package is now considered deleted.
Now @code{make bootstrap} has to resume where it left of, more or less. This
make target is equal to these three commands:
@example
$ git submodule init
$ lib/borg/borg.sh
$ make build
@end example
The first already succeeded at this point and the second failed
somewhere along the way, so lets run that again. It will make some
noise about the packages that is has already dealt with, but you can
just ignore that. Then it should silently skip over the package that
you have just disabled and proceed with the rest, proceeding towards
the end of the alphabet.
So now that everything is peachy you can start Emacs and look into
what went wrong. Here are some things that could have happened and
how to deal with them.
The commit that you have referenced was removed from the upstream
repository. Pick another commit instead and resume the bootstrap.
@example
$ git submodule update --init lib/hl-todo
Submodule 'hl-todo' (git@@github.com:tarsius/hl-todo.git) registered for path 'lib/hl-todo'
fatal: remote error: upload-pack: not our ref 02bda39bf2d2b77168255d9e49c78b95b0bd314a
Fetched in submodule path 'lib/hl-todo', but it did not contain 02bda39bf2d2b77168255d9e49c78b95b0bd314a. Direct fetching of that commit failed.
$ cd lib/hl-todo
$ git reset --hard
$ cd ../..
$ git add lib/hl-todo
$ git commit -m '"Update" hl-todo'
@end example
The repository was moved. Update the url and resume the bootstrap.
@example
$ git config --file .gitmodules submodule.paren-face.url git@@github.com:tarsius/paren-face.git
$ git submodule update --init lib/paren-face
Submodule 'paren-face' (git@@github.com:tarsius/paren-face.git) registered for path 'lib/paren-face'
Cloning into '/home/you/.emacs.d/lib/paren-face'...
Submodule path 'lib/paren-face': checked out 'eb4a51b8ef455e0914108105e7c0008d675457cc'
$ git add .gitmodules
$ git commit -m "paren-face: Update url"
@end example
The repository was removed and no copy remains available anywhere.
This is the worst case scenario and unlikely to become a reality.
Remove the package for good.
@example
$ git rm lib/goner
$ git commit -m "Remove goner"
@end example
@node Startup
@chapter Startup
The @code{user-init-file}, @code{~/.emacs.d/init.el}, has to contain a call to
@code{borg-initialize}. It should also set @code{package-enable-at-startup} to @code{nil}
unless you really want to use both @code{borg} and @code{package} at the same time.
@defun borg-initialize
This function initializes assimilated drones using @code{borg-activate}.
To skip the activation of the drone named DRONE, temporarily disable
it by setting the value of the Git variable @code{submodule.DRONE.disabled}
to true in @code{~/.emacs.d/.gitmodules}.
@end defun
@cindex borg-activate clone
@deffn Command borg-activate clone
This function activates the clone named CLONE by adding the
appropriate directories to the @code{load-path} and to @code{Info-directory-list},
and by loading the autoloads file, if it exists.
Unlike @code{borg-initialize}, this function ignores the Git variable
@code{submodule.DRONE.disabled} and can be used to activate clones that
have not been assimilated.
@end deffn
@node Assimilation
@chapter Assimilation
A third-party package is assimilated by adding it as a submodule and,
if necessary, by configuring it in @code{~/.emacs.d/init.el}. Built-in
packages are assimilated merely by configuring them.
To begin the assimilation of a third-party package use the command
@code{borg-assimilate}, which adds the package's repository as a submodule
and attempts to build the drone.
A safer alternative is to first clone the package without assimilating
it, using @code{borg-clone}. This gives you an opportunity to inspect the
cloned package for broken or malicious code before it gets a chance to
run arbitrary code. Later you can proceed with the assimilation using
@code{borg-assimilate}, or remove the clone using @code{borg-remove}.
Building the drone can fail, for example due to missing dependencies.
Failure to build a drone is not considered as a failure to assimilate.
If a build fails, then a buffer containing information about the
issue pops up. If the failure is due to unsatisfied dependencies,
then assimilate those too, and then build any drone which previously
couldn't be built by using the Emacs command @code{borg-build} or @code{make
lib/DRONE}. Alternatively you can just rebuild everything using @code{make
build}.
If you wish to avoid such complications, you should use the command
@code{epkg-describe-package} before assimilating a package. Among other
useful information, it also provides a dependency tree.
Once the packages have been added as submodules and the drones have
been built, the assimilation is completed by creating an assimilation
commit.
If you assimilate a single package, then it is recommended that you
use a message similar to this:
@example
Assimilate foo v1.0.0
@end example
Or if one or more dependencies had to be assimilated, something like:
@example
Assimilate foo and dependencies
Assimilate foo v1.0.0
Assimilate bar v1.1.0
Assimilate baz v0.1.0
@end example
It's usually a good idea not to assimilate unrelated packages in the
same commit, but something like this might make sense:
@example
Assimilate ido and extensions
Assimilate flx v0.6.1-3-gae0981b
Assimilate ido-at-point v1.0.0
Assimilate ido-ubiquitious v3.12-2-g7354d98
Assimilate ido-vertical-mode v0.1.6-33-gb42e422
Assimilate smex 3.0-13-g55aaebe
@end example
The command @code{borg-insert-update-message} can be used to generate such
commit messages.
@table @asis
@kindex C-c C-b [in git-commit-mode buffer]
@cindex borg-insert-update-message
@item @kbd{C-c C-b [in git-commit-mode buffer]} @tie{}@tie{}@tie{}@tie{}(@code{borg-insert-update-message})
This command insert information about drones that are changed in the
index. Formatting is according to the commit message conventions
described above.
@end table
@cindex borg-assimilate package url &optional partially
@deffn Command borg-assimilate package url &optional partially
This command assimilates the package named PACKAGE from URL@.
If @code{epkg} is available, then only the name of the package is read in
the minibuffer and the url stored in the Epkg database is used. If
@code{epkg} is unavailable, the package is not in the database, or if a
prefix argument is used, then the url too is read in the minibuffer.
If a negative prefix argument is used, then the submodule is added
but the build and activation steps are skipped. This is useful when
assimilating a package that requires special build steps. After
configuring the build steps use @code{borg-build} to complete the
assimilation.
@end deffn
@cindex borg-clone package url
@deffn Command borg-clone package url
This command clones the package named PACKAGE from URL, without
assimilating it. This is useful when you want to inspect the
package before potentially executing malicious or broken code.
Interactively, when the @code{epkg} package is available, then the name
is read in the minibuffer and the url stored in the Epkg database
is used. If @code{epkg} is unavailable, the package is unknown, or when
a prefix argument is used, then the url is also read in the
minibuffer.
@end deffn
@cindex borg-remove clone
@deffn Command borg-remove clone
This command removes the cloned or assimilated package named CLONE,
by removing the working tree from @code{borg-drones-directory}, regardless
of whether that repository belongs to an assimilated package or a
package that has only been cloned for review using @code{borg-clone}. The
Git directory is not removed.
@end deffn
@cindex borg-build clone &optional activate
@deffn Command borg-build clone &optional activate
This command builds the clone named CLONE@. Interactively, or when
optional ACTIVATE is non-nil, then also activate the drone using
@code{borg-activate}.
@end deffn
@defun borg-update-autoloads clone &optional path
This function updates the autoload file for the libraries belonging
to the clone named CLONE in the directories in PATH@. PATH can be
omitted or contain file-names that are relative to the top-level of
CLONE's repository.
@end defun
@defun borg-byte-compile clone &optional path
This function compiles the libraries for the clone named CLONE in
the directories in PATH@. PATH can be omitted or contain file-names
that are relative to the top-level of CLONE's repository.
@end defun
@defun borg-makeinfo clone
This function generates the Info manuals and the Info index for the
clone named CLONE@.
@end defun
@defun borg-batch-rebuild &optional quick
This function rebuilds all assimilated drones in alphabetic order,
except for Org which is rebuilt first. After that it also builds
the user init files using @code{borg-batch-rebuild-init}.
This function is not intended for interactive use; instead it is
used by the Make target @code{build} described in the following section.
When optional QUICK is non-nil, then this function does not build
drones for which @code{submodule.DRONE.build-step} is set, assuming that
those are the drones that take longer to be built.
@end defun
@defun borg-batch-rebuild-init
This function builds the init files specified by the Make variable
@code{INIT_FILES}, or if that is unspecified @code{init.el} and @code{LOGIN.el}, where
@code{LOGIN} is the value of the variable @code{user-real-login-name}. If a file
does not exist, then it is silently ignored.
This function is not intended for interactive use; instead it is
used by the Make targets @code{build-init} and (indirectly) @code{build}, which
are described in @ref{Make targets}.
@end defun
@node Updating drones
@chapter Updating drones
Borg does not provide an update command. By not doing so, it empowers
you to update to exactly the commit you wish to update to, instead of
to "the" new version.
To determine the drones which you @emph{might} want to update, visit the Magit
status buffer of the @code{~/.emacs.d} repository and press @code{f m} to fetch
inside all submodules. After you have done so, and provided there
actually are any modules with new upstream commits, a section titled
"Modules unpulled from @@@{upstream@}" appears.
Each subsection of that section represents a submodule with new
upstream commits. Expanding such a subsection lists the new upstream
commits. These commits can be visited by pressing @code{RET}, and the status
buffer of a submodule can be visited by pressing @code{RET} while point is
inside the heading of the respective submodule section. To return to
the status buffer of @code{~/.emacs.d} press @code{q}.
Inside the status buffer of a submodule, you can pull the upstream
changes as usual, using @code{F u}. If you wish you can inspect the changes
before doing so. And you can also choose to check out another commit
instead of the upstream @code{HEAD}.
Once you have "updated" to a new commit, you should also rebuild the
drone using the command @code{borg-build}. This may fail, e.g. due to new
dependencies.
Once you have resolved all issues you should create an "update
commit". You can either create one commit per updated drone or you
can create a single commit for all updated drones, which ever you find
more appropriate. However it is recommended that you use a message
similar to:
@example
Update foo to v1.1.0
@end example
Or for multiple packages:
@example
Update 2 drones
Update foo to v1.1.0
Update bar to v1.2.1
@end example
The command @code{borg-insert-update-message} can be used to generate such
commit messages.
To update the Epkg package database use the command @code{epkg-update}.
@node Patching drones
@chapter Patching drones
By using Borg you can not only make changes to assimilated packages,
you can also keep track of those patches and share them with others.
If you created some commits in a drone repository and are the
maintainer of the respective package, then you can just push your
changes to the "origin" remote. You don't have to do this every time
you created some commits, but at important checkpoints, such as after
creating a release, you should record the changes in the @code{~/.emacs.d}
repository. To do so proceed as described in @ref{Updating drones}.
But for most packages you are not the maintainer and if you create
commits for such drones, then you have to create a fork and push there
instead. You should configure that remote as the push-remote using
@code{git config remote.pushDefault FORK}, or by pressing @code{b C M-p} in Magit.
After you have done that you can continue to pull from the upstream
using @code{F u} in Magit and you can also push to your fork using @code{P p}.
Of course you should also occasionally record the changes in the
@code{~/.emacs.d} repository. Additionally, and ideally when you first
fork a drone, you should also record information about your personal
remote in the super-repository by setting @code{submodule.DRONE.remote} in
@code{~/.emacs.d/.gitmodules}.
@defvar submodule.DRONE.remote "NAME URL"
This variable specifies an additional remote named NAME that is
fetched from URL@. This variable can be specified multiple times.
Note that "NAME URL" is a single value and that the two parts of
that value are separated by a single space.
@code{make bootstrap} automatically adds all remotes that are specified
like this to the DRONE repository by setting @code{remote.NAME.url} to
URL and using the standard value for @code{remote.NAME.fetch}.
@end defvar
@defvar borg.pushDefault FORK
This variable specifies a name used for push-remotes. Because this
variable can only have one value it is recommended that you use the
same name, FORK, for your personal remote in all drone repositories
in which you have created patches that haven't been merged into the
upstream repository (yet). A good value may be your username.
For all DRONES for which one value of @code{submodule.DRONE.remote}
specifies a remote whose NAME matches FORK, @code{make bootstrap}
automatically configures FORK to be used as the push-remote by
setting @code{remote.pushDefault} to FORK@.
@end defvar
@node Make targets
@chapter Make targets
The following @code{make} targets are available by default. To use them you
have to be in @code{~/.emacs.d} in a shell. They are implemented in @code{borg.mk},
which is part of the @code{borg} package.
@cindex help
@deffn Command help
This target prints information about the following targets.
@end deffn
@cindex all
@deffn Command all
@end deffn
@cindex build
@deffn Command build
This target rebuilds all assimilated drones in alphabetic order,
except for Org which is rebuilt first. After that it also builds
the user init files, like @code{build-init} does.
@end deffn
@cindex build-init
@deffn Command build-init
This target builds the init files specified by the Make variable
@code{INIT_FILES}, or if that is unspecified @code{init.el} and @code{LOGIN.el}, where
@code{LOGIN} is the value of the variable @code{user-real-login-name}. If a file
does not exist, then it is silently ignored.
If you publish your @code{~/.emacs.d} repository but would like to keep
some settings private, then you can do so by putting them in a file
@code{~/.emacs.d/LOGIN.el}. The downside of this approach is that you will
have to somehow synchronize that file between your machines without
checking it into Git.
@end deffn
@cindex quick
@deffn Command quick
This target builds @emph{most} drones. Excluded are all drones for which
the Git variable @code{submodule.DRONE.build-step} is set, assuming that those
are the drones that take longer to build.
It also builds the init files as described above.
@end deffn
@cindex lib/DRONE
@deffn Command lib/DRONE
This target builds the drone named DRONE@.
@end deffn
@cindex tangle-init
@deffn Command tangle-init
This target tangles (creates) @code{init.el} from @code{init.org}. You obviously
don't have to use such a file if you don't want to.
@end deffn
@cindex clean
@deffn Command clean
This target removes all byte-code files inside @code{~/.emacs.d}.
@end deffn
@cindex clean-init
@deffn Command clean-init
This target removes byte-code files for init files.
@end deffn
@cindex bootstrap-borg
@deffn Command bootstrap-borg
This target bootstraps @code{borg} itself.
@end deffn
@cindex bootstrap
@deffn Command bootstrap
This target attempts to bootstrap the drones. To do so it runs
@code{git submodule init}, @code{borg.sh} (which see), and @code{make build}.
If an error occurs during the @code{borg.sh} phase, then you can just run
that command again to process the remaining drones. The drones that
have already been bootstrapped or that have previously failed will
be skipped. If a drone cannot be cloned from any of the known
remotes, then you should temporarily remove it using @code{git submodule
deinit lib/DRONE}. When done with @code{borg.sh} also manually run @code{make
build} again.
@end deffn
@node Variables
@chapter Variables
@defvar borg.drones-directory DIRECTORY
This Git variable can be used to override the name of the directory
that contains the drone submodules. If specified, the value has to
be relative to the top-level directory of the repository.
Note that if you change the value of this variable, then you might
have to additionally edit @code{~/.emacs.d/Makefile}.
@end defvar
The values of the following variables are set at startup and should
not be changed by the user.
@defvar borg-drones-directory
The value of this constant is the directory beneath which drone
submodules are placed. The value is set based on the location of
the @code{borg} library and the Git variable @code{borg.drones-directory} if set,
and should not be changed.
@end defvar
@defvar borg-user-emacs-directory
The value of this constant is the directory beneath which additional
per-user Emacs-specific files are placed. The value is set based on
the location of the @code{borg} library and should not be changed. The
value is usually the same as that of @code{user-emacs-directory}, except
when Emacs is started with @code{emacs -q -l /path/to/init.el}.
@end defvar
@defvar borg-gitmodules-file
The value of this constant is the @code{.gitmodules} file of the
super-repository.
@end defvar
The value of this Make variable has to be set in @code{~/.emacs.d/Makefile}.
@defvar INIT@math{_FILES}
A list of init files to be build by the Make targets @code{build} and
@code{build-init}. See @ref{Make targets}.
@end defvar
The values of these borg-specific Git variables have to be set in the
file @code{~/.emacs.d/.gitmodules}. The variables @code{borg.pushDefault} and
@code{submodule.DRONE.remote} are described in @ref{Patching drones}.
@defvar borg.collective REMOTE
This variable specifies the name used for remotes that reference
a repository that has been patched by the collective. If a NAME
matches REMOTE, then it is configured as the upstream of the
current branch of the respective DRONE@.
If the file @code{.hive-maint} exists, then this variable has the same
effect as @code{borg.pushDefault}. This special case is only useful for