在环境之间共享项目树

在环境之间共享项目树

为了节省空间和时间,我在网络驱动器上复制了一个大型项目树作为硬链接,即

cp -a -r --link proj proj_B

(背景:它很大,需要从两个不兼容的环境中重建,并且对指定中间和产品位置没有良好的支持。因此,这是在环境“B”中进行重建的快速技巧:在复制干净并重建之后来自“proj_B/obj”。两个环境都在 LinuxMint 16 下)

这种方法的问题在于,编辑不会在这些树之间(可靠地)共享,例如,将编辑保存到“proj/foo.cpp”将使其指向新的 inode,而“proj_B/foo.cpp”仍将指向旧的(可能来自“save temp; mv orig temp2; mv temp orig; rm temp2”的避免损失模式)。

为了共享源代码,我想我需要源目录的符号链接(但不仅仅是项目根目录的符号链接,因为二进制目录需要分开),例如:

cp -a -r --symbolic-link proj proj_B

然后取消链接二进制目录(除了递归符号链接复制失败,并显示“只能在当前目录中创建相对符号链接”。但是可以使用“find -exec”完成类似的操作,或者只是投降并编写脚本)

但在这样做之前,我想要进行一次健全性检查:是否有更好的工具来实现这一点(例如 rsync 标志的一些术士级组合)?或者这种共享方法注定会以泪水和数据丢失而告终,而我应该放弃使用两个副本(当我发现我忘记在它们之间推送/拉取最新更改时,我会咒骂很多)?

答案1

我不会使用硬链接。有些编辑器在保存文件时会断开硬链接,有些则不会,有些可以配置。但是,在保存文件时保留硬链接意味着该文件是就地写入的,这意味着如果系统在写入过程中崩溃,您将得到一个不完整的文件。这就是为什么保存到新文件并移动就地更可取——但这会破坏硬链接。

特别是,大多数版本控制软件都会破坏硬链接。所以硬链接已经消失了。

符号链接森林不存在这个问题。您需要确保将编辑器指向主副本或编辑器遵循符号链接。

您可以使用创建符号链接林cp -as。但是,如果您创建新文件,则cp -as不方便创建相应的符号链接(它会完成这项工作,但会让您陷入目标已存在的抱怨中)。您可以使用简单的 shell 循环。

for env in environement1 environment2 environment3; do
  cd "../$env"
  find ../src \
       -type d -exec mkdir {} + \
       -o -exec sh -c 'ln -s "$@" .' _ {} +
done

答案2

这种方法的问题在于,编辑不会在这些树之间(可靠地)共享,例如,将编辑保存到“proj/foo.cpp”将使其指向新的 inode,而“proj_B/foo.cpp”仍将指向旧的。

这是不正确的。如果您有两个硬链接文件,它们始终具有相同的内容。编辑不应改变这一点。

如果您需要编辑文件 - 似乎您需要像中央存储这样的东西来存储您的两个目录。也许更好的办法是将你的项目置于版本控制之下(比如 git)?

答案3

@Gilles 答案的转换形式,允许使用更像 cp 的语法(我的 Bash 脚本非常简单,所以我无法弄清楚如何将路径替换打包到“-exec {}”中)

#/usr/bin/bash
if [ $# -ne 2 ] ; then  echo "Args: <original tree> <new tree of symlinks>" ; exit 1; fi
mkdir -p "$2"
srclen=${#1}
find "$1" | while read line
do
    sub=${line:$srclen}
    if [ -d "$line" ]
    then
        mkdir "$2$sub"
    else
        ln -s "$1$sub" "$2$sub"
    fi
done

相关内容