是否执行" git导出"(如" svn导出")?

时间:2020-03-06 15:00:25  来源:igfitidea点击:

我一直在想是否有一个好的" git export"解决方案,可以创建没有.git存储库目录的树的副本。我至少知道三种方法:

  • git clone,然后删除.git存储库目录。
  • git checkout-index`暗示了此功能,但以"仅将所需的树读入索引..."开头,我不确定该怎么做。
  • git-export是第三方脚本,本质上是将git clone复制到临时位置,然后将rsync --exclude = .git复制到最终目的地。

这些解决方案都没有一个令我满意。最接近" svn export"的选项可能是选项1,因为这两个选项均要求目标目录首先为空。但是,假设我能弄清楚将树读入索引的含义,选项2似乎更好。

解决方案

从Git手册:

使用git-checkout-index来"导出整个树"

前缀功能基本上使将git-checkout-index用作"导出为树"功能变得微不足道。只需将所需的树读入索引,然后执行:

$ git checkout-index --prefix = git-export-dir / -a`

我发现了选项2的含义。在存储库中,我们可以执行以下操作:

git checkout-index -a -f --prefix=/destination/path/

路径末尾的斜杠很重要,否则它将导致文件位于/ destination中,且前缀为" path"。

由于在正常情况下索引包含存储库的内容,因此无需执行任何特殊操作即可"将所需的树读入索引"。它已经在那里。

需要使用-a标志来检出索引中的所有文件(我不确定在这种情况下忽略此标志的含义,因为它不执行我想要的操作)。 -f标志强制覆盖输出中的所有现有文件,此命令通常不会执行此操作。

这似乎是我一直在寻找的" git export"。

我的偏好实际上是在Makefile(或者其他构建系统)中有一个dist目标,该目标可以导出代码的可分发存档(.tar.bz2,.zip,.jar或者任何适当的文件)。如果我们碰巧正在使用GNU自动工具或者Perl的MakeMaker系统,那么我认为这自动存在。如果没有,我强烈建议添加它。

预计到达时间(2012-09-06):哇,严厉的否决票。我仍然认为,使用构建工具而不是源代码控制工具来构建发行版会更好。我相信使用构建工具来构建工件。在我目前的工作中,我们的主要产品是使用蚂蚁目标制造的。我们正处于切换源代码控制系统的过程中,而这个ant目标的存在意味着迁移的麻烦减少了。

可能最简单的方法是使用git archive。如果我们真的只需要扩展树,则可以执行以下操作。

git archive master | tar -x -C /somewhere/else

在大多数情况下,我需要从git中"导出"某些内容,无论如何我都想要压缩的存档,所以我要做类似的事情。

git archive master | bzip2 >source-tree.tar.bz2

ZIP存档:

git archive --format zip --output /full/path/to/zipfile.zip master

git help archive`以获得更多详细信息,它非常灵活。

请注意,即使存档中不包含.git目录,但是该存档中也会包含其他特定于git的隐藏文件,例如.gitignore,.gitattributes等。如果我们不希望它们出现在存档中,请确保在.gitattributes文件中使用export-ignore属性,并在进行归档之前提交。阅读更多...

注意:如果我们有兴趣导出索引,则命​​令为

git checkout-index -a -f --prefix=/destination/path/

(有关更多详细信息,请参见格雷格的答案)

我已经为git-checkout-index编写了一个简单的包装,我们可以像这样使用:

git export ~/the/destination/dir

如果目标目录已经存在,则需要添加-f或者--force。

安装简单;只需将脚本放在" PATH"中的某个位置,并确保其可执行即可。

git-export的github仓库

git archive也可以和远程仓库一起使用。

git archive --format=tar \
--remote=ssh://remote_server/remote_repository master | tar -xf -

要在仓库中导出特定路径,请在git的最后一个参数中添加任意数量的路径,例如:

git archive --format=tar \
--remote=ssh://remote_server/remote_repository master path1/ path2/ | tar -xv

看来,与SVN相比,Git的问题较小。 Git仅在存储库根目录中放置一个.git文件夹,而SVN在每个子目录中放置一个.svn文件夹。因此," svn导出"避免了递归命令行魔术,而使用Git则不需要递归。

我需要此作为部署脚本,并且无法使用任何上述方法。相反,我想出了一个不同的解决方案:

#!/bin/sh
[ $# -eq 2 ] || echo "USAGE 
gitss() {
    URL=[url:path]

    TMPFILE="`/bin/tempfile`"
    if [ "" = "" ]; then
        echo -e "Use: gitss repo [tree/commit]\n"
        return
    fi
    if [ "" = "" ]; then
        TREEISH="HEAD"
    else
        TREEISH=""
    fi
    echo "Getting /$TREEISH..."
    git archive --format=zip --remote=$URL/ $TREEISH > $TMPFILE && unzip $TMPFILE && echo -e "\nDone\n"
    rm $TMPFILE
}
REPOSITORY DESTINATION" && exit 1 REPOSITORY= DESTINATION= TMPNAME="/tmp/$(basename $REPOSITORY).$$" git clone $REPOSITORY $TMPNAME rm -rf $TMPNAME/.git mkdir -p $DESTINATION cp -r $TMPNAME/* $DESTINATION rm -rf $TMPNAME

这样做很简单,这是.bash_profile的功能,它直接将存档解压缩到当前位置,首先配置我们通常的[url:path]。注意:使用此功能可以避免克隆操作,它直接从远程存储库获取。

ss = !env GIT_TMPFILE="`/bin/tempfile`" sh -c 'git archive --format=zip --remote=[url:path]/  \ > $GIT_TMPFILE && unzip $GIT_TMPFILE && rm $GIT_TMPFILE' -

.gitconfig的别名,需要相同的配置(请在.git项目中执行命令TAKE CARE,它总是像这里所说的那样一直跳到先前的基本目录,直到此问题修复为止,我个人更喜欢该功能

cp -R ./path-to-git-repo /path/to/destination/

我只想指出,在这种情况下

  • 导出存储库的子文件夹(这就是我以前使用SVN导出功能的方式)
  • 可以将所有内容从该文件​​夹复制到部署目标
  • 并且由于我们已经拥有整个存储库的副本。

然后,我们可以只使用cp foo [destination]来代替提到的git-archive master foo |。 -x -C [目标]

这将复制所有内容,减去.dot文件。我用它来将git克隆项目导出到我的Web应用程序的git repo中,而没有.git内容。

##代码##

普通的旧bash效果很好:)