2013-12-05 23:22

Bsync is a bidirectional file synchronization tool, using rsync for transfers. Moved files are also synchronized in a smart way.

It uses rsync for file transfers, find to generate filelist snapshots, and ssh for remote transfers.

bsync is an alternative to Unison, written in Python 3. A big strength of bsync: it can detect and apply moved files from one side to the other (Unison uses some copy calls to handle moved files).

I developped it to be able to synchronize my music directory from my laptop to my Raspberry Pi in an efficient way, and to sync with my girlfriend laptop too.

Bsync is released under GPL. Feel free to report any bugs/wishes in GitHub issues.

More info, Download and Install on the GitHub repo.

2013-12-05 23:22 · Tags: , , , , ,

8 Comments

  1. Intéressant !
    Quelques questions :
    - peux-tu expliquer la différence avec csync (http://www.csync.org/) ?
    - que se passe-t’il en cas de conflit avec bsync ?

    Reply

  2. Hey!

    csync has similar features, however, for now csync doesn’t ask the user when there are conflicts.
    A merge algorithm is used (most recent file). When working alone on files, this is generally not a problem, however if 2 different persons add some changes to one file in both directories, one version will be lost.

    csync stores history in a central database in ~/.csync
    bsync stores history directly in the directories (git like).

    I added a sample run with a conflict here: https://github.com/dooblem/bsync

    Reply

  3. Cerem Cem ASLAN

    I loved bsync. It is easy to use and has distributed database, and written in Python.

    There is a problem:
    1. What if DIRX is a ssh location on a different port other than 22? What is the syntax?

    There is my WISH/TODO list:
    1. When about to sync directories, change list should be redisplayed briefly. If I expect “there should be no copy from DIR1 to DIR2″, I should see it in the last part, before “yes/no” prompt, something like:

    file copies –> : 3
    file copies <– : 89
    yes/no?

    2. Database should keep a track of mount information. If any of the directories was mounted before and not now, sync should be canceled.

    3. There should be a versioning option. This will be good for safety and other usages.

    Reply

    • Hi,

      Thanks for your feedback.

      1. What if DIRX is a ssh location on a different port other than 22? What is the syntax?

      I just commited a patch a few days ago, you should be able to use the -p flag for that.

      1. When about to sync directories, change list should be redisplayed briefly. If I expect “there should be no copy from DIR1 to DIR2″, I should see it in the last part, before “yes/no” prompt, something like:

      file copies –> : 3
      file copies < – : 89
      yes/no?

      Good idea. I just added a Wishlist ticket on github : https://github.com/dooblem/bsync/issues/1
      Feel free to comment it if needed.

      2. Database should keep a track of mount information. If any of the directories was mounted before and not now, sync should be canceled.

      I’m not sure bsync should be aware of mount points (do you expect rsync to be aware of that ?). But if any mount point changes, the user should see the problem in the transfer summary and cancel it.
      With the summary feature you just asked it should be ok no ?
      What you could also do is make a bash wrapper script around bsync that exports the mount points before each sync, and exits if a mount point changes.

      3. There should be a versioning option. This will be good for safety and other usages.

      If you need full versioning, you can use git for that. But we may have an option like the –backup flag of rsync.

      Reply

  4. F. Chabaud

    Merci pour ce petit utilitaire simple et bien pratique.
    Comme je l’utilise dans une crontab et que je n’ai pas envie de recevoir des messages quand il ne se passe rien j’ai rajouté deux options :
    -b : mode batch non interactif (toutes les actions sont réalisées)
    -n : mode dry-run pour les tests (aucune action réalisée)

    — bsync.1 2014-08-29 19:07:53.295304257 +0200
    +++ bsync 2014-08-29 19:15:58.445350377 +0200
    @@ -521,9 +521,11 @@
    print(” 1a Keep left version for all”)
    print(” 2a Keep right version for all”)
    print(” Please note: you will be able to confirm the actions later.\n”)
    -
    - resp = myinput(“Which one do I keep? [1/2/1a/2a/Quit/Help] “)
    -
    +
    + if interactive:
    + resp = myinput(“Which one do I keep? [1/2/1a/2a/Quit/Help] “)
    + else
    + sys.exit(1)
    if resp == “1″ or resp == “2″ or resp == “1a” or resp == “2a”:
    return resp
    elif resp == “q” or resp == “Q” or resp == “Quit”:
    @@ -736,6 +738,8 @@
    usage+= ” DIR can be user@sshserver:DIR\n”
    usage+= ” -v Verbose\n”
    usage+= ” -i Ignore permissions\n”
    + usage+= ” -b Batch script (non interactive automatic approval)\n”
    + usage+= ” -n Dry-run (non interactive dry-run)\n”
    usage+= ” -p PORT Port for SSH\n”
    usage+= ” -o SSHARGS Custom options for SSH\n”
    printerr(usage)
    @@ -744,13 +748,14 @@

    #### process commandline args
    try:
    - opts, args = getopt.gnu_getopt(sys.argv[1:], “vcip:o:”)
    + opts, args = getopt.gnu_getopt(sys.argv[1:], “vcbnip:o:”)
    except getopt.GetoptError as err:
    printerr(err)
    usage()
    sys.exit(2)

    -verbose = check = ignoreperms = False
    +verbose = check = ignoreperms = dryrun = False
    +interactive = True
    sshport = None
    sshargs = “”
    for o, a in opts:
    @@ -760,6 +765,10 @@
    ignoreperms = True
    elif o == “-c”:
    check = True
    + elif o == “-n”:
    + dryrun = True
    + elif o == “-b”:
    + interactive = False
    elif o == “-p”:
    sshport = a
    elif o == “-o”:
    @@ -804,7 +813,7 @@
    except:
    console_width = 0

    -print(“Loading filelists…”)
    +if interactive: print(“Loading filelists…”)

    printv(“Loading original filelist from snap files…”)
    snapname, origlist, ignores = load_orig(ssh1,dir1name, ssh2,dir2name)
    @@ -1000,7 +1009,7 @@
    if len(mkdir1)==0 and len(moves1)==0 and len(rm1)==0 and len(rmdirs1)==0 and len(copy21)==0 and len(sync21)==0 and \
    len(mkdir2)==0 and len(moves2)==0 and len(rm2)==0 and len(rmdirs2)==0 and len(copy12)==0 and len(sync12)==0:
    if check: rsync_check(ssh1,dir1name, ssh2,dir2name)
    - print(“Identical directories. Nothing to do.”)
    + if interactive: print(“Identical directories. Nothing to do.”)
    if snapname == None:
    make_snapshots(ssh1,dir1name, ssh2,dir2name, snapname)
    sys.exit()
    @@ -1017,10 +1026,12 @@
    print(“Todo in “+args[1]+”: “+get_dir_summary(mkdir2,moves2,rm2,rmdirs2, copy12,sync12))

    resp = “none”
    -while resp != “y” and resp != “n”:
    - resp = myinput(“Apply actions? [y/N] “).lower()
    - if resp == “”: resp = “n”
    -print()
    +if dryrun: resp = “n”
    +if interactive:
    + while resp != “y” and resp != “n”:
    + resp = myinput(“Apply actions? [y/N] “).lower()
    + if resp == “”: resp = “n”
    + print()
    if resp == “n”:
    print(“Leaving files in place.”)
    sys.exit()

    Reply

  5. Bonjour,
    est-ce qu’une GUI serait possible d’après vous ? je suis asse fan de l’efficacité de celle d’unison mais je ne l’utilise plus à cause du temps de création de ses archives à chaque fois qu’on a un nouveau “truc” à synchroniser (ce qui m’arrive tout le temps).
    Je suis passé à bsync, un plaisir, mais impossible de le mettre entre les mains des personnes qui m’entourent, ouvrir une console … comment dire :p

    Merci d’avance,
    Éric

    Reply

    • Bonjour Eric,
      Je n’ai malheureusement plus le temps de m’occuper de bsync ces temps-ci.
      Mais toute contribution est la bienvenue !
      Marc

      Reply

  6. Great utility, thanks for this. I’m looking to keep a remote directory in sync by running this nightly, any way I could disable prompts for confirmations on file transfers?

    Reply

Leave a Reply to Cerem Cem ASLAN Cancel reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>