Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/jpa/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Git 如何打开包装好的参考资料?_Git_Command Line - Fatal编程技术网

Git 如何打开包装好的参考资料?

Git 如何打开包装好的参考资料?,git,command-line,Git,Command Line,我用git clone--mirror从github克隆了一个项目。这给我留下了一个存储库,其中包含一个打包的refs文件、一个.pack文件和一个.idx文件。出于开发目的,我想看看松散的对象,所以我用git unpack objects20字节。请注意,这仅适用于具有远程存储的存储库。 ( IFS=$'\n'; # set the input field separator to new line for f in $(git show-ref --heads); do

我用git clone--mirror从github克隆了一个项目。这给我留下了一个存储库,其中包含一个打包的refs文件、一个.pack文件和一个.idx文件。出于开发目的,我想看看松散的对象,所以我用git unpack objects<解包了对象,这很好(如果您想知道的话,我将包文件解包到了一个新的repo中)。唯一的问题是refs/heads/仍然是空的,所有的refs仍然只在打包的refs中,但我需要它们在refs/heads/中。 我找不到一个可以提取或解包这些引用的命令,我无法相信我必须手工(或通过管道)完成这项工作

所以实际上我有两个问题:

  • 是否有一种简单的方法可以从打包的引用“恢复”引用
  • 如果没有,为什么没有?如果有一个用于解包对象的命令,那么不为refs提供相同的命令的原因是什么(不要忘记,甚至还有一个命令gitpackrefs…)
  • 谢谢你的建议和想法。

    简短的回答是“不”-没有“简单的方法”可以按照你的提问方式解开裁判的包裹

    稍微长一点的答案是,每个ref只是特定路径中的一个41字节的文本文件(40字节的SHA1,十六进制+换行符),因此“硬”版本只需要在
    ~/.gitconfig
    中使用类似的内容:

    [alias]
    unpack-refs = "!bash -c 'IFS=$''\\n''; for f in $(git show-ref --heads); do /bin/echo ''Writing  '' $(echo $f | cut -c42-); echo $(echo $f | cut -c1-40) > \"${GIT_DIR:-.git}/$(echo $f | cut -c42-)\"; done'"
    

    花了一点小技巧来弄清楚如何让它正常工作,但你做到了!现在您有了'git unpack refs',它可以实现您所期望的功能,而且如果设置了$git_DIR,它甚至可以与$git_DIR一起工作(否则它假定您位于git树的根目录中)。如果你还没有读过git别名,是一个很好的参考,甚至包括一个示例“git alias”扩展名,您可以使用它来扩展自己的别名。

    打包引用存在的原因是为了在包含无数引用的repo中加快访问速度-查看包含多行的单个文件要比为每个引用访问一次文件系统更容易。git中任何需要了解refs的代码可以读取refs目录和打包的refs文件。拆开包装会破坏它的用途。如果要访问参照,请使用卫浴命令(例如,显示参照、每个参照、更新参照…)。我真的想不出使用目录结构比使用管道命令(尤其是使用for each ref)更快捷、更容易的任何访问方式

    是的,创建压缩对象(如压缩引用)是为了提高性能,但是有很大的区别。压缩的refs文件只是一堆独立的行。基本上,您可以免费添加或删除它。没有必要为了修改它而解包它。另一方面,压缩对象是增量压缩的,因此内部的对象相互依赖。它们极大地降低了磁盘使用率,并且可以以合理的成本从中读取对象,但是尝试修改包中的对象集要比修改松散的对象昂贵得多,因此只能通过
    git-repack
    (称为
    git-gc
    )定期执行,虽然我不相信git repack实际上是解包的,它只是从packfile中读取对象,用松散的对象打包,然后制作一个新的包

    然而,当一个包从远程传输时,它是在本地端解包的。我在
    git receive pack
    源代码中看到对unpack方法的调用,
    pack objects
    手册页显示:

    git unpack objects命令可以读取打包的归档文件,并将包中包含的对象扩展为“一个文件一个对象”格式;这通常是在动态创建数据包以便其对等方高效进行网络传输时,通过智能拉动命令完成的


    你的问题1的另一个答案是:

    我假设您已经使用了这样的循环来使用git unpack对象:

    请注意与克莱答案的不同: A) 压缩引用将从.git/packed refs文件中删除,并且 B) 将删除文件.git/info/refs和.git/objects/info/packs

    我承认,像这样删除.git文件夹中的文件可能不是一个好主意,但是这正是我需要做的,以便完成一个干净的解包


    问题2仍然没有得到回答。

    有一个变通方法对我有效,可能对你们中的一些人有效:

    基本上,在本地删除所有标记(将其从打包引用中删除),然后再次获取它

    git tag | xargs git tag -d && git fetch --tags
    

    这是有道理的。谢谢,伙计。离题–40字节的SHA1是错误的。SHA1由40个十六进制字符组成,相当于160位=>20字节。请注意,这仅适用于具有远程存储的存储库。
    (
       IFS=$'\n'; # set the input field separator to new line
       for f in $(git show-ref --heads); do
          ref_hash="$(echo $f | cut -c1-40)"
          ref_label="$(echo $f | cut -c42-)"
          echo " unpack: $ref_hash $ref_label"
          echo "$ref_hash" > ".git/$ref_label";
          sed -i "s~^${ref_hash} ${ref_label}\$~~" .git/packed-refs
          sed -i '/^$/d'                           .git/packed-refs
       done
       rm .git/info/refs
       rm .git/objects/info/packs
    )
    
    git tag | xargs git tag -d && git fetch --tags