Git 做一个;“吉特出口”;(如“svn出口”)?

Git 做一个;“吉特出口”;(如“svn出口”)?,git,export,git-archive,svn-export,Git,Export,Git Archive,Svn Export,我一直在想,是否有一个好的“git导出”解决方案可以在不使用.git存储库目录的情况下创建树的副本。我知道至少有三种方法: git克隆,然后删除.git存储库目录 暗指此功能,但以“只需将所需的树读入索引…”开头,我不完全确定该如何做 是一个第三方脚本,它基本上将git克隆到临时位置,然后将rsync--exclude='.git'克隆到最终目标 这些解决方案中没有一个真正让我感到满意。最接近svn export的选项可能是选项1,因为这两个选项都要求目标目录首先为空。但选项2似乎更好,假设我能

我一直在想,是否有一个好的“git导出”解决方案可以在不使用
.git
存储库目录的情况下创建树的副本。我知道至少有三种方法:

  • git克隆
    ,然后删除
    .git
    存储库目录
  • 暗指此功能,但以“只需将所需的树读入索引…”开头,我不完全确定该如何做
  • 是一个第三方脚本,它基本上将
    git克隆到临时位置,然后将
    rsync--exclude='.git'
    克隆到最终目标
  • 这些解决方案中没有一个真正让我感到满意。最接近svn export的选项可能是选项1,因为这两个选项都要求目标目录首先为空。但选项2似乎更好,假设我能理解将树读入索引意味着什么。

    来自:

    使用git签出索引“导出整个树”

    前缀功能基本上使使用git签出索引作为“导出为树”函数变得简单。只需将所需的树读入索引,然后执行以下操作:


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

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

    git checkout-index -a -f --prefix=/destination/path/
    
    路径末尾的斜杠很重要,否则会导致文件位于/destination中,前缀为“path”

    因为在正常情况下,索引包含存储库的内容,所以“将所需的树读入索引”没有什么特别的事情要做。它已经在那里了

    签出索引中的所有文件需要
    -a
    标志(我不确定在这种情况下省略此标志意味着什么,因为它不符合我的要求)。
    -f
    标志强制覆盖输出中的任何现有文件,此命令通常不会这样做


    这似乎是我一直在寻找的那种“git导出”。

    我的偏好实际上是在Makefile(或其他构建系统)中有一个dist目标,它导出代码的可分发归档(.tar.bz2、.zip、.jar或任何合适的东西)。如果您碰巧使用GNU autotools或Perl的MakeMaker系统,我认为这是自动存在的。如果没有,我强烈建议添加它


    埃塔(2012-09-06):哇,糟糕的否决票。我仍然相信使用构建工具构建发行版比使用源代码控制工具更好。我相信使用构建工具构建工件。在我目前的工作中,我们的主要产品是以蚂蚁为目标的。我们正处于转换源代码控制系统的过程中,这个ant目标的出现意味着迁移过程中的麻烦减少了。

    实现这一点的最简单方法可能是使用。如果你真的需要扩展的树,你可以这样做

    git archive master | tar -x -C /somewhere/else
    
    git archive master | bzip2 >source-tree.tar.bz2
    
    大多数时候,我需要从git“导出”一些东西,我希望在任何情况下都有一个压缩的归档文件,所以我会这样做

    git archive master | tar -x -C /somewhere/else
    
    git archive master | bzip2 >source-tree.tar.bz2
    
    压缩档案:

    git archive --format zip --output /full/path/to/zipfile.zip master 
    
    关于更多细节,它非常灵活


    请注意,即使归档文件不包含.git目录,但它也会包含其他隐藏的git特定文件,如.gitignore、.gitattributes等。如果您不希望将它们包含在归档文件中,请确保在.gitattributes文件中使用导出忽略属性,并在进行归档之前提交这些文件


    注意:如果您对导出索引感兴趣,可以使用以下命令

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

    (有关更多详细信息,请参阅)

    我编写了一个简单的包装器,用于
    git checkout index
    ,您可以这样使用:

    git export ~/the/destination/dir
    
    git clone -b someBranch --depth 1 --single-branch git://somewhere.com/repo.git \
    && rm -rf repo/.git/
    
    如果目标目录已经存在,则需要添加
    -f
    -force

    安装简单;只需将脚本放到
    路径中的某个地方,并确保它是可执行的


    git archive
    也可用于远程存储库

    git archive --format=tar \
    --remote=ssh://remote_server/remote_repository master | tar -xf -
    
    function garchive()
    {
      if [[ "x$1" == "x-h" || "x$1" == "x" ]]; then
        cat <<EOF
    Usage: garchive <archive-name>
    create zip archive of the current branch into <archive-name>
    EOF
      else
        local oname=$1
        set -x
        local bname=$(git branch | grep -F "*" | sed -e 's#^*##')
        git archive --format zip --output ${oname} ${bname}
        set +x
      fi
    }
    
    要导出回购协议中的特定路径,请将任意多个路径作为最后一个参数添加到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 $0 REPOSITORY DESTINATION" && exit 1
    REPOSITORY=$1
    DESTINATION=$2
    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]。注意:使用此功能可以避免克隆操作,它直接从远程repo获取

    gitss() {
        URL=[url:path]
    
        TMPFILE="`/bin/tempfile`"
        if [ "$1" = "" ]; then
            echo -e "Use: gitss repo [tree/commit]\n"
            return
        fi
        if [ "$2" = "" ]; then
            TREEISH="HEAD"
        else
            TREEISH="$2"
        fi
        echo "Getting $1/$TREEISH..."
        git archive --format=zip --remote=$URL/$1 $TREEISH > $TMPFILE && unzip $TMPFILE && echo -e "\nDone\n"
        rm $TMPFILE
    }
    
    .gitconfig的别名,需要相同的配置(注意在.git项目中执行命令,它以前总是跳转到base dir,直到修复为止,我个人更喜欢这个函数

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

    我只想指出,如果你是

  • 导出存储库的子文件夹(这就是我使用SVN导出功能的方式)
  • 是否可以将所有内容从该文件夹复制到部署目标
  • 因为您已经准备好了整个存储库的副本

  • 然后,您可以使用
    cp foo[destination]
    而不是前面提到的
    git archive master foo |-x-C[destination]
    这将复制所有内容,减去.dot文件。我使用它将git克隆项目导出到我的web应用程序的git repo中,而不使用.git内容

    cp-R./git回购路径/path/to/destination/


    普通的老bash非常好:)

    我广泛使用git子模块。 这个对我很有用:

    rsync -a ./FROM/ ./TO --exclude='.*'
    

    git导出的Bash实现

    我将.empty文件的创建和删除过程划分为各自的功能,目的是在“git archive”实现中重新使用它们
    git archive branchname | (cd otherpath; tar x)
    
    svn export url otherpath
    
    git archive --remote=url branchname | (cd otherpath; tar x)
    
    git archive --format=zip --output=archive.zip --remote=USERNAME@HOSTNAME:PROJECTNAME.git HASHOFGITCOMMIT
    
    svn export https://github.com/username/repo-name/trunk/
    
    svn export https://github.com/username/repo-name/trunk/src/lib/folder
    
    svn ls https://github.com/jquery/jquery/trunk
    
    svn ls https://github.com/jquery/jquery/branches/2.1-stable
    
    svn ls https://github.com/jquery/jquery/tags/2.1.3
    
    mkdir /path/to/checkout/
    git --git-dir=/path/to/repo/.git --work-tree=/path/to/checkout/ checkout -f -q
    
    mkdir /path/to/checkout/
    git --git-dir=/path/to/repo/.git --work-tree=/path/to/checkout/ checkout 2ef2e1f2de5f3d4f5e87df7d8 -f -q -- ./
    
    git --git-dir=/path/to/repo/.git --work-tree=/path/to/checkout/ checkout fef2e1f2de5f3d4f5e87df7d8 -f -q -- ./libs ./docs/readme.txt
    
    git --git-dir=/path/to/repo/.git --work-tree=/path/to/checkout/ checkout HEAD^2 -f -q -- ./my_file_2_behind_HEAD.txt
    
    git --git-dir=/path/to/repo/.git --work-tree=/path/to/checkout/ checkout myotherbranch -f -q -- ./
    
    git diff-tree -r --no-commit-id --name-only --diff-filter=ACMRT C~..G | xargs tar -rf myTarFile.tar
    
    function garchive()
    {
      if [[ "x$1" == "x-h" || "x$1" == "x" ]]; then
        cat <<EOF
    Usage: garchive <archive-name>
    create zip archive of the current branch into <archive-name>
    EOF
      else
        local oname=$1
        set -x
        local bname=$(git branch | grep -F "*" | sed -e 's#^*##')
        git archive --format zip --output ${oname} ${bname}
        set +x
      fi
    }
    
    /media/disk/repo_svn/subdir$ svn export . /media/disk2/repo_svn_B/subdir
    
    /media/disk/git_svn/subdir$ ls -la .
    
    /media/disk/git_svn/subdir$ git archive --format=tar --prefix=junk/ HEAD | (tar -t -v --full-time -f -)
    
    ls -la /media/disk/git_svn/subdir
    ls -la /media/diskC/tmp/subdirB   # DEST
    
    curl -L https://api.github.com/repos/VENDOR/PROJECT/tarball | tar xzf -
    
    $ curl -L https://api.github.com/repos/jpic/bashworks/tarball | tar xzf -
    $ ls jpic-bashworks-34f4441/
    break  conf  docs  hack  LICENSE  mlog  module  mpd  mtests  os  README.rst  remote  todo  vcs  vps  wepcrack
    
    curl -L https://api.github.com/repos/VENDOR/PROJECT/tarball | \
    tar xzC /path/you/want --strip 1
    
    git archive --format zip --output /full/path/to/zipfile.zip master 
    
    git clone -b someBranch --depth 1 --single-branch git://somewhere.com/repo.git \
    && rm -rf repo/.git/
    
    git archive master --prefix=directoryWithinZip/  --format=zip -o out.zip