做一个“git export”(比如“svn export”)?

时间:2008-10-02 02:21:34

标签: git export git-archive svn-export

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

  1. git clone然后删除.git存储库目录。
  2. git checkout-index提到了这个功能,但是从“只需将所需的树读入索引......”开始,我不完全确定该怎么做。
  3. git-export是第三方脚本,它基本上将git clone放入临时位置,然后rsync --exclude='.git'进入最终目的地。
  4. 这些解决方案都没有让我感到满意。最接近svn export的选项可能是选项1,因为这两者都要求目标目录首先为空。但是假设我可以弄清楚将树读入索引意味着什么,选项2看起来会更好。

31 个答案:

答案 0 :(得分:2300)

实现这一目标的最简单方法可能是使用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属性并在进行存档之前提交此属性。 Read more...


注意:如果您对导出索引感兴趣,则命令为

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

(有关详细信息,请参阅Greg's answer

答案 1 :(得分:313)

我发现了2选项意味着什么。从存储库中,您可以执行以下操作:

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

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

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

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

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

答案 2 :(得分:248)

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

答案 3 :(得分:53)

enter image description here

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

只需使用svn export

据我所知,Github不允许archive --remote。虽然GitHub是svn compatible,但他们确实可以访问所有git repos svn,所以你可以像往常一样使用svn export对你的GitHub网址进行一些调整。

例如,要导出整个存储库,请注意网址中trunk替换master(或project's HEAD branch is set to的任何内容)的方式:

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

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

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

jQuery JavaScript Library

的示例

使用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

答案 4 :(得分:39)

来自Git Manual

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

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

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

答案 5 :(得分:38)

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

git export ~/the/destination/dir

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

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

The github repository for git-export

答案 6 :(得分:36)

对于Git而言,这似乎不是SVN的问题。 Git只在存储库根目录中放置一个.git文件夹,而SVN在每个子目录中放置一个.svn文件夹。所以“svn export”避免了递归命令行魔术,而Git递归则没有必要。

答案 7 :(得分:26)

相当于

svn export . otherpath
现有仓库中的

git archive branchname | (cd otherpath; tar x)

相当于

svn export url otherpath

git archive --remote=url branchname | (cd otherpath; tar x)

答案 8 :(得分:22)

如果您未使用.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不会删除任何文件,但会覆盖具有相同名称的文件而不会发出任何警告

更新: 为了避免斩首问题或在使用checkout导出标签,分支或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 -- ./

请注意./相对于存储库的根

答案 9 :(得分:21)

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

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

答案 10 :(得分:19)

在寻找导出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

答案 11 :(得分:16)

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

  

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

普通的旧bash工作得非常好:)

答案 12 :(得分:12)

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

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

答案 13 :(得分:11)

是的,this是一个干净利落的命令,用于存档您的代码,而不会在存档中包含任何git,并且可以在不担心任何git提交历史记录的情况下传递。

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

答案 14 :(得分:10)

我只想指出你是

的情况
  1. 导出存储库的子文件夹(这就是我以前使用SVN导出功能的方式)
  2. 可以将所有内容从该文件​​夹复制到部署目标
  3. 因为您已经拥有整个存储库的副本。
  4. 然后您可以使用cp foo [destination]代替上述git-archive master foo | -x -C [destination]

答案 15 :(得分:10)

对于GitHub用户,git archive --remote方法不会直接作为the export URL is 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

答案 16 :(得分:9)

您可以将任何提交的远程仓库存档为zip文件。

git archive --format=zip --output=archive.zip --remote=USERNAME@HOSTNAME:PROJECTNAME.git HASHOFGITCOMMIT

答案 17 :(得分: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

答案 18 :(得分:8)

git-export的Bash实现。

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

我还将'.gitattributes'文件添加到进程中,以便从目标导出文件夹中删除不需要的文件。 在使'git-export'功能更有效的同时包括流程的冗长。

EMPTY_FILE = “空”;

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 admin wheel 25445901 3月12日12:57 /tmp/rel-1.0.0.tgz

     

我现在已将'git archive'功能合并到一个使用'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;
  }

答案 19 :(得分:6)

这会将提交范围(C到G)中的文件复制到tar文件中。注意:这只会提交文件。不是整个存储库。稍微修改自Here

示例提交历史记录

A - &gt; B - &gt; C - &gt; D - &gt; E - &gt; F - &gt; G - &gt; H - &gt;我

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

git-diff-tree Manual Page

-r - &gt;递归到子树

- no-commit-id - &gt; git diff-tree在适用时输出带有提交ID的行。此标志禁止提交ID输出。

- 仅限名称 - &gt;仅显示已更改文件的名称。

- diff-filter = ACMRT - &gt;仅选择这些文件。 See here for full list of files

C..G - &gt;此提交范围内的文件

C~ - &gt;包括Commit C中的文件。不仅仅是自Commit C。

以来的文件

| xargs tar -rf myTarFile - &gt;输出到tar

答案 20 :(得分:6)

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

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

答案 21 :(得分: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的别名,需要相同的配置(TAKE CARE在.git项目中执行命令,它始终跳转到基础目录as said here,直到修复此我个人更喜欢该功能

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' -

答案 22 :(得分: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

答案 23 :(得分:4)

正如我理解这个问题,它更多的是从服务器下载某个状态,没有历史记录,没有其他分支的数据,而不是从本地存储库中提取状态(这里有很多答案)。

可以这样做:

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是(有?)reportedly错误,但对于导出的情况,上述问题无关紧要。

答案 24 :(得分:3)

我认为@Aredridel的帖子最接近,但还有更多 - 所以我会在这里添加;问题是,在svn中,如果您位于回购的子文件夹中,那么您可以:

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

然后svn将导出所有受版本控制的文件(它们也可以新添加;或者已修改状态) - 如果你有其他&#34;垃圾&#34;在该目录中(我不在此处.svn子文件夹,但.o文件等可见内容),将被导出;只导出SVN仓库注册的文件。对我来说,一个好处是这个导出还包括具有 not 尚未提交的本地更改的文件;另一个好处是导出文件的时间戳与原始文件的时间戳相同。或者,正如svn help export所说:

  
      
  1. 从指定的工作副本导出干净的目录树   PATH1,修订版REV,如果给出,否则在WORKING,进入   PATH2。 ...如果未指定REV,则全部为本地   变化将被保留。不受版本控制的文件会   不被复制。
  2.   

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

/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时的行为不同。在第一种情况下   当前时间用作存档中每个文件的修改时间。在后一种情况下,记录的提交时间   而是使用引用的commit对象。

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

所以,为了也保留时间戳,这里有一个bash脚本,实际上是一个&#34;单行&#34;虽然有点复杂 - 所以低于它发布在多行:

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

请注意,我们假设您正在导出&#34;当前&#34;目录(上面,/media/disk/git_svn/subdir) - 您导出的目标位置有些不方便,但它位于DEST环境变量中。请注意,使用此脚本;在运行上述脚本之前,您必须自己手动创建DEST目录。

运行脚本后,您应该可以比较:

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

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

希望这有助于某人,
干杯!

答案 25 :(得分:3)

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

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

有关详细信息,请参阅此答案:How can I copy my git repository from my windows machine to a linux machine via usb drive?

答案 26 :(得分:3)

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

GIT_WORK_TREE=outputdirectory git checkout -f

如果您使用git存储库管理网站并希望在/var/www/中签出一个干净的版本,这将非常有用。在这种情况下,在.git/hooks/post-receive脚本(hooks/post-receive上的裸存储库中添加此命令,这在这种情况下更合适)

答案 27 :(得分:3)

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

git archive master --prefix=directoryWithinZip/  --format=zip -o out.zip

答案 28 :(得分:2)

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

答案 29 :(得分: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
}

答案 30 :(得分: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行也可以作为git archive但有一种排除选项(如here所述)。