Bem, eu não achava que conseguiria fazer isso até que descobri recentemente um truque bacana que você pode fazer com o rsync e, como ninguém respondeu em algum momento, apresentarei minha solução.
O truque é quando você usa os seguintes argumentos:
rsync --suffix "" --backup-dir "." ...
Isso faz com que o rsync faça backup de arquivos antes de modificá-los, mas os backups acabam sendo in-loco, então você está realmente fazendo cópias dos arquivos antes de modificá-los. Isso permite que você altere os arquivos com link físico sem alterar os originais.
Então, a sequência para realizar o comportamento desejado pode ser a seguinte:
# locally hard-link the mutable files
rsync -ahv --link-dest C --include-from MUTABLE_FILES.filter C/* B
# copy locally + append remotely changed files
# (also delete mutable files that disappeared at remote location A)
rsync -ahbv --suffix "" --backup-dir "." --append-verify \
--include-from MUTABLE_FILES.filter --delete A/* B
# now hard-link locally + transfer immutable files
rsync -ahv --link-dest C --include-from IMMUTABLE_FILES.filter A/* B
Isso provavelmente poderia ser resolvido com as duas primeiras etapas sem usar filtros, mas no meu caso de uso particular para garantir a coerência no destino final eu preciso dos arquivos mutáveis transferidos antes dos imutáveis, e a ordenação alfabética padrão feita pelo rsync não garanto isso no meu caso. A razão pela qual eu preciso disso é que os arquivos mutáveis podem ser excluídos e substituídos por um arquivo imutável. Se eu não transferi o arquivo imutável porque ele não existia no momento, mas o mutável desaparece antes de eu chegar nele, não tenho nenhum dos dois e perco os dados.