2464

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

  1. git clone然后删除.git存储库目录。
  2. git checkout-index暗指此功能,但以“只需将所需的树读入索引...”开头,我不完全确定该怎么做。
  3. git-export是一个第三方脚本,本质上是先git clone进入一个临时位置,然后rsync --exclude='.git'进入最终目的地。

这些解决方案中没有一个真正让我感到满意。最接近的svn export可能是选项 1,因为两者都要求目标目录首先为空。但是选项 2 似乎更好,假设我可以弄清楚将树读入索引意味着什么。

4

31 回答 31

2504

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

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

大多数时候,我需要从 git 中“导出”某些东西,无论如何我都想要一个压缩存档,所以我做这样的事情。

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

压缩包:

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/

(有关更多详细信息,请参阅Greg 的答案

于 2008-10-02T18:13:14.263 回答
333

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

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

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

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

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

这似乎是我正在寻找的那种“git export”。

于 2008-10-02T03:03:35.993 回答
265

git archive也适用于远程存储库。

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

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

git archive --format=tar \
--remote=ssh://remote_server/remote_repository master path1/ path2/ | tar -xv
于 2008-12-09T18:59:01.560 回答
73

在此处输入图像描述

如果存储库托管在 GitHub 上,则为特殊情况的答案。

只需使用svn export.

据我所知 Github 不允许archive --remote。尽管 GitHub 与svn 兼容,并且它们确实可以svn访问所有 git repos,因此您可以svn export像往常一样使用,只需对您的 GitHub url 进行一些调整。

例如,要导出整个存储库,请注意trunkURL 中的替换方式master(或项目的 HEAD 分支设置为的任何内容):

svn export https://github.com/username/repo-name/trunk/

您可以导出单个文件甚至某个路径或文件夹:

svn export https://github.com/username/repo-name/trunk/src/lib/folder

使用jQuery JavaScript 库的示例

HEAD分支或主分支将可用trunk

svn ls https://github.com/jquery/jquery/trunk

HEAD 分支机构将可在以下位置访问/branches/

svn ls https://github.com/jquery/jquery/branches/2.1-stable

所有标签都以/tags/相同的方式:

svn ls https://github.com/jquery/jquery/tags/2.1.3
于 2013-10-30T17:03:24.200 回答
42

来自Git 手册

使用 git-checkout-index “导出整棵树”

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

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

于 2008-10-02T02:27:07.253 回答
39

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

git export ~/the/destination/dir

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

安装简单;只需将脚本放在你的某个地方PATH,并确保它是可执行的。

github存储库git-export

于 2008-10-16T17:17:00.260 回答
36

与 SVN 相比,这似乎对 Git 来说不是问题。Git 只在存储库根目录中放置一个 .git 文件夹,而 SVN 在每个子目录中放置一个 .svn 文件夹。所以“svn export”避免了递归命令行魔法,而使用 Git 递归是不必要的。

于 2009-05-12T04:20:24.927 回答
29

相当于

svn export . otherpath

在现有的回购中是

git archive branchname | (cd otherpath; tar x)

相当于

svn export url otherpath

git archive --remote=url branchname | (cd otherpath; tar x)
于 2012-02-23T15:41:55.123 回答
24

如果您不排除文件,请.gitattributes export-ignore尝试git checkout

mkdir /path/to/checkout/
git --git-dir=/path/to/repo/.git --work-tree=/path/to/checkout/ checkout -f -q

-f
从索引中检出路径时,不要在未合并的条目上失败;相反,未合并的条目将被忽略。

-q
避免冗长

此外,您可以获取任何分支或标签或从特定的提交修订版,如在 SVN 中只需添加 SHA1(Git 中的 SHA1 等同于 SVN 中的修订号)

mkdir /path/to/checkout/
git --git-dir=/path/to/repo/.git --work-tree=/path/to/checkout/ checkout 2ef2e1f2de5f3d4f5e87df7d8 -f -q -- ./

必须为空/path/to/checkout/,Git 不会删除任何文件,但会覆盖同名文件而不发出任何警告

更新:为避免斩首问题或在使用带有标签、分支或 SHA1 的签出导出时保持工作存储库完整,您需要-- ./在末尾添加

双破折号--告诉 git,破折号后面的所有内容都是路径或文件,在这种情况下也告诉git checkout不要更改HEAD

例子:

此命令将仅获取 libs 目录以及readme.txt来自该确切提交的文件

git --git-dir=/path/to/repo/.git --work-tree=/path/to/checkout/ checkout fef2e1f2de5f3d4f5e87df7d8 -f -q -- ./libs ./docs/readme.txt

my_file_2_behind_HEAD.txt这将在头部后面创建(覆盖)两个提交HEAD^2

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 -- ./

请注意,这./是相对于存储库的根目录

于 2014-03-28T01:39:03.890 回答
21

我广泛使用 git-submodules。这个对我有用:

rsync -a ./FROM/ ./TO --exclude='.*'
于 2011-09-13T06:26:03.070 回答
20

在寻找导出 git 存储库的方法时,我经常点击此页面。我对这个问题的回答考虑了 svn export 与 git 相比在设计上具有的三个属性,因为 svn 遵循集中存储库方法:

  • 它通过不导出所有修订来最小化到远程存储库位置的流量
  • 它不包含导出目录中的元信息
  • 使用svn导出某个分支是通过指定合适的路径来完成的

    git clone --depth 1 --branch master git://git.somewhere destination_path
    rm -rf destination_path/.git
    

在构建某个版本时,克隆一个稳定的分支很有用,例如--branch stable--branch release/0.9.

于 2012-01-22T17:31:47.387 回答
16

这将复制所有内容,减去 .dot 文件。我使用它来将 git 克隆的项目导出到我的 web 应用程序的 git repo 中,而不需要 .git 的东西。

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

普通的旧 bash 效果很好:)

于 2010-12-10T17:17:49.350 回答
13

就像克隆一样简单,然后删除 .git 文件夹:

git clone url_of_your_repo path_to_export && rm -rf path_to_export/.git

于 2013-09-27T19:35:10.220 回答
11

对于 GitHub 用户,该git archive --remote方法无法直接使用,因为导出 URL 是 ephemeral。您必须向 GitHub 询问 URL,然后下载该 URL。 curl让这很容易:

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

编辑
如果您希望将代码放入特定的现有目录(而不是来自 github 的随机目录):

curl -L https://api.github.com/repos/VENDOR/PROJECT/tarball | \
tar xzC /path/you/want --strip 1
于 2014-07-31T13:58:49.017 回答
11

是的,是一个干净整洁的命令,用于归档您的代码,而归档中不包含任何 git,并且可以很好地传递而不用担心任何 git 提交历史记录。

git archive --format zip --output /full/path/to/zipfile.zip master 
于 2015-01-05T21:42:44.683 回答
10

我只想指出,如果你是

  1. 导出存储库的子文件夹(这就是我过去使用 SVN 导出功能的方式)
  2. 可以将该文件夹中的所有内容复制到部署目标
  3. 并且因为您已经拥有整个存储库的副本。

然后你可以只使用cp foo [destination]而不是提到的git-archive master foo | -x -C [destination].

于 2010-10-29T13:51:08.920 回答
9

您可以在任何提交时将远程存储库归档为 zip 文件。

git archive --format=zip --output=archive.zip --remote=USERNAME@HOSTNAME:PROJECTNAME.git HASHOFGITCOMMIT
于 2012-10-09T13:49:55.980 回答
8

如果您想要与子模块一起使用的东西,这可能值得一试。

笔记:

  • MASTER_DIR = 结帐,同时签出您的子模块
  • DEST_DIR = 此导出将结束的位置
  • 如果你有 rsync,我认为你可以做同样的事情,而且球痛更少。

假设:

  • 您需要从 MASTER_DIR 的父目录运行它(即从 MASTER_DIR cd ..)
  • 假定已创建 DEST_DIR。如果您愿意,这很容易修改以包括创建 DEST_DIR

cd MASTER_DIR && tar -zcvf ../DEST_DIR/export.tar.gz --exclude='.git*' 。&& cd ../DEST_DIR/ && tar xvfz export.tar.gz && rm export.tar.gz

于 2012-02-28T01:42:28.653 回答
7

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

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

于 2008-10-02T15:13:20.217 回答
7

git-export 的 Bash 实现。

我已经根据自己的功能对 .empty 文件的创建和删除过程进行了分段,目的是在“git-archive”实现中重新使用它们(稍后将发布)。

我还在进程中添加了“.gitattributes”文件,以便从目标导出文件夹中删除不需要的文件。在使“git-export”功能更高效的同时,包括对流程的详细说明。

EMPTY_FILE=".empty";

function create_empty () {
## Processing path (target-dir):
    TRG_PATH="${1}";
## Component(s):
    EXCLUDE_DIR=".git";
echo -en "\nAdding '${EMPTY_FILE}' files to empty folder(s): ...";
    find ${TRG_PATH} -not -path "*/${EXCLUDE_DIR}/*" -type d -empty -exec touch {}/${EMPTY_FILE} \;
#echo "done.";
## Purging SRC/TRG_DIRs variable(s):
    unset TRG_PATH EMPTY_FILE EXCLUDE_DIR;
    return 0;
  }

declare -a GIT_EXCLUDE;
function load_exclude () {
    SRC_PATH="${1}";
    ITEMS=0; while read LINE; do
#      echo -e "Line [${ITEMS}]: '${LINE%%\ *}'";
      GIT_EXCLUDE[((ITEMS++))]=${LINE%%\ *};
    done < ${SRC_PATH}/.gitattributes;
    GIT_EXCLUDE[${ITEMS}]="${EMPTY_FILE}";
## Purging variable(s):
    unset SRC_PATH ITEMS;
    return 0;
  }

function purge_empty () {
## Processing path (Source/Target-dir):
    SRC_PATH="${1}";
    TRG_PATH="${2}";
echo -e "\nPurging Git-Specific component(s): ... ";
    find ${SRC_PATH} -type f -name ${EMPTY_FILE} -exec /bin/rm '{}' \;
    for xRULE in ${GIT_EXCLUDE[@]}; do
echo -en "    '${TRG_PATH}/{${xRULE}}' files ... ";
      find ${TRG_PATH} -type f -name "${xRULE}" -exec /bin/rm -rf '{}' \;
echo "done.'";
    done;
echo -e "done.\n"
## Purging SRC/TRG_PATHs variable(s):
    unset SRC_PATH; unset TRG_PATH;
    return 0;
  }

function git-export () {
    TRG_DIR="${1}"; SRC_DIR="${2}";
    if [ -z "${SRC_DIR}" ]; then SRC_DIR="${PWD}"; fi
    load_exclude "${SRC_DIR}";
## Dynamically added '.empty' files to the Git-Structure:
    create_empty "${SRC_DIR}";
    GIT_COMMIT="Including '${EMPTY_FILE}' files into Git-Index container."; #echo -e "\n${GIT_COMMIT}";
    git add .; git commit --quiet --all --verbose --message "${GIT_COMMIT}";
    if [ "${?}" -eq 0 ]; then echo " done."; fi
    /bin/rm -rf ${TRG_DIR} && mkdir -p "${TRG_DIR}";
echo -en "\nChecking-Out Index component(s): ... ";
    git checkout-index --prefix=${TRG_DIR}/ -q -f -a
## Reset: --mixed = reset HEAD and index:
    if [ "${?}" -eq 0 ]; then
echo "done."; echo -en "Resetting HEAD and Index: ... ";
        git reset --soft HEAD^;
        if [ "${?}" -eq 0 ]; then
echo "done.";
## Purging Git-specific components and '.empty' files from Target-Dir:
            purge_empty "${SRC_DIR}" "${TRG_DIR}"
          else echo "failed.";
        fi
## Archiving exported-content:
echo -en "Archiving Checked-Out component(s): ... ";
        if [ -f "${TRG_DIR}.tgz" ]; then /bin/rm ${TRG_DIR}.tgz; fi
        cd ${TRG_DIR} && tar -czf ${TRG_DIR}.tgz ./; cd ${SRC_DIR}
echo "done.";
## Listing *.tgz file attributes:
## Warning: Un-TAR this file to a specific directory:
        ls -al ${TRG_DIR}.tgz
      else echo "failed.";
    fi
## Purgin all references to Un-Staged File(s):
   git reset HEAD;
## Purging SRC/TRG_DIRs variable(s):
    unset SRC_DIR; unset TRG_DIR;
    echo "";
    return 0;
  }

输出:

$ git-export /tmp/rel-1.0.0

将“.empty”文件添加到空文件夹:...完成。

签出索引组件:...完成。

重置 HEAD 和索引:...完成。

清除特定于 Git 的组件:...

'/tmp/rel-1.0.0/{.buildpath}' 文件...完成。'

'/tmp/rel-1.0.0/{.project}' 文件...完成。'

'/tmp/rel-1.0.0/{.gitignore}' 文件...完成。'

'/tmp/rel-1.0.0/{.git}' 文件...完成。'

'/tmp/rel-1.0.0/{.gitattributes}' 文件...完成。'

'/tmp/rel-1.0.0/{*.mno}' 文件...完成。'

'/tmp/rel-1.0.0/{*~}' 文件...完成。'

'/tmp/rel-1.0.0/{.*~}' 文件...完成。'

'/tmp/rel-1.0.0/{*.swp}' 文件...完成。'

'/tmp/rel-1.0.0/{*.swo}' 文件...完成。'

'/tmp/rel-1.0.0/{.DS_Store}' 文件...完成。'

'/tmp/rel-1.0.0/{.settings}' 文件...完成。'

'/tmp/rel-1.0.0/{.empty}' 文件...完成。'

完毕。

归档签出组件:...完成。

-rw-r--r-- 1 管理轮 25445901 11 月 3 日 12:57 /tmp/rel-1.0.0.tgz

我现在已将“git 存档”功能合并到一个使用“create_empty”功能和其他功能的进程中。

function git-archive () {
    PREFIX="${1}"; ## sudo mkdir -p ${PREFIX}
    REPO_PATH="`echo "${2}"|awk -F: '{print $1}'`";
    RELEASE="`echo "${2}"|awk -F: '{print $2}'`";
    USER_PATH="${PWD}";
echo "$PREFIX $REPO_PATH $RELEASE $USER_PATH";
## Dynamically added '.empty' files to the Git-Structure:
    cd "${REPO_PATH}"; populate_empty .; echo -en "\n";
#    git archive --prefix=git-1.4.0/ -o git-1.4.0.tar.gz v1.4.0
# e.g.: git-archive /var/www/htdocs /repos/domain.name/website:rel-1.0.0 --explode
    OUTPUT_FILE="${USER_PATH}/${RELEASE}.tar.gz";
    git archive --verbose --prefix=${PREFIX}/ -o ${OUTPUT_FILE} ${RELEASE}
    cd "${USER_PATH}";
    if [[ "${3}" =~ [--explode] ]]; then
      if [ -d "./${RELEASE}" ]; then /bin/rm -rf "./${RELEASE}"; fi
      mkdir -p ./${RELEASE}; tar -xzf "${OUTPUT_FILE}" -C ./${RELEASE}
    fi
## Purging SRC/TRG_DIRs variable(s):
    unset PREFIX REPO_PATH RELEASE USER_PATH OUTPUT_FILE;
    return 0;
  }
于 2011-11-01T18:27:58.020 回答
7

据我了解这个问题,它更多的是从服务器下载某些状态,没有历史记录,也没有其他分支的数据,而不是从本地存储库中提取状态(就像这里的许多回答者所做的那样)。

可以这样做:

git clone -b someBranch --depth 1 --single-branch git://somewhere.com/repo.git \
&& rm -rf repo/.git/
  • --single-branch从 Git 1.7.10(2012 年 4 月)开始可用。
  • --depth是否(曾经?)据报道有缺陷,但对于出口而言,上述问题应该无关紧要。
于 2018-03-12T14:53:19.333 回答
6

这会将一系列提交(C 到 G)中的文件复制到 tar 文件中。注意:这只会提交文件。不是整个存储库。从这里稍微修改

示例提交历史

A --> B --> C --> D --> E --> F --> G --> H --> I

git diff-tree -r --no-commit-id --name-only --diff-filter=ACMRT C~..G | xargs tar -rf myTarFile.tar

git-diff-tree 手册页

-r --> 递归到子树

--no-commit-id --> git diff-tree 在适用时输出带有提交 ID 的行。此标志抑制了提交 ID 输出。

--name-only --> 仅显示更改文件的名称。

--diff-filter=ACMRT --> 只选择这些文件。有关文件的完整列表,请参见此处

C..G --> 此提交范围内的文件

C~ --> 包括来自 Commit C 的文件。不仅仅是 Commit C 之后的文件。

| xargs tar -rf myTarFile --> 输出到 tar

于 2014-04-25T17:47:12.190 回答
5

到目前为止,我见过的最简单的方法(也适用于 Windows)是git bundle

git bundle create /some/bundle/path.bundle --all

有关更多详细信息,请参阅此答案:如何通过 USB 驱动器将我的 git 存储库从我的 windows 机器复制到 linux 机器?

于 2015-04-05T21:47:57.720 回答
5

在添加前缀(例如目录名称)的同时将 git 导出到 zip 存档:

git archive master --prefix=directoryWithinZip/  --format=zip -o out.zip
于 2018-11-05T08:04:13.663 回答
4

我需要将其用于部署脚本,但我无法使用上述任何方法。相反,我想出了一个不同的解决方案:

#!/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
于 2009-07-17T10:07:43.853 回答
4

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

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 项目中执行命令,它总是会跳转到前面所说的基本目录,直到这个问题得到修复我个人更喜欢这个功能

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' -
于 2010-03-19T16:12:52.750 回答
4

如果您在要创建导出的机器上有存储库的本地副本,我还有另一个解决方案可以正常工作。在这种情况下,移动到此存储库目录,并输入以下命令:

GIT_WORK_TREE=outputdirectory git checkout -f

如果您管理具有 git 存储库的网站并希望在/var/www/. .git/hooks/post-receive在这种情况下,在脚本中添加这个命令(hooks/post-receive在裸存储库上,这更适合这种情况)

于 2018-02-23T10:30:17.747 回答
3

我认为@Aredridel的帖子最接近,但还有更多内容 - 所以我将在此处添加此内容;问题是,svn如果你在一个 repo 的子文件夹中,你这样做:

/media/disk/repo_svn/subdir$ svn export . /media/disk2/repo_svn_B/subdir

然后svn将导出所有受修订控制的文件(它们也可能是新添加的;或修改状态) - 如果您在该目录中有其他“垃圾”(我.svn这里不计算子文件夹,而是可见的东西,如.o文件) ,它不会被导出;只有那些由 SVN repo 注册的文件才会被导出。对我来说,一件好事是这个导出还包括尚未提交的本地更改的文件;另一个好处是导出文件的时间戳与原始文件相同。或者,正如svn help export它所说:

  1. 从 PATH1 指定的工作副本中导出一个干净的目录树,如果给出,则在修订版本 REV,否则在 WORKING,到 PATH2。... 如果未指定 REV,则将保留所有本地更改。不受版本控制的文件将不会被复制。

要意识到这git不会保留时间戳,请比较这些命令的输出(在git您选择的 repo 的子文件夹中):

/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 -)

...而且我无论如何都注意到这git archive会导致存档文件的所有时间戳都相同!git help archive说:

git archive 在给定树 ID 与给定提交 ID 或标签 ID 时的行为不同。在第一种情况下,当前时间用作存档中每个文件的修改时间。在后一种情况下,将使用引用的提交对象中记录的提交时间。

...但显然这两种情况都设置了“每个文件的修改时间”;从而保留这些文件的实际时间戳!

所以,为了也保留时间戳,这里有一个bash脚本,它实际上是一个“单行”,虽然有点复杂 - 所以下面分多行发布:

/media/disk/git_svn/subdir$ git archive --format=tar master | (tar tf -) | (\
  DEST="/media/diskC/tmp/subdirB"; \
  CWD="$PWD"; \
  while read line; do \
    DN=$(dirname "$line"); BN=$(basename "$line"); \
    SRD="$CWD"; TGD="$DEST"; \
    if [ "$DN" != "." ]; then \
      SRD="$SRD/$DN" ; TGD="$TGD/$DN" ; \
      if [ ! -d "$TGD" ] ; then \
        CMD="mkdir \"$TGD\"; touch -r \"$SRD\" \"$TGD\""; \
        echo "$CMD"; \
        eval "$CMD"; \
      fi; \
    fi; \
    CMD="cp -a \"$SRD/$BN\" \"$TGD/\""; \
    echo "$CMD"; \
    eval "$CMD"; \
    done \
)

请注意,假设您正在导出“当前”目录(上图/media/disk/git_svn/subdir)中的内容 - 并且您要导出到的目标位置有些不便,但它位于DEST环境变量中。请注意,使用此脚本;DEST在运行上述脚本之前,您必须自己手动创建目录。

脚本运行后,您应该能够比较:

ls -la /media/disk/git_svn/subdir
ls -la /media/diskC/tmp/subdirB   # DEST

...并希望看到相同的时间戳(对于那些受版本控制的文件)。

希望这对某人有帮助,
干杯!

于 2014-07-15T14:16:48.943 回答
2

如果您还需要子模块,这应该可以解决问题:https ://github.com/meitar/git-archive-all.sh/wiki

于 2012-08-23T15:05:20.980 回答
1

我的 .bashrc 文件中有以下实用程序函数:它在 git 存储库中创建当前分支的存档。

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
}
于 2014-05-22T07:38:31.753 回答
1

选项 1 听起来不太有效。如果客户端没有空间进行克隆然后删除.git文件夹怎么办?

今天我发现自己正在尝试这样做,其中客户端是一个 Raspberry Pi,几乎没有剩余空间。此外,我还想从存储库中排除一些繁重的文件夹。

选项 2 和此处的其他答案在这种情况下没有帮助。两者都不git archive是(因为需要提交.gitattributes文件,并且我不想将此排除保存在存储库中)。

在这里我分享我的解决方案,类似于选项 3,但不需要git clone

tmp=`mktemp`
git ls-tree --name-only -r HEAD > $tmp
rsync -avz --files-from=$tmp --exclude='fonts/*' . raspberry:

将行更改rsync为 compress 的等效行也可以作为 a 使用,git archive但带有一种排除选项(如此处所问

于 2015-06-12T19:09:04.777 回答