overleaf-ce-sync
Sincronización bidireccional «al estilo git» para Overleaf Community Edition autoalojado.
La integración nativa con Git (git-bridge) es una función de Server Pro y no
se puede usar con CE: la Snapshot API y el servidor OAuth2 que necesita están en
módulos de código cerrado. Esta herramienta ofrece lo más parecido: bajar un
proyecto al disco, versionarlo con tu propio git y subir los cambios.
Usa los mismos endpoints HTTP que la interfaz web. El login por HTTP simple, que en overleaf.com no funciona por el CAPTCHA, anda bien en CE porque CE no tiene CAPTCHA.
Instalación
Con pipx (entorno aislado, overleaf-ce-sync en el PATH):
git clone https://git.all.ar/pub/overleaf-ce-sync.git
cd overleaf-ce-sync
pipx install -e . # -e = editable: los cambios al código se aplican sin reinstalar
La única dependencia es requests; hace falta Python 3.8 o posterior.
Si pipx avisa que ~/.local/bin no está en el PATH, ejecutá pipx ensurepath y
abrí otra terminal.
Uso
# 1. iniciar sesión una vez por servidor (la cookie se guarda en ~/.config/overleaf-ce, con permisos 0600)
overleaf-ce-sync login --host overleaf.example.com --email vos@example.com
# 2. buscar el id del proyecto
overleaf-ce-sync list
# 3. clonarlo en un repo git
overleaf-ce-sync clone <id-del-proyecto> milibro
cd milibro
# 4. ciclo normal
overleaf-ce-sync pull # trae los cambios remotos (pisa los locales)
# ...editar, git commit...
overleaf-ce-sync push # sube los archivos cambiados localmente
Después del primer pull/clone, el servidor y el id del proyecto quedan
guardados en .overleaf-ce.json, así que dentro del directorio alcanza con
overleaf-ce-sync pull / overleaf-ce-sync push.
Cómo funciona
La sincronización se ancla en commits de git: push publica solo lo que
commiteaste, nunca las ediciones sueltas del árbol de trabajo.
- pull →
GET /Project/<id>/download/zip, lo extrae sobre el árbol de trabajo, hace un «commit de sincronización» y lo recuerda comolast_sync_commiten.overleaf-ce.json. - push → sube el estado commiteado (HEAD). Compara
last_sync_commit..HEAD, sube el contenido commiteado de cada archivo cambiado (git show HEAD:<ruta>) conPOST /Project/<id>/upload(pisa por nombre) y avanzalast_sync_commita HEAD. Lo no commiteado se ignora. - El endpoint de subida necesita el id de la carpeta raíz del proyecto. Se
obtiene una sola vez por socket.io con xhr-polling (HTTP simple: funciona
detrás de cualquier proxy inverso, sin upgrade a websocket) a partir del
evento
joinProjectResponse, y se guarda en.overleaf-ce.json.
Limitaciones
- push solo manda cambios commiteados. Editá, hacé
git commity despuéspush. Un archivo con cambios sin commitear se saltea (y te avisa). - Los borrados no se propagan. Los archivos que borrás en tus commits se
informan pero NO se borran en Overleaf (por seguridad). Borralos desde la web;
usá
pull --prunepara reflejar en tu copia los borrados remotos. - pull pisa el árbol de trabajo y se niega si hay cambios sin commitear
(
--forcepara forzarlo). Commitea solo lo que trae, así que tu historial intercala commits «overleaf pull» con los tuyos. - Binario o documento: lo decide Overleaf por archivo; volver a subir crea versiones nuevas en su historial, por eso push solo manda los archivos cuyo contenido commiteado cambió.
- No cierres sesión en el navegador con la que iniciaste: Overleaf puede revocar la cookie.
Alternativa: id de la carpeta raíz sin socket.io
Si la detección por xhr-polling falla con tu instalación, sacá el id una vez de
Mongo en el servidor y pasalo con --root-folder-id (después queda guardado):
docker compose exec mongo mongosh sharelatex --quiet --eval \
'printjson(db.projects.findOne({_id:ObjectId("<id-del-proyecto>")},{ "rootFolder._id":1}))'
overleaf-ce-sync push --root-folder-id <id-carpeta-raiz>
Licencia
MIT