I've been wondering whether there is a good "git export" solution that creates a copy of a tree without the .git
repository directory. There are at least three methods I know of:
git clone
followed by removing the .git
repository directory.git checkout-index
alludes to this functionality but starts with "Just read the desired tree into the index..." which I'm not entirely sure how to do.git-export
is a third-party script that essentially does a git clone
into a temporary location followed by rsync --exclude='.git'
into the final destination.None of these solutions really strike me as being satisfactory. The closest one to svn export
might be option 1, because both require the target directory to be empty first. But option 2 seems even better, assuming I can figure out what it means to read a tree into the index.
Probably the simplest way to achieve this is with git archive
. If you really need just the expanded tree you can do something like this.
git archive master | tar -x -C /somewhere/else
Most of the time that I need to 'export' something from git, I want a compressed archive in any case so I do something like this.
git archive master | bzip2 >source-tree.tar.bz2
ZIP archive:
git archive --format zip --output /full/path/to/zipfile.zip master
git help archive
for more details, it's quite flexible.
Be aware that even though the archive will not contain the .git directory, it will, however, contain other hidden git-specific files like .gitignore, .gitattributes, etc. If you don't want them in the archive, make sure you use the export-ignore attribute in a .gitattributes file and commit this before doing your archive. Read more...
Note: If you are interested in exporting the index, the command is
git checkout-index -a -f --prefix=/destination/path/
(See Greg's answer for more details)
Here's a real-world example using libchrony on Linux:
mkdir $HOME/dev
cd $HOME/dev
pushd /tmp
git clone https://gitlab.com/chrony/libchrony.git
cd libchrony
BRANCH=$(git rev-parse --abbrev-ref HEAD)
git archive -o ../libchrony.zip --prefix="libchrony/" $BRANCH
popd
unzip /tmp/libchrony.zip
Those commands produce a zip file and extract it into $HOME/dev/libchrony
. We can peek into the archive using:
$ unzip -v /tmp/libchrony
Archive: /tmp/libchrony.zip
e0a3807f770b56f6b0e9833254baa7c4fc13564b
Length Method Size Cmpr Date Time CRC-32 Name
-------- ------ ------- ---- ---------- ----- -------- ----
0 Stored 0 0% 2023-07-20 09:37 00000000 libchrony/
49 Defl:N 47 4% 2023-07-20 09:37 37c3f2e2 libchrony/.gitignore
26530 Defl:N 9350 65% 2023-07-20 09:37 5622583e libchrony/COPYING
961 Defl:N 467 51% 2023-07-20 09:37 da9221e3 libchrony/Makefile
475 Defl:N 304 36% 2023-07-20 09:37 cae27f70 libchrony/README.adoc
3313 Defl:N 1119 66% 2023-07-20 09:37 37eb110f libchrony/chrony.h
7673 Defl:N 2261 71% 2023-07-20 09:37 5d455a52 libchrony/client.c
6190 Defl:N 2093 66% 2023-07-20 09:37 7ea9d81b libchrony/example-reports.c
16348 Defl:N 3855 76% 2023-07-20 09:37 e82f5fe3 libchrony/message.c
2946 Defl:N 1099 63% 2023-07-20 09:37 945ee82b libchrony/message.h
-------- ------- --- -------
64485 20595 68% 10 files