我开发了一个包含大量文件的 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 连接到远程计算机(我的 SSH
config
已设置为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
。您可以在这里阅读我的一些设计笔记gsync
:https://github.com/ElectricRCAaircraftGuy/eRCaGuy_dotfiles/issues/24
答案3
这种用例实际上很常见(尤其是在嵌入式开发中),因为正如您提到的,有时会发生本地计算机无法具有运行应用程序的正确环境的情况。
因此,许多/大多数 IDE 都有“远程运行”功能,但我没有使用 PyCharm 的经验。看这里专门针对 PyCharm。
另一种与环境无关的方法是使用scp
或rsync
传输/同步文件,然后远程运行它们。
为了使其正常工作,您应该配置从主机到目标的 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:如果适用,您可以例如删除整个远程文件夹,如果您愿意的话)
如果您的设置过程稍微复杂一些,您还可以创建一个每次都会传输的脚本,然后调用该脚本。