如何将工作目录“附加”到裸GIT存储库

时间:2012-07-27 12:34:56

标签: linux git git-bare

我已经嵌入了我们想要存储在Git中的Linux系统。我在系统上安装了Git,安装了额外的USB驱动器来存储Git数据(裸存储库)。使用以下命令提交和推送到远程存储库没有问题:

cd /media/usb
git init --bare
git --work-tree=/ add -A
git --work-tree=/ commit
git --work-tree=/ push -u origin master

但是当我将裸存储库克隆到新的USB驱动器并调用git --work-tree=/ status时,我看到所有先前推送的文件都已删除,并且未跟踪。如何告诉Git使用工作树?

1 个答案:

答案 0 :(得分:1)

您将以前提交的文件视为已删除的原因是第一个存储库中的git index(这只是一个名为index的文件)与第二个存储库中的索引不同。第一个中的索引对应于工作树,而第二个中的索引未初始化,因此没有条目。 git status的输出是两次比较的结果:

  1. 介于HEAD和索引之间(以确定要提交的分阶段更改)
  2. 在索引和工作树之间(以确定不会提交的未分级更改)
  3. 在您的情况下,第二个存储库中的HEAD指向一个提交,其中包含您从根文件系统提交的所有文件,但索引为空。因此,当git执行第一次比较时,它会认为这些文件中的每一个都已在下一次提交时被删除。

    当git执行第二次比较时,它发现工作树包含与提交相同的所有文件,但索引当然仍为空,因此它将这些文件视为“新”未跟踪文件。这就是为什么你看到所有文件都被删除和未跟踪的原因。

    解决方案非常简单:初始化第二个索引,使其与master匹配:

    git --work-tree=/ reset
    

    当我在这里时,我应该指出你发布的命令的其他一些问题:

    • 首先,您的git add -U正在将所有git存储库元数据文件添加到存储库。换句话说,存储库正在跟踪自己。这是由于您使用--work-tree的方式而导致的,并且非常糟糕。您应该通过将存储库文件添加到info/exclude.gitignore
    • 来确保它们被忽略
    • 其次,你真的不想要一个裸存储库,只是一个独立的工作树。您可以通过git config core.bare falseexport GIT_DIR=/media/usb实现这一目标;然后你可以从外面运行git命令(即/media/usb以上),你不必在每个命令中不断包含--work-tree=/作为全局选项。

    这是一个完整的测试用例,它封装了我刚刚介绍的所有内容,但第二个要点除外:

    #!/bin/sh
    
    root=fakeroot
    mkdir -p $root/media/usb{1,2} $root/{bin,etc}
    echo a > $root/bin/sh
    echo b > $root/etc/hosts
    
    cd $root/media/usb1
    git init --bare
    
    # We don't want our git repository meta-data being tracked.
    echo '/media/usb*/' >> info/exclude
    
    git --work-tree=../.. add -A ../..
    git --work-tree=../.. commit -m '1st commit'
    
    echo c >> ../../etc/hosts
    git --work-tree=../.. add -A ../..
    git --work-tree=../.. commit -m '2nd commit'
    
    git remote add origin ../usb2
    git --git-dir=../usb2 init --bare
    
    git push origin master
    
    cd ../usb2
    echo '/media/usb*/' >> info/exclude
    
    echo "========================================="
    echo "index in usb2 is not yet initialized:"
    git --work-tree=../.. status
    echo "========================================="
    echo "initialize index to master (HEAD)"
    git --work-tree=../.. reset
    echo "========================================="
    echo "now we have a clean working tree:"
    git --work-tree=../.. status