Sync up two beets directories

I’m using beets to manage my music collection. I have a part of my music collection on my laptop, an external harddisk where all the music is and another external harddisk as a backup. From time to time I add new music on my laptop, and I would like to have it on the harddisks as well. How can I transfer all the new music onto the harddisk? To ask the question otherwise, if I have a collection managed with beets, how do I take a directory and copy all the music that isn’t in the collection into the collection, without touching the directory? Bear in mind that most of the music in the directory is already in the collection, and I can’t just copy everything into the collection and sort for duplicates afterwards because the harddisk doesn’t have enough space.
If there was a way to compare two beets musicdata files it would be much easier, just make a beets collection of the directory and then compare the two musicdata files and copy what is needed, but as far as I know this feature has not been implemented.
I don’t know if this is possible with the current beets commands, I couldn’t find out how, but maybe you know? Or maybe this needs a pull request?

Hi Dorian,

Beets doesn’t currently handle multiple music repositories, although people have requested similar things before. There are a few options depending on your workflow.

If you’re saying that you might add new music to the hard disk and then later want to pick it up in your other beets library on your laptop, one thing you might consider is the duplicate_action configuration item. That lets you tell beets’ importer what to do when it finds an album that’s already in your library. If you set it to skip then it will skip duplicates when importing without prompting.

If on the other hand you just want a copy of your music on the hard disk that reflects what’s on your laptop, then you could just synchronise the files with a tool like rsync. You’d only really need a single beets library (on your laptop).

If you want a list of files in the library, you can use beet ls -f '$path'. You could compare this to the directory listing (e.g. find . -type f) to discover which files are missing from the library.

1 Like

Thanks for your quick reply. Concerning duplicate_action, does it also work when the data is imported without autotag? One solution I used was to import with -A which makes the import way quicker, but I’m afraid that it makes the duplicate handling difficult, as I use the tags mb_trackid, mb_releasegroupid and track as keys and they are not stored in the files as far as I know.
I don’t want to have a hard disk that reflects what is on my laptop. I have a hard disk where everything is and a laptop where I keep a selection (to listen to while working) and all the stuff I ripped in the latest time. I want to copy what has been ripped to the harddisk and not move the rest. However, it has proven not practical to just keep the ripped stuff somewhere else than the selection, so I have a folder where everything is mixed.
Keep in mind that I’m talking of music collections of the order of 500 GB, so a ‘quick import’ won’t do the trick, I need a procedure that I could ideally let do overnight.

As an additional backup, I have a second harddisk with the same music as the first one, with the exception that to save space, I use different duplicate keys: they are mb_trackid and track instead of mb_trackid, mb_releasegroupid and track . I would like the two to be synchronized as well.

The MusicBrainz tags should indeed be stored in the files themselves:

I would therefore expect the duplicate detection to work without the autotagger, though I haven’t tried this myself.

In general I think it’s going to be easier to keep a single authoritative beets library that contains the whole collection, and a separate copy of whatever selection you like. For my own use, I created a flexible field called sync that I set on albums I want to sync to my music player. I wrote a little plugin for myself that copies tagged files to my device whenever I (un)set this field. I know that there are public plugins that do similar things.

If I’m following correctly your problem is that the copies on your laptop are later mixed with new untagged files and you later on want to find those untagged files. Let’s imagine you have a setup similar to what I described, where the beets library lives with the full collection on your HD and the subset that made it to your laptop has been marked with a flexible field in the library. Then it would be possible as your library for a list of files it put on your laptop (e.g. beet ls -f '$path' sync:laptop | sed -e 's,/path/to/library/on/hd,/path/to/music/on/laptop,'). Anything that’s on your laptop that doesn’t appear in that list must be something the library doesn’t know about and you can import it.

I hope that made sense!

In general I think it’s going to be easier to keep a single authoritative beets library that contains the whole collection, and a separate copy of whatever selection you like.

Yes, and that’s what I’m doing. However, as the whole library is too big to fit on my laptop, I put a selection on the laptop. The problem is that it is the same laptop I use for ripping CDs so new additions will end up on the laptop and will need to be synced with the reference on the harddisk, which is exactly what I’m trying to do. But thanks, I will check if the duplicate detection works with disabled autotagger. A little sidenote: what if the new one is better and I would rather use the new one (for example, better audio quality), can duplicate detection handle this? As far as I know no, but you probably know better.

It sounds like I understood correctly. My suggestion was to use the library on your harddrive to also track which files from your library that are copied on your laptop. Any files not on that list must be new ones you’ve ripped, ready for importing.

The duplicate plugin has a tiebreak config item explained in the docs that’s exactly for that purpose. You can use a field like bitrate to prefer a higher-quality duplicate.

Thanks! I will try that out.