def sync_from_log(src, dst, log_file, exclude=()):
from os.path import join, exists, isdir<EOL>exclude = [os.path.normpath(i) for i in exclude]<EOL>added, removed = [], []<EOL>if not exists(log_file):<EOL><INDENT>print("<STR_LIT>" % log_file)<EOL><DEDENT>else:<EOL><INDENT>with open(log_file) as f:<EOL><INDENT>files = f.read().strip().split('<STR_LIT:\n>')<EOL><DEDENT>for new_f in files:<EOL><INDENT>new_f = new_f.strip()<EOL>if any(is_subdir(new_f, os.path.join(dst, i)) for i in exclude):<EOL><INDENT>pass<EOL><DEDENT>elif exists(new_f):<EOL><INDENT>os.remove(new_f)<EOL>removed.append(new_f)<EOL><DEDENT>else:<EOL><INDENT>print("<STR_LIT>" % new_f, file=sys.stderr)<EOL><DEDENT><DEDENT><DEDENT>if os.path.isdir(src):<EOL><INDENT>if not src.endswith(os.sep):<EOL><INDENT>src += os.sep<EOL><DEDENT>files = glob.iglob(join(src, '<STR_LIT>'), recursive=True)<EOL><DEDENT>else:<EOL><INDENT>files = [src]<EOL>src = os.path.dirname(src) + os.sep if os.sep in src else '<STR_LIT>'<EOL>os.makedirs(dst, exist_ok=True)<EOL><DEDENT>for f in sorted(files):<EOL><INDENT>if any(is_subdir(f, os.path.join(src, i)) for i in exclude):<EOL><INDENT>continue<EOL><DEDENT>new_f = join(dst, f[len(src):])<EOL>if isdir(f) or f.endswith(os.sep):<EOL><INDENT>os.makedirs(new_f, exist_ok=True)<EOL><DEDENT>else:<EOL><INDENT>shutil.copy2(f, new_f)<EOL>added.append(new_f)<EOL>if new_f in removed:<EOL><INDENT>removed.remove(new_f)<EOL><DEDENT><DEDENT><DEDENT>with open(log_file, '<STR_LIT:w>') as f:<EOL><INDENT>f.write('<STR_LIT:\n>'.join(added))<EOL><DEDENT>added.append(log_file)<EOL>return added, removed<EOL>
Sync the files in ``src`` to ``dst``.

The files that are synced are logged to ``log_file``. If ``log_file``
exists, the files in ``log_file`` are removed first.

Returns ``(added, removed)``, where added is a list of all files synced from
``src`` (even if it already existed in ``dst``), and ``removed`` is every
file from ``log_file`` that was removed from ``dst`` because it wasn't in
``src``. ``added`` also includes the log file.

``exclude`` may be a list of paths from ``src`` that should be ignored.
Such paths are neither added nor removed, even if they are in the logfile.