如何使本地目录自动与远程同步,而不会出现延迟问题?

如何使本地目录自动与远程同步,而不会出现延迟问题?

我开发了一个包含大量文件的 git 跟踪代码库。此代码必须在远程机器上运行。因此,每次我在本地进行更改时,我都必须将其同步到远程并在远程机器上运行新代码。

我想消除手动同步步骤。我尝试过的事情:

  • 简单git push地(本地)和git pull(远程)进行工作是可行的,但会导致许多无用的提交。另外,有时我只是尝试一些小的改变,但我不希望这些改变被实施。
  • 在本地挂载远程目录可以sshfs工作,但文件访问有轻微的延迟。我不介意,但 PyCharm 依赖它并且许多功能都被破坏了。

有更好的方法来实现这一点吗?

答案1

我最终找到了两个解决方案。

  • 使用unison。这是一个命令行实用程序,用于镜像远程服务器上的本地目录。它与处理许多文件时类似,rsync但更复杂且更符合人体工程学。他们的github 仓库相当活跃,尽管网页上说开发已基本停止,主要缺点是它unison是一个运行一次的实用程序,而不是在后台运行的东西。您可以使用类似cron定期运行的方法unison,但我不确定这是否会导致长时间的同步滞后(1 分钟以上)以及手动冲突解决如何工作。
  • 使用lsyncd。该程序专为我的用例而设计:它持续监视给定目录,并在短短 1 秒内立即同步任何更改。然而,最后一次提交是在两年前,所以我不确定它的长期可行性如何。

我最终使用它是lsyncd因为它可以连续运行。对于lsyncd,您必须提供一个“配置文件”,它是一个 Lua 文件,告诉lsyncd哪个目录要同步到何处以及如何同步(例如是否忽略某些文件)。我使用了以下配置文件:

settings {
    nodaemon = true,
    statusInterval = 1
}

sync {
    default.rsync,
    source = "/home/donentolon/github/my-awesome-codebase",
    target = "remote-machine:/home/remote-user/my-awesome-codebase",
    delay = 1, 
    exclude = { '/.git', '/.idea' }
}

这告诉lsyncd我们:

  • 使用 SSH 连接到远程计算机(我的 SSHconfig已设置为ssh remote-machine可以连接到它)
  • 使用 rsync 进行实际同步
  • 至少每秒检查一次文件更改(the delay
  • 不同步顶级 git 和 PyCharm 文件

当我打开计算机时,我打开一个终端并运行lsyncd my-lsyncd-profile.lua,它开始运行并打印有关其正在执行的操作的实时更新。我让终端保持打开状态并进行开发,并lsyncd在一天结束时完成工作。

我不使用 git 来跟踪远程目录上的更改,尽管我可以。如果我想将更改提交到 git,我会git commit在本地计算机上运行其他命令,这些命令lsyncd会同步。因为本地目录实际上是本地目录,而不是本地安装的远程目录,所以 PyCharm 功能(如索引)都可以正常工作。

有后台模式,但我没有使用它,因为我喜欢查看状态lsyncd。可以使用标准 Linux 方法将其配置为自动启动,但我更喜欢手动方法。

lsyncd的页面列出了一些具有类似用例的替代方案,因此如果您不喜欢这个解决方案,您可以看看这些解决方案。

答案2

你可以尝试syncthing。它看起来得到了很好的支持和良好的开发。到目前为止,它拥有 48,900 个 star、7009 次提交和 284 名贡献者。

我第一次了解到它的地方:https://hackaday.com/2020/07/23/linux-fu-keep-in-sync/


我正在开发自己的连续同步工具,我将调用该工具gsync,该工具目前是一个异步的、手动调用的脚本,名为sync_git_repo_from_pc1_to_pc2.sh。您可以在这里阅读我的一些设计笔记gsynchttps://github.com/ElectricRCAaircraftGuy/eRCaGuy_dotfiles/issues/24

答案3

这种用例实际上很常见(尤其是在嵌入式开发中),因为正如您提到的,有时会发生本地计算机无法具有运行应用程序的正确环境的情况。

因此,许多/大多数 IDE 都有“远程运行”功能,但我没有使用 PyCharm 的经验。看这里专门针对 PyCharm。

另一种与环境无关的方法是使用scprsync传输/同步文件,然后远程运行它们。

为了使其正常工作,您应该配置从主机到目标的 ssh 公钥身份验证ssh-copy-id user@target

然后您可以使用如下脚本将文件夹传输到远程,如果传输成功 - 运行一些命令:

#!/bin/bash

TARGET="<your-remote-here>";
USER="<your-user-name-on-remote-here>";
FOLDER_TO_TRANSMIT="<folder-to-transmit>";
FOLDER_TO_TRANSMIT_TO="<folder-path-on-target>";
REMOTE_COMMANDS="touch ~/testdir/z; ls ~/testdir;"

#transmit only (inefficiant, transmits everything, every time)
#scp -r $dir_to_transmit $USER@$TARGET:$FOLDER_TO_TRANSMIT_TO;
rsync -rv --delete $dir_to_transmit $USER@$TARGET:$FOLDER_TO_TRANSMIT_TO

if [ $? -eq 0 ]
then
    ssh -t $USER@$TARGET "$REMOTE_COMMANDS"
fi

使用此设置,您唯一需要担心的是正确清理每次传输到的文件夹。 (rsync:--delete源文件夹中不存在的所有内容也会在目标文件夹中删除,这可以通过排除模式来避免)(scp:如果适用,您可以例如删除整个远程文件夹,如果您愿意的话)

如果您的设置过程稍微复杂一些,您还可以创建一个每次都会传输的脚本,然后调用该脚本。

相关内容