V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
爱意满满的作品展示区。
117503445
V2EX  ›  分享创造

基于 Syncthing 的代码自动同步方案

  •  2
     
  •   117503445 · 309 天前 · 2466 次点击
    这是一个创建于 309 天前的主题,其中的信息可能已经有所发展或是发生改变。

    动机

    我经常在不同台式电脑和笔记本电脑之间切换。为了保持代码文件的一致性,最简单的解决方案是使用一台 PC 作为开发服务器,并在我使用其他设备工作时连接到它。然而,这个方案存在以下缺点:

    • 互联网连接可能不稳定,导致经常断开连接
    • 部分开发工作无法在远程服务器上完成,比如嵌入式、GPU 计算等
    • 延迟会导致编码体验下降

    替代方案是在每台设备上设置开发环境,并在设备之间同步代码。常见的代码同步方案是通过 Git 提交到远程仓库,然后在另一台设备上拉取。然而,这要求程序员手动进行提交,而我经常会忘记提交,导致未提交的代码被留在已关机的台式电脑中。

    通过同步网盘可以在代码文件变更时自动在设备间同步。其中,Syncthing 是一款优秀的开源同步盘软件。但 Syncthing 会同步所有文件,而 node_modulestarget 等文件夹是不需要同步的,因为它们可以通过 package.jsonCargo.toml 等文件自动生成。同步这些文件会导致巨大的网络带宽消耗,并显著降低 Syncthing 的性能。

    Syncthing 支持使用 .stignore 忽略同步文件。可以考虑将 .gitignore 中忽略的文件也添加到 .stignore 中,这样就可以保证 Syncthing 只同步代码文本文件了。但是,.gitignore.stignore 的语法存在差异,不能直接使用。本项目可以弥补这个鸿沟,实现思路是在每台设备上运行 stignore-generator 进程。stignore-generator 进程在后台监听 .gitignore 文件的变化,并自动将其转换为 .stignore 文件。

    使用方法

    假设每个设备的项目路径都位于 ~/workspace 下,比如 ~/workspace/project1~/workspace/project2

    1. 使用 Syncthing 同步文件夹 ~/workspace

    2. 运行 stignore-generator 服务,可以使用 Docker 和 Systemd 两种方式。

    Docker

    准备 docker-compose.yml 文件:

    version: "3.9"
    services:
      stignore_generator:
        image: 117503445/stignore-generator
        restart: unless-stopped
        volumes:
          - ~/workspace:/workspace
    

    中国用户可以使用以下命令加速 Docker 镜像拉取

    docker pull registry.cn-hangzhou.aliyuncs.com/117503445-mirror/stignore-generator && docker tag registry.cn-hangzhou.aliyuncs.com/117503445-mirror/stignore-generator 117503445/stignore-generator
    

    启动 stignore-generator

    docker compose up -d
    

    Systemd

    下载 stignore-generator 可执行文件

    curl -L -O $(curl -s https://api.github.com/repos/117503445/syncthing-code/releases/latest | grep "browser_download_url" | cut -d '"' -f 4) && chmod +x stignore-generator && mv stignore-generator /usr/bin
    

    安装 stignore-generator 服务

    cat << EOF > /etc/systemd/system/stignore-generator.service
    [Unit]
    Description=stignore-generator
    
    [Service]
    Type=simple
    Restart=always
    RestartSec=1
    ExecStart=/usr/bin/stignore-generator
    
    [Install]
    WantedBy=multi-user.target
    EOF
    

    启用 stignore-generator 服务

    systemctl enable --now stignore-generator
    

    注意事项

    具体的生成方式是

    1. 保证 .stignore 中有 #include .stgitignore。如果 .stignore 不存在,则创建它;如果 .stignore 存在但不包含 #include .stgitignore,则在文件末尾添加它。

    2. .gitignore 中的内容转换为 .stgitignore,并将其保存到 .stignore 所在目录下。

    这种生成方式允许用户在 .stignore 中添加自定义的忽略规则,而不会被 stignore-generator 覆盖。典型的,包含机密信息的配置文件也存在于 .gitignore 中,程序员可以使用 ! 语法在自己的设备间同步这些文件。

    GitHub Repo

    https://github.com/117503445/syncthing-code

    如果帮助到了你,欢迎 Star ~

    致谢

    21 条回复    2024-06-10 22:42:17 +08:00
    villivateur
        1
    villivateur  
       309 天前
    这种东西不适合管理大量细碎的文件,你不如在每台机子上定时执行 git pull
    117503445
        2
    117503445  
    OP
       309 天前
    @villivateur 这样无法解决写了一半的代码同步至另一台设备的问题,毕竟不可能定时去 commit
    zagfai
        3
    zagfai  
       309 天前
    @117503445 开新分支,习惯性 commit ,感觉可以改变下编程习惯
    blankmiss
        4
    blankmiss  
       309 天前
    idea 会自动 fetch 提示你有新的需要拉取
    117503445
        5
    117503445  
    OP
       309 天前
    @blankmiss 问题在于前一台设备上的代码还没有 commit
    117503445
        6
    117503445  
    OP
       309 天前
    @zagfai 我也尝试过这种做法,但是在多个 Repo 和设备频繁切换的场景下,我很容易就忘记了 commit 。此外,每次手动 commit ,后续还要处理清理分支的事,比较繁琐。所以我倾向于自动在所有设备上获得一致的代码文件。

    有点类似于编辑器的自动保存功能,编辑后自动写入磁盘;我希望能更进一步,编辑代码后自动同步到所有设备上。
    AoEiuV020JP
        7
    AoEiuV020JP  
       309 天前
    gitignore 也不是什么经常改的文件,感觉没必要常驻一个后台区监控吧,当普通命令行工具运行时直接把当前目录的 gitignore 处理到 stgitignore 中就好,
    seekafter
        8
    seekafter  
       309 天前
    会忘记 commit 就不会忘记启动 syncthing 吗,感觉是为了捣鼓而捣鼓.不过我也是喜欢捣鼓的.也自建了 syncthing 中继在用
    enpitsulin
        9
    enpitsulin  
       309 天前
    我以前就是这样,现在发现直接 ssh 到自己服务器上写就完事了,还同步个鸡毛,反正最终都是 github 存储的
    locoz
        10
    locoz  
       309 天前 via Android
    @seekafter #8 文件同步工具可以自启动,但 commit 需要手动操作,两者没有可比性的
    joyhub2140
        11
    joyhub2140  
       309 天前
    我觉得这个同步工具实时性一般,非常一般。
    117503445
        12
    117503445  
    OP
       309 天前
    @AoEiuV020JP 也是支持的,下载二进制后直接执行就可以了
    117503445
        13
    117503445  
    OP
       309 天前
    @seekafter Syncthing 是开机自启、常驻后台的,不需要手动启动
    117503445
        14
    117503445  
    OP
       309 天前
    @joyhub2140 正常情况下 Syncthing 可以在 5s 内完成同步。在这个场景中,只要我不是在编辑完代码的 5s 内就关闭了电脑、切换到新设备,Syncthing 都可以及时的完成文件传输。

    相当于一个分布式文件系统,要求分区容忍性和可用性,所以一致性会有所欠缺。但是同时刻最多只有 1 个写入者,而且写入者的切换也比较慢,所以一般不会触发一致性的问题(比如修改丢失、冲突等)。
    0o0O0o0O0o
        15
    0o0O0o0O0o  
       309 天前 via Android
    一旦出现没同步好又被修改的情况会很烦吧
    117503445
        16
    117503445  
    OP
       309 天前
    @enpitsulin 我本来也是用这种方案,但感觉有一些痒点

    1. 在外面网络比较差的时候比较容易断开连接,延迟也比本地开发大不少
    2. 使用机架服务器当作开发机的开发体验不一定有 PC 好(内存带宽、硬盘性能等)。也不是所有开发工作都能通过 SSH 完成,比如运行 Pytorch 项目但服务器没有 GPU 。
    117503445
        17
    117503445  
    OP
       309 天前
    @0o0O0o0O0o 是的,但一般在切换设备前,Syncthing 已经能完成代码同步了
    APool
        18
    APool  
       309 天前
    如果使用 VSCode 的话, 有个 GitDoc 插件倒是支持自动 commit😀😀
    https://marketplace.visualstudio.com/items?itemName=vsls-contrib.gitdoc
    117503445
        19
    117503445  
    OP
       309 天前
    @APool 这个方案很不错欸,和我这个方案相比

    - 不能跨设备同步被 .gitignore 忽略的机密配置文件
    - 不能设备之间 p2p 直接传输,需要 GitHub 服务器中转

    但是就不需要维护本地 Syncthing 实例了,会方便很多
    shenzhuoyan
        20
    shenzhuoyan  
       150 天前
    @seekafter syncthing 是自动启动的。但是我总忘了开好内网穿透。所以我还是试试 onedrive 同步吧
    shenzhuoyan
        21
    shenzhuoyan  
       150 天前
    @shenzhuoyan 忘了开好内网穿透 -> 忘了开机并保持联网。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1403 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 23:46 · PVG 07:46 · LAX 15:46 · JFK 18:46
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.