]> arthur.barton.de Git - bup.git/blob - README.md
test-misc: be independent of user's git defaultBranch
[bup.git] / README.md
1 bup: It backs things up
2 =======================
3
4 bup is a program that backs things up.  It's short for "backup." Can you
5 believe that nobody else has named an open source program "bup" after all
6 this time?  Me neither.
7
8 Despite its unassuming name, bup is pretty cool.  To give you an idea of
9 just how cool it is, I wrote you this poem:
10
11                              Bup is teh awesome
12                           What rhymes with awesome?
13                             I guess maybe possum
14                            But that's irrelevant.
15                         
16 Hmm.  Did that help?  Maybe prose is more useful after all.
17
18
19 Reasons bup is awesome
20 ----------------------
21
22 bup has a few advantages over other backup software:
23
24  - It uses a rolling checksum algorithm (similar to rsync) to split large
25    files into chunks.  The most useful result of this is you can backup huge
26    virtual machine (VM) disk images, databases, and XML files incrementally,
27    even though they're typically all in one huge file, and not use tons of
28    disk space for multiple versions.
29    
30  - It uses the packfile format from git (the open source version control
31    system), so you can access the stored data even if you don't like bup's
32    user interface.
33    
34  - Unlike git, it writes packfiles *directly* (instead of having a separate
35    garbage collection / repacking stage) so it's fast even with gratuitously
36    huge amounts of data.  bup's improved index formats also allow you to
37    track far more filenames than git (millions) and keep track of far more
38    objects (hundreds or thousands of gigabytes).
39    
40  - Data is "automagically" shared between incremental backups without having
41    to know which backup is based on which other one - even if the backups
42    are made from two different computers that don't even know about each
43    other.  You just tell bup to back stuff up, and it saves only the minimum
44    amount of data needed.
45    
46  - You can back up directly to a remote bup server, without needing tons of
47    temporary disk space on the computer being backed up.  And if your backup
48    is interrupted halfway through, the next run will pick up where you left
49    off.  And it's easy to set up a bup server: just install bup on any
50    machine where you have ssh access.
51    
52  - Bup can use "par2" redundancy to recover corrupted backups even if your
53    disk has undetected bad sectors.
54    
55  - Even when a backup is incremental, you don't have to worry about
56    restoring the full backup, then each of the incrementals in turn; an
57    incremental backup *acts* as if it's a full backup, it just takes less
58    disk space.
59    
60  - You can mount your bup repository as a FUSE filesystem and access the
61    content that way, and even export it over Samba.
62    
63  - It's written in python (with some C parts to make it faster) so it's easy
64    for you to extend and maintain.
65
66
67 Reasons you might want to avoid bup
68 -----------------------------------
69
70  - It's not remotely as well tested as something like tar, so it's
71    more likely to eat your data.  It's also missing some
72    probably-critical features, though fewer than it used to be.
73    
74  - It requires python 3.7 or newer (or 2.7 for a bit longer), a C
75    compiler, and an installed git version >= 1.5.6.  It also requires
76    par2 if you want fsck to be able to generate the information needed
77    to recover from some types of corruption.  While python 2.7 is
78    still supported, please make plans to upgrade.  Python 2 upstream
79    support ended on 2020-01-01, and we plan to drop support soon too.
80  
81  - It currently only works on Linux, FreeBSD, NetBSD, OS X >= 10.4,
82    Solaris, or Windows (with Cygwin, and WSL).  Patches to support
83    other platforms are welcome.
84
85  - Until resolved, a [glibc bug](https://sourceware.org/bugzilla/show_bug.cgi?id=26034)
86    might cause bup to crash on startup for some (unusual) command line
87    argument values, when bup is configured to use Python 3.
88
89  - Any items in "Things that are stupid" below.
90
91 Notable changes introduced by a release
92 =======================================
93
94  - <a href="note/0.32-from-0.31.md">Changes in 0.32 as compared to 0.31</a>
95  - <a href="note/0.31-from-0.30.1.md">Changes in 0.31 as compared to 0.30.1</a>
96  - <a href="note/0.30.1-from-0.30.md">Changes in 0.30.1 as compared to 0.30</a>
97  - <a href="note/0.30-from-0.29.3.md">Changes in 0.30 as compared to 0.29.3</a>
98  - <a href="note/0.29.3-from-0.29.2.md">Changes in 0.29.3 as compared to 0.29.2</a>
99  - <a href="note/0.29.2-from-0.29.1.md">Changes in 0.29.2 as compared to 0.29.1</a>
100  - <a href="note/0.29.1-from-0.29.md">Changes in 0.29.1 as compared to 0.29</a>
101  - <a href="note/0.29-from-0.28.1.md">Changes in 0.29 as compared to 0.28.1</a>
102  - <a href="note/0.28.1-from-0.28.md">Changes in 0.28.1 as compared to 0.28</a>
103  - <a href="note/0.28-from-0.27.1.md">Changes in 0.28 as compared to 0.27.1</a>
104  - <a href="note/0.27.1-from-0.27.md">Changes in 0.27.1 as compared to 0.27</a>
105
106
107 Test status
108 ===========
109
110 | branch | Debian                                                                                                                                         | FreeBSD                                                                                                                                          | macOS                                                                                                                                        |
111 |--------|------------------------------------------------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------|
112 | master | [![Debian test status](https://api.cirrus-ci.com/github/bup/bup.svg?branch=master&task=debian)](https://cirrus-ci.com/github/bup/bup) | [![FreeBSD test status](https://api.cirrus-ci.com/github/bup/bup.svg?branch=master&task=freebsd)](https://cirrus-ci.com/github/bup/bup) | [![macOS test status](https://api.cirrus-ci.com/github/bup/bup.svg?branch=master&task=macos)](https://cirrus-ci.com/github/bup/bup) |
113 | 0.30.x | [![Debian test status](https://api.cirrus-ci.com/github/bup/bup.svg?branch=0.30.x&task=debian)](https://cirrus-ci.com/github/bup/bup) | [![FreeBSD test status](https://api.cirrus-ci.com/github/bup/bup.svg?branch=0.30.x&task=freebsd)](https://cirrus-ci.com/github/bup/bup) | [![macOS test status](https://api.cirrus-ci.com/github/bup/bup.svg?branch=0.30.x&task=macos)](https://cirrus-ci.com/github/bup/bup) |
114 | 0.29.x | [![Debian test status](https://api.cirrus-ci.com/github/bup/bup.svg?branch=0.29.x&task=debian)](https://cirrus-ci.com/github/bup/bup) | [![FreeBSD test status](https://api.cirrus-ci.com/github/bup/bup.svg?branch=0.29.x&task=freebsd)](https://cirrus-ci.com/github/bup/bup) | [![macOS test status](https://api.cirrus-ci.com/github/bup/bup.svg?branch=0.29.x&task=macos)](https://cirrus-ci.com/github/bup/bup) |
115
116 Getting started
117 ===============
118
119 From source
120 -----------
121
122  - Check out the bup source code using git:
123
124     ```sh
125     git clone https://github.com/bup/bup
126     ```
127
128  - This will leave you on the master branch, which is perfect if you
129    would like to help with development, but if you'd just like to use
130    bup, please check out the latest stable release like this:
131
132     ```sh
133     git checkout 0.32
134     ```
135
136    You can see the latest stable release here:
137    https://github.com/bup/bup/releases.
138
139  - Install the required python libraries (including the development
140    libraries).
141
142    On very recent Debian/Ubuntu versions, this may be sufficient (run
143    as root):
144
145     ```sh
146     apt-get build-dep bup
147     ```
148
149    Otherwise try this:
150
151     ```sh
152     apt-get install python3.7-dev python3-fuse
153     apt-get install python3-pyxattr python3-pytest
154     apt-get install python3-distutils
155     apt-get install pkg-config linux-libc-dev libacl1-dev
156     apt-get install gcc make acl attr rsync
157     apt-get isntall python3-pytest-xdist # optional (parallel tests)
158     apt-get install par2 # optional (error correction)
159     apt-get install libreadline-dev # optional (bup ftp)
160     apt-get install python3-tornado # optional (bup web)
161
162     ```
163    Or, if you can't yet migrate to Python 3 (please try to soon):
164
165     ```sh
166     apt-get install python2.7-dev python-fuse
167     apt-get install python-pyxattr python-pytest
168     apt-get install pkg-config linux-libc-dev libacl1-dev
169     apt-get install gcc make acl attr rsync
170     apt-get isntall python-pytest-xdist # optional (parallel tests)
171     apt-get install par2 # optional (error correction)
172     apt-get install libreadline-dev # optional (bup ftp)
173     apt-get install python-tornado # optional (bup web)
174     ```
175
176    On CentOS (for CentOS 6, at least), this should be sufficient (run
177    as root):
178
179     ```sh
180     yum groupinstall "Development Tools"
181     yum install python2 python2-devel libacl-devel pylibacl
182     yum install fuse-python pyxattr
183     yum install perl-Time-HiRes
184     yum install readline-devel # optional (bup ftp)
185     yum install python-tornado # optional (bup web)
186     ```
187
188    In addition to the default CentOS repositories, you may need to add
189    RPMForge (for fuse-python) and EPEL (for pyxattr).
190
191    On Cygwin, install python, make, rsync, and gcc4.
192
193    If you would like to use the optional bup web server on systems
194    without a tornado package, you may want to try this:
195
196     ```sh
197     pip install tornado
198     ```
199
200  - Build:
201
202     ```sh
203     make
204     ```
205         
206  - Run the tests:
207
208     ```sh
209     make long-check
210     ```
211
212     or if you're in a bit more of a hurry:
213
214     ```sh
215     make check
216     ```
217         
218     If you have the Python xdist module installed, then you can
219     probably run the tests faster by adding the make -j option (see <a
220     href="HACKING">./HACKING</a> for additional information):
221
222     ```sh
223     make -j check
224     ```
225
226     The tests should pass.  If they don't pass for you, stop here and
227     send an email to bup-list@googlegroups.com.  Though if there are
228     symbolic links along the current working directory path, the tests
229     may fail.  Running something like this before "make test" should
230     sidestep the problem:
231
232     ```sh
233     cd "$(pwd -P)"
234     ```
235
236  - You can install bup via "make install", and override the default
237    destination with DESTDIR and PREFIX.
238
239    Files are normally installed to "$DESTDIR/$PREFIX" where DESTDIR is
240    empty by default, and PREFIX is set to /usr/local.  So if you wanted to
241    install bup to /opt/bup, you might do something like this:
242
243     ```sh
244     make install DESTDIR=/opt/bup PREFIX=''
245     ```
246
247  - The Python version that bup will use is determined by the
248    `python-config` program chosen by `./configure`, which will search
249    for a reasonable version unless `BUP_PYTHON_CONFIG` is set in the
250    environment.  You can see which Python executable was chosen by
251    looking at the configure output, or examining
252    `config/config.var/bup-python-config`, and you can change the
253    selection by re-running `./configure`.
254
255 From binary packages
256 --------------------
257
258 Binary packages of bup are known to be built for the following OSes:
259
260  - Debian:
261     http://packages.debian.org/search?searchon=names&keywords=bup
262  - Ubuntu:
263     http://packages.ubuntu.com/search?searchon=names&keywords=bup
264  - pkgsrc (NetBSD, Dragonfly, and others)
265     http://pkgsrc.se/sysutils/bup
266     http://cvsweb.netbsd.org/bsdweb.cgi/pkgsrc/sysutils/bup/
267  - Arch Linux:
268     https://www.archlinux.org/packages/?sort=&q=bup
269  - Fedora:
270     https://apps.fedoraproject.org/packages/bup
271  - macOS (Homebrew):
272     https://formulae.brew.sh/formula/bup
273
274
275 Using bup
276 ---------
277
278  - Get help for any bup command:
279
280     ```sh
281     bup help
282     bup help init
283     bup help index
284     bup help save
285     bup help restore
286     ...
287     ```
288
289  - Initialize the default BUP_DIR (~/.bup -- you can choose another by
290    either specifying `bup -d DIR ...` or setting the `BUP_DIR`
291    environment variable for a command):
292
293     ```sh
294     bup init
295     ```
296
297  - Make a local backup (-v or -vv will increase the verbosity):
298
299     ```sh
300     bup index /etc
301     bup save -n local-etc /etc
302     ```
303
304  - Restore a local backup to ./dest:
305
306     ```sh
307     bup restore -C ./dest local-etc/latest/etc
308     ls -l dest/etc
309     ```
310
311  - Look at how much disk space your backup took:
312
313     ```sh
314     du -s ~/.bup
315     ```
316
317  - Make another backup (which should be mostly identical to the last one;
318    notice that you don't have to *specify* that this backup is incremental,
319    it just saves space automatically):
320
321     ```sh
322     bup index /etc
323     bup save -n local-etc /etc
324     ```
325
326  - Look how little extra space your second backup used (on top of the first):
327
328     ```sh
329     du -s ~/.bup
330     ```
331
332  - Get a list of your previous backups:
333
334     ```sh
335     bup ls local-etc
336     ```
337
338  - Restore your first backup again:
339
340     ```sh
341     bup restore -C ./dest-2 local-etc/2013-11-23-11195/etc
342     ```
343
344  - Make a backup to a remote server which must already have the 'bup' command
345    somewhere in its PATH (see /etc/profile, etc/environment, ~/.profile, or
346    ~/.bashrc), and be accessible via ssh.
347    Make sure to replace SERVERNAME with the actual hostname of your server:
348
349     ```sh
350     bup init -r SERVERNAME:path/to/remote-bup-dir
351     bup index /etc
352     bup save -r SERVERNAME:path/to/remote-bup-dir -n local-etc /etc
353     ```
354
355  - Make a remote backup to ~/.bup on SERVER:
356
357     ```sh
358     bup index /etc
359     bup save -r SERVER: -n local-etc /etc
360     ```
361
362  - See what saves are available in ~/.bup on SERVER:
363
364     ```sh
365     bup ls -r SERVER:
366     ```
367
368  - Restore the remote backup to ./dest:
369
370     ```sh
371     bup restore -r SERVER: -C ./dest local-etc/latest/etc
372     ls -l dest/etc
373     ```
374
375  - Defend your backups from death rays (OK fine, more likely from the
376    occasional bad disk block).  This writes parity information
377    (currently via par2) for all of the existing data so that bup may
378    be able to recover from some amount of repository corruption:
379
380     ```sh
381     bup fsck -g
382     ```
383
384  - Use split/join instead of index/save/restore.  Try making a local
385    backup using tar:
386
387     ```sh
388     tar -cvf - /etc | bup split -n local-etc -vv
389     ```
390         
391  - Try restoring the tarball:
392
393     ```sh
394     bup join local-etc | tar -tf -
395     ```
396         
397  - Look at how much disk space your backup took:
398
399     ```sh
400     du -s ~/.bup
401     ```
402         
403  - Make another tar backup:
404
405     ```sh
406     tar -cvf - /etc | bup split -n local-etc -vv
407     ```
408         
409  - Look at how little extra space your second backup used on top of
410    the first:
411
412     ```sh
413     du -s ~/.bup
414     ```
415         
416  - Restore the first tar backup again (the ~1 is git notation for "one
417    older than the most recent"):
418
419     ```sh
420     bup join local-etc~1 | tar -tf -
421     ```
422  
423  - Get a list of your previous split-based backups:
424
425     ```sh
426     GIT_DIR=~/.bup git log local-etc
427     ```
428         
429  - Save a tar archive to a remote server (without tar -z to facilitate
430    deduplication):
431
432     ```sh
433     tar -cvf - /etc | bup split -r SERVERNAME: -n local-etc -vv
434     ```
435  
436  - Restore the archive:
437
438     ```sh
439     bup join -r SERVERNAME: local-etc | tar -tf -
440     ```
441         
442 That's all there is to it!
443
444
445 Notes on FreeBSD
446 ----------------
447
448 - FreeBSD's default 'make' command doesn't like bup's Makefile. In order to
449   compile the code, run tests and install bup, you need to install GNU Make
450   from the port named 'gmake' and use its executable instead in the commands
451   seen above. (i.e. 'gmake test' runs bup's test suite)
452
453 - Python's development headers are automatically installed with the 'python'
454   port so there's no need to install them separately.
455
456 - To use the 'bup fuse' command, you need to install the fuse kernel module
457   from the 'fusefs-kmod' port in the 'sysutils' section and the libraries from
458   the port named 'py-fusefs' in the 'devel' section.
459
460 - The 'par2' command can be found in the port named 'par2cmdline'.
461
462 - In order to compile the documentation, you need pandoc which can be found in
463   the port named 'hs-pandoc' in the 'textproc' section.
464
465
466 Notes on NetBSD/pkgsrc
467 ----------------------
468
469  - See pkgsrc/sysutils/bup, which should be the most recent stable
470    release and includes man pages.  It also has a reasonable set of
471    dependencies (git, par2, py-fuse-bindings).
472
473  - The "fuse-python" package referred to is hard to locate, and is a
474    separate tarball for the python language binding distributed by the
475    fuse project on sourceforge.  It is available as
476    pkgsrc/filesystems/py-fuse-bindings and on NetBSD 5, "bup fuse"
477    works with it.
478
479  - "bup fuse" presents every directory/file as inode 0.  The directory
480    traversal code ("fts") in NetBSD's libc will interpret this as a
481    cycle and error out, so "ls -R" and "find" will not work.
482
483  - There is no support for ACLs.  If/when some enterprising person
484    fixes this, adjust dev/compare-trees.
485
486
487 Notes on Cygwin
488 ---------------
489
490  - There is no support for ACLs.  If/when some enterprising person
491    fixes this, adjust dev/compare-trees.
492
493  - In test/ext/test-misc, two tests have been disabled.  These tests
494    check to see that repeated saves produce identical trees and that
495    an intervening index doesn't change the SHA1.  Apparently Cygwin
496    has some unusual behaviors with respect to access times (that
497    probably warrant further investigation).  Possibly related:
498    http://cygwin.com/ml/cygwin/2007-06/msg00436.html
499
500
501 Notes on OS X
502 -------------
503
504  - There is no support for ACLs.  If/when some enterprising person
505    fixes this, adjust dev/compare-trees.
506
507
508 How it works
509 ============
510
511 Basic storage:
512 --------------
513
514 bup stores its data in a git-formatted repository.  Unfortunately, git
515 itself doesn't actually behave very well for bup's use case (huge numbers of
516 files, files with huge sizes, retaining file permissions/ownership are
517 important), so we mostly don't use git's *code* except for a few helper
518 programs.  For example, bup has its own git packfile writer written in
519 python.
520
521 Basically, 'bup split' reads the data on stdin (or from files specified on
522 the command line), breaks it into chunks using a rolling checksum (similar to
523 rsync), and saves those chunks into a new git packfile.  There is at least one
524 git packfile per backup.
525
526 When deciding whether to write a particular chunk into the new packfile, bup
527 first checks all the other packfiles that exist to see if they already have that
528 chunk.  If they do, the chunk is skipped.
529
530 git packs come in two parts: the pack itself (*.pack) and the index (*.idx).
531 The index is pretty small, and contains a list of all the objects in the
532 pack.  Thus, when generating a remote backup, we don't have to have a copy
533 of the packfiles from the remote server: the local end just downloads a copy
534 of the server's *index* files, and compares objects against those when
535 generating the new pack, which it sends directly to the server.
536
537 The "-n" option to 'bup split' and 'bup save' is the name of the backup you
538 want to create, but it's actually implemented as a git branch.  So you can
539 do cute things like checkout a particular branch using git, and receive a
540 bunch of chunk files corresponding to the file you split.
541
542 If you use '-b' or '-t' or '-c' instead of '-n', bup split will output a
543 list of blobs, a tree containing that list of blobs, or a commit containing
544 that tree, respectively, to stdout.  You can use this to construct your own
545 scripts that do something with those values.
546
547 The bup index:
548 --------------
549
550 'bup index' walks through your filesystem and updates a file (whose name is,
551 by default, ~/.bup/bupindex) to contain the name, attributes, and an
552 optional git SHA1 (blob id) of each file and directory.
553
554 'bup save' basically just runs the equivalent of 'bup split' a whole bunch
555 of times, once per file in the index, and assembles a git tree
556 that contains all the resulting objects.  Among other things, that makes
557 'git diff' much more useful (compared to splitting a tarball, which is
558 essentially a big binary blob).  However, since bup splits large files into
559 smaller chunks, the resulting tree structure doesn't *exactly* correspond to
560 what git itself would have stored.  Also, the tree format used by 'bup save'
561 will probably change in the future to support storing file ownership, more
562 complex file permissions, and so on.
563
564 If a file has previously been written by 'bup save', then its git blob/tree
565 id is stored in the index.  This lets 'bup save' avoid reading that file to
566 produce future incremental backups, which means it can go *very* fast unless
567 a lot of files have changed.
568
569  
570 Things that are stupid for now but which we'll fix later
571 ========================================================
572
573 Help with any of these problems, or others, is very welcome.  Join the
574 mailing list (see below) if you'd like to help.
575
576  - 'bup save' and 'bup restore' have immature metadata support.
577  
578     On the plus side, they actually do have support now, but it's new,
579     and not remotely as well tested as tar/rsync/whatever's.  However,
580     you have to start somewhere, and as of 0.25, we think it's ready
581     for more general use.  Please let us know if you have any trouble.
582
583     Also, if any strip or graft-style options are specified to 'bup
584     save', then no metadata will be written for the root directory.
585     That's obviously less than ideal.
586
587  - bup is overly optimistic about mmap.  Right now bup just assumes
588    that it can mmap as large a block as it likes, and that mmap will
589    never fail.  Yeah, right... If nothing else, this has failed on
590    32-bit architectures (and 31-bit is even worse -- looking at you,
591    s390).
592
593    To fix this, we might just implement a FakeMmap[1] class that uses
594    normal file IO and handles all of the mmap methods[2] that bup
595    actually calls.  Then we'd swap in one of those whenever mmap
596    fails.
597
598    This would also require implementing some of the methods needed to
599    support "[]" array access, probably at a minimum __getitem__,
600    __setitem__, and __setslice__ [3].
601
602      [1] http://comments.gmane.org/gmane.comp.sysutils.backup.bup/613
603      [2] http://docs.python.org/2/library/mmap.html
604      [3] http://docs.python.org/2/reference/datamodel.html#emulating-container-types
605
606  - 'bup index' is slower than it should be.
607  
608     It's still rather fast: it can iterate through all the filenames on my
609     600,000 file filesystem in a few seconds.  But it still needs to rewrite
610     the entire index file just to add a single filename, which is pretty
611     nasty; it should just leave the new files in a second "extra index" file
612     or something.
613    
614  - bup could use inotify for *really* efficient incremental backups.
615
616     You could even have your system doing "continuous" backups: whenever a
617     file changes, we immediately send an image of it to the server.  We could
618     give the continuous-backup process a really low CPU and I/O priority so
619     you wouldn't even know it was running.
620
621  - bup only has experimental support for pruning old backups.
622
623    While you should now be able to drop old saves and branches with
624    `bup rm`, and reclaim the space occupied by data that's no longer
625    needed by other backups with `bup gc`, these commands are
626    experimental, and should be handled with great care.  See the
627    man pages for more information.
628
629    Unless you want to help test the new commands, one possible
630    workaround is to just start a new BUP_DIR occasionally,
631    i.e. bup-2013, bup-2014...
632
633  - bup has never been tested on anything but Linux, FreeBSD, NetBSD,
634    OS X, and Windows+Cygwin.
635  
636     There's nothing that makes it *inherently* non-portable, though, so
637     that's mostly a matter of someone putting in some effort.  (For a
638     "native" Windows port, the most annoying thing is the absence of ssh in
639     a default Windows installation.)
640     
641  - bup needs better documentation.
642  
643     According to an article about bup in Linux Weekly News
644     (https://lwn.net/Articles/380983/), "it's a bit short on examples and
645     a user guide would be nice."  Documentation is the sort of thing that
646     will never be great unless someone from outside contributes it (since
647     the developers can never remember which parts are hard to understand).
648     
649  - bup is "relatively speedy" and has "pretty good" compression.
650  
651     ...according to the same LWN article.  Clearly neither of those is good
652     enough.  We should have awe-inspiring speed and crazy-good compression. 
653     Must work on that.  Writing more parts in C might help with the speed.
654    
655  - bup has no GUI.
656  
657    Actually, that's not stupid, but you might consider it a
658    limitation.  See the ["Related Projects"](https://bup.github.io/)
659    list for some possible options.
660     
661 More Documentation
662 ==================
663
664 bup has an extensive set of man pages.  Try using 'bup help' to get
665 started, or use 'bup help SUBCOMMAND' for any bup subcommand (like split,
666 join, index, save, etc.) to get details on that command.
667
668 For further technical details, please see ./DESIGN.
669
670
671 How you can help
672 ================
673
674 bup is a work in progress and there are many ways it can still be improved.
675 If you'd like to contribute patches, ideas, or bug reports, please join the
676 <a href="mailto:bup-list@googlegroups.com">bup mailing list</a>:
677
678 You can find the mailing list archives here:
679
680         http://groups.google.com/group/bup-list
681         
682 and you can subscribe by sending a message to:
683
684         bup-list+subscribe@googlegroups.com
685
686 You can also reach us via the
687 \#bup IRC channel at ircs://irc.libera.chat:6697/bup
688 on the [libera.chat](https://libera.chat/) network or via this
689 [web interface](https://web.libera.chat/?channels=bup).
690
691 Please see <a href="HACKING">./HACKING</a> for
692 additional information, i.e. how to submit patches (hint - no pull
693 requests), how we handle branches, etc.
694
695
696 Have fun,
697
698 Avery
699
700 <!--
701 Local Variables:
702 mode: markdown
703 End:
704 -->