Preface

This is an early draft of the usage guide, as it was before this system's scripts were translated to Python. It's no longer maintained, and is retained only because it may be relevant to the Bash-script originals in this folder. The main folder above hosts the official guide, which has moved on substantially from the draft here; please see it for up-to-date usage info.

Android Deltas Sync: Bash Version

Version:  (Draft, September 29, 2021)
License:  Provided freely, but with no warranties of any kind
Author:  © M. Lutz (learning-python.com) 2021
Install:  Unzip the download, browse code, see ahead
Start:  Run with Bash, on macOS/Windows/Linux and Android
Web:  See this package's rationale here and here

This doc's package was born of frustration with the twin removals of POSIX USB access in Android 11, and microSD-card support in Samsung's flagship phones. Those removals crippled content-processing tools, as covered here and here. This doc leaves the drama behind, and focuses instead on how to use the work-around embodied in this package's scripts. It starts with a brief overview, followed by a quick start, additional usage details, and general notes.

Overview

This package provides Bash scripts that automate steps used to copy content from a PC to an Android device initially, and sync the Android device's copy later for changes made on the PC. PC here means any macOS, Windows, or Linux computer, and Android device means any Android phone or tablet—though "phone" includes tablets here for brevity, and this package is primarily of interest to users of Android 11 and later (see Scope ahead).

In brief, the scripts here:

The net effect allows POSIX programs like Mergeall to be used for content management on Android 11 and later, and propagates content from PC to phone safely and easily. The next section explains the process that achieves this.

How the Work-Around Works

To sync changes from PC to phone, this system leverages a proxy drive, which takes the place of the phone for change detection: as long as the proxy's content copy is always the same as the phone's, PC-to-proxy changes double as PC-to-phone changes, and can be computed independently of the phone. The proxy's role is similar to an intermediate drive in earlier Mergeall models, and partly replaces now-defunct microSD cards. Under Android 11, however, the proxy's content copy cannot be merged to the phone directly by USB with Mergeall.

To address this loss of USB access, this system also employs a new Mergeall script, deltas.py. This script detects differences between FROM and TO as usual, but instead of applying FROM changes to TO immediately like a normal sync, it saves the changes separately to a folder, in the same format as Mergeall backups. This allows changes to be both archived as a unit, and applied to TO later with a Mergeall -restore run. Because change sets are almost always very small, both tasks are almost always very quick.

By combining the new script's deferred changes with the proxy's forgery, this system is able to apply changes to the phone transitively: changes are collected by comparing the PC's content copy to the proxy's; transferred from the proxy to the phone manually with a file explorer; and finally applied to the phone itself. The net effect updates the phone for changes on the PC indirectly, without requiring POSIX USB access on the phone.

Beyond orchestrating the new script and proxy, this system also ensures that content is zipped and unzipped to evade interoperability perils in filesystems and platforms along the way. Depending on the target of content propagations, this can avoid loss of symlinks, permissions, folder modtimes, and nonportable filenames, all of which may otherwise be silently munged in raw transfers. Zipping also minimizes the role of Android file explorers, which are generally slow, and frequently fail for larger copies.

This may sound like a lot of work (and it is, compared to the direct two-merge process before Android 11), but it's still well worth the effort for people who don't want to store their private digital property on clouds, where it can be arbitrarily misused by hosting companies.

How You'll Use the System

The good news is that this package's scripts automate most of the details behind these indirect syncs. In short, you will simply:

  1. Setup your PC and phone to run Python, Mergeall, and these scripts
  2. Pick a USB drive whose content copy will be used as proxy for your phone
  3. Run scripts here to copy content to your proxy and phone initially
  4. Run scripts here to sync changes from PC to phone, via proxy
The rest of this doc provides a brief reference guide to this process, followed by more-complete details.

Quick Start

In the following, you'll generally run the setup tasks and initial copy just once, and repeat the sync steps any time you wish to propagate changes from PC to phone. Skip steps you've already performed, but see Installs ahead for specific version requirements.

Setup: Install Python

On PC:

  1. Install Python 3.X if not already present, from python.org

On Phone:

  1. Install the free Termux app, from Google Play or F-Droid
  2. Install Python 3.X in Termux, with command pkg install python

Setup: Install Mergeall and Scripts

On both PC and phone:

  1. Fetch Mergeall's source-code package from learning-python.com, and unzip
  2. Fetch this script package from learning-python.com, and unzip
  3. Edit this package's config-pc.txt on PC, and config-phone.txt on phone

Setup: Choose a Proxy Drive

Dedicate an external USB "proxy" drive to host a content copy that will serve as a stand-in for your phone in later syncs. This copy should never be changed except by this system's scripts, else change detection won't work and you may have to rerun an initial copy.

The drive should be large enough to hold your content and more—twice as large for initial copies, but a smaller increment for later change syncs (see space requirements ahead). exFAT is recommended for the proxy for its larger file sizes and friendlier modtimes, but any filesystem supported by both your PC and phone will do.

To Run a One-Time Initial Copy

  1. Plug your proxy drive into your PC, and on your PC run command:
    bash initial-copy-part1-pc.sh
  2. Plug your proxy drive into your phone, and on your phone run command:
    bash initial-copy-part2-phone.sh

To Run All Later Content Syncs

  1. Plug your proxy drive into your PC, and on your PC run command:
    bash sync-changes-part1-pc.sh
  2. Plug your proxy drive into your phone, and on your phone run command:
    bash sync-changes-part2-phone.sh

Usage Details

Installs
Download and unzip Mergeall and this package to any folder (Download suffices on Android). This system requires Mergeall 3.2 or later, for its deltas.py script and included ziptools. ziptools 1.3 or later is also required, but is shipped with Mergeall 3.2; it can be found separately at learning-python.com here. This system works with any Python 3.X; install Python only if not already present, and see the web for PC install tips. See also PC and Android file explorers for unzip options; you can use ziptools to unzip install packages, but not until you've unzipped it.
Space
The initial-copy scripts here temporarily require twice as much space on your proxy drive and phone as your content collection itself. This stems from their use of zipfiles to avoid interoperability issues. If your devices don't have enough space, see the later caveats on proxy and phone space for manual work-arounds. By contrast, the sync scripts here require only enough extra space for changes sets, which are normally very small and transfer quickly.
Configs
Edit both config-pc.txt and config-phone.txt to set paths to code and content on your PC and phone, respectively. See these files' top comments for directions. You need edit only the file for the host—edit the PC file on the PC, and the phone file on the phone.

These files are technically Bash code, but the settings are few and simple. Two syntax tips: use single quotes ('...') for paths with spaces and other non-alphanumeric oddities, but don't add a space around the "=" in assignments.

Storage
In the phone config file, you'll need to choose one of three on-phone storage categories to host your content. In brief: Most Android file explorers can access shared and app-specific storage for content views and changes, though this varies by app and Android version. Paths may vary too, and perhaps even by vendor (e.g., /sdcard is also /storage/emulated/0); see the primer here.
Commands
Run the Quick Start's bash commands in Termux on your phone, and in a Unix shell on your PC—in Terminal on macOS and Linux, and Cygwin or the Linux subsystem (WSL) on Windows.

Depending on where you unzipped this package, its scripts may not be in the folder you start at in your command tool. If so, add their path to the front of their names in the commands above (e.g., bash path/script.sh), or cd to their folder first.

Copies
On your phone, you will be instructed to manually copy a zipfile from the proxy drive's root to a specific phone folder, during both the initial copy and later syncs. Copy zipfiles using any Android file explorer which has permission to access the storage location to which you are copying; most will suffice, because this is a single-file copy.

This copy must be a manual step, because it cannot be run by command line in Termux. Like all other POSIX programs, Termux no longer has direct access to USB in Android 11, per this coverage. This is the only manual step in initial copies and later syncs.

Interaction
Press enter/return to continue when prompted about a new step starting; step runtimes are displayed in the console after each step completes. To avoid having to press enter between steps, set PauseSteps=n in either or both config files. A control-C at a pre-step pause's prompt kills the running script, but may leave temporary zipfiles behind; see the killed script for details on its progress.
Logfiles
Step logfiles show up in your folder config-files setting: read them there later, or monitor step progress with tail -f $L/filename at a console run in a different window. On your phone in Termux, you can open a new session to tail logfiles and switch sessions by swiping in from the top left. Don't control-Z to background a step in the run window; it may terminate timing.
Verifications
There is no way to verify the on-phone content copy against the proxy or PC copies, because POSIX code like Python can't access USB drives directly in Android 11, and phone access by MTP and network servers is not fully usable. The phone might be compared to the proxy after syncs by manually copying full zipped content from proxy to phone (or vice versa), but this is too slow to automate here.

As a partial measure, setting VerifyProxy=y in the PC config file runs mergeall and diffall to verify the proxy's content against the PC's in both initial copies and later syncs. You are prompted to confirm this step, because it adds time to the run.

Previews
The Mergeall deltas.py script supports the -report option to preview differences without saving them, though using the same switch with mergeall.py has the same effect. This preview is run initially by the syncs PC script, if PreviewSyncs=y in the PC config file.

Use these previews as desired to inspect deltas before writing them to disk; this may, for example, avoid full copies at DST rollovers for FAT32 proxy drives (see Mergeall docs). You are prompted to confirm this step, because it adds time to the run.

Filenames
This system offers to run Mergeall's fixer tool for nonportable filenames on the PC. This step is recommended when transferring content or changes from Unix to Windows, some Android's shared storage, or proxy drives using FAT32 or exFAT. For more on this step, see the comments in Mergeall's fixer tool or ziptools' related coverage here. The offer can be disabled by setting CheckFilenames=n in the PC configs file.
Rollbacks
If ever needed, changes made by applying a deltas set here can be fully rolled back (i.e., undone), by manually running another mergeall.py -restore command, passing the backups set saved in the archive's __bkp__ folder. See Mergeall's docs, as well as "ROLLBACKS" in deltas.py's main docstring for usage details.
Finalization
Depending on your use case, you may wish to edit the z-postcopy-hook-phone.sh script, to add custom steps required after to-phone copies are finished. This script is run at the end of both the initial-copy and synch-changes phone scripts. It's shipped with no commands, but any Bash code you add to it will be run after all to-phone content propagations.

As an example, you might expand this script if you're keeping your full content in Termux's app-specific storage for speed, and need to copy specific folders to shared storage so it can be accessed by apps with limited permissions—including tkinter GUIs run in Pydroid 3. This won't help, however, for copying website content to browsers' app-specific storage so it can be viewed locally; Termux cannot access other apps' app-specific storage in Android 11, so a file explorer with broader permissions is required.

General Notes

Background docs
See the overview page for more on this system's scripts, and this folder for the unzipped content of this package. If you are new to Mergeall, the best starting points are its main web page and user guide. For more on the ziptools system used throughout these scripts, start at its web page or user guide. For this system's rationale in general, try this and this.
Coding notes
These are Bash shell scripts. They could be coded in Python for portability, but are largely just command lines, and Windows' Subsystem for Linux (WSL) may suffice as a host. Nit: ziptools is shipped both stand-alone and as a tool embedded in the Mergeall package; scripts here use Mergeall's copy, but the stand-alone version is apt to be more recent; if needed, you can enable newer ziptools installs in common.sh.
Times and logs
These scripts use the Bash time command to display step run times, but this command ends timing prematurely on control-Z to background a step. An alternative /usr/bin/time survives control-Z, but isn't present on phone in Termux, and doesn't respect Bash settings as well. Both timers work with & backgrounding, but this is unusable in this serial system. As a general rule: open another console to tail log files during runs, per Logfiles above.
Why zips
This system zips content for transfer to minimize the risks of data loss and copy failures. Else, some copy destinations drop folder modtimes, symlinks, and permissions, and may discard or covertly rename files with nonportable names. Worse, Android file explorers run very slowly for raw folder copies, and may even fail to finish (without naming names, multiple apps fully hung while testing copies of large folders, and some suffered disk unmounts). Zipping content neutralizes all these factors in full. As a bonus, zips are also generally much faster to transfer than individual files on every device. Unzips can even outpace raw copies, because the former opens just one input file: see the initial-copy script's cpall note.
Why not a GUI
A cross-platform deltas create/apply GUI was rejected for this project for a number of reasons. For one, in the simplest use case with no zips, syncs would require two runs in the GUI on PC (create deltas, apply deltas), and forgetting the second would leave the proxy different than the phone. For another, zips are nearly required per the preceding note, and this makes for numerous steps (four on both PC and phone; see the scripts). Automating steps and zips in scripts is far less error prone.
Size caveat: FAT32
This system won't work with a FAT32 proxy drive if content or deltas zipfiles are larger than 4G (this is a FAT32 limit). If your zips are that large, reformat the proxy drive to use exFAT or another more-functional filesystem supported by both your PC and your phone, or use raw copies in file explorers. Most recent Android phones support exFAT, but test to be sure.
Size caveat: proxy
As coded, the initial-copy-part1-pc.sh script requires twice as much space on your proxy drive as your content collection, to hold both a content copy and an uncompressed content zip. This is necessary because stingier alternatives have too many steps to automate. If your proxy doesn't have enough space, simply run this script's steps manually, but move the zip to your phone before copying content to the proxy. The upside is that this space requirement is temporary (the zip may be manually removed from the proxy after the to-phone transfer), and applies only to the initial content copy (later syncs require just enough extra space for normally small change sets).
Size caveat: phone
As coded, the initial-copy-part2-phone.sh script requires twice as much space on your phone as your content collection, to hold both an uncompressed content zip and a content copy. This is necessary to avoid issues in Android file explorers, which have been seen to fail for direct copies of larger content collections. If your phone doesn't have enough space, manually copy unzipped content from proxy to phone by file explorer, and run this script's other steps manually as needed. This script deletes the zip from the phone automatically after unzipping, and its size requirement also applies only to the initial content copy.
Skew caveat: proxy vs phone
It's rare but not impossible that the proxy drive's content copy may differ slightly from that on the phone for which is stands in, because the phone's copy reflects PC zipfiles, not the proxy itself. The two copies should never differ for normal content (files and folders) and its modtimes, but exotica like symlinks and Unix permissions may differ across proxy filesystems and Android storage types. This should be irrelevant as long as the proxy suffices for syncs to PC (e.g. macOS symlink stub files on exFAT drives will compare correctly), and zipping on proxy itself would slow initial copies and syncs.
Scope
This system is primarily meant for Android 11 and later. It works on Android 10 and earlier too, but may be overkill there. Prior to 11, you can simply run two direct Mergealls by USB: from PC to external drive, and from external drive to phone—and using either Mergeall's command lines or GUI for both. See Mergeall's original docs for its simpler usage on less restrictive platforms, including PCs and earlier Androids.

In the end, Android 11's removal of USB access for POSIX programs convolutes this story badly and remains an affront to usability and interoperability, while Samsung's removal of microSD cards seals the door tighter. Even so, this package's scripts manage to subvert whatever storage agendas may be.

 

[Python Logo] Top Code Fold3 Android11 Android Mergeall Mergeall Ziptools Input ©M.Lutz