Sometimes, it is useful to have a snapshot of the directory structure as specified by a particular commit, but without the corresponding history. This can, of course, be done by checking the particular commit followed by deleting/omitting the .git
folder when creating an archive. But with Git, there is a better way to do this, which is built in so it is possible to create an archive from a particular commit or reference. When using Git to create the archive, you also make sure that the archive only contains the files tracked by Git and not any untracked files or folders you might have in your working directory.
We'll use the same offline-sharing
repository as used in the previous examples in this chapter:
$ git clone https://github.com/dvaske/offline-sharing.git Cloning into 'offline-sharing'... remote: Counting objects: 32, done. remote: Compressing objects: 100% (25/25), done. remote: Total 32 (delta 7), reused 30 (delta 6) Unpacking objects: 100% (32/32), done. Checking connectivity... done. $ cd offline-sharing
We'll start by creating an archive of the directory structure on the latest commit on the master
branch. The offline-sharing
repository is checked out on the develop
branch by default, so we'll use the reference origin/master
to specify the ref for the archive:
$ git archive --prefix=offline/ -o offline.zip origin/master
The --prefix
option prepends the specified prefix to each file in the archive, effectively adding an offline
directory as a root directory for the files in the repository,and the -o
option tells Git to create the archive in the offline.zip
file which of course, is compressed in the zip format. We can investigate the zip archive to check whether the files contain the following:
$ unzip -l offline.zip Archive: offline.zip 1e42a2dfa3a377d412efd27a77b973c75935c62a Length Date Time Name -------- ---- ---- ---- 0 04-10-14 09:19 offline/ 162 04-10-14 09:19 offline/README.md 485 04-10-14 09:19 offline/another_pi.c 672 04-10-14 09:19 offline/math.c -------- ------- 1319 4 files
If we look in the Git repository in the origin/master
commit, we can see that the files are the same; the -l
option tells Git to specify each file's size as follows:
$ git ls-tree -l origin/master 100644 blob c79cad47938a25888a699142ab3cdf764dc99193 162 README.md 100644 blob 86df41b3a8bbfb588e57c7b27742cf312ab3a12a 485 another_pi.c 100644 blob d393b41eb14561e583f1b049db716e35cef326c3 672 math.c
The archive command can also be used to create an archive for a subdirectory of the repository. We can use this on the doc
branch of the repository to zip the content of the Documentation
folder:
$ git archive --prefix=docs/ -o docs.zip origin/doc:Documentation
Again, we can list the contents of the zip file and the Documentation
tree at origin/doc
as follows:
$ unzip -l docs.zip Archive: docs.zip Length Date Time Name -------- ---- ---- ---- 0 04-13-14 21:14 docs/ 99 04-13-14 21:14 docs/README.md 152 04-13-14 21:14 docs/build.md -------- ------- 251 3 files $ git ls-tree -l origin/doc:Documentation 100644 blob b65b4fc78c0e39b3ff8ea549b7430654d413159f 99 README.md 100644 blob f91777f3e600db73c3ee7b05ea1b7d42efde8881 152 build.md
There are other format options besides the zip format for the archive, for example, tar, tar.gz, and so on. The format can be specified with the --format=<format>
option or as a suffix to the output file name with the -o
option. The following two commands will produce the same output file:
$ git archive --format=tar.gz HEAD > offline.tar.gz $ git archive -o offline.tar.gz HEAD
The Git archive command behaves a bit differently if a commit/tag ID or a tree ID is passed as an identifier. If a commit or tag ID is given, the ID will be stored in a global extended pax header for the tar format and as a file comment for the zip format. If only the tree ID is given, no extra information will be stored. You can actually see this in the previous examples where the first ID was given a branch as a reference. As the branch points to a commit, the ID of this commit was written as a comment to the file and we can actually see it in the output of the archive listing:
$ unzip -l offline.zip Archive: offline.zip 1e42a2dfa3a377d412efd27a77b973c75935c62a Length Date Time Name -------- ---- ---- ---- 0 04-10-14 09:19 offline/ 162 04-10-14 09:19 offline/README.md 485 04-10-14 09:19 offline/another_pi.c 672 04-10-14 09:19 offline/math.c -------- ------- 1319 4 files
In the second example, we also passed a branch as a reference, but furthermore we specified the Documentation
folder as the subfolder we wanted to create an archive from. This corresponds to passing the ID of the tree to the archive command; hence, no extra information will be stored in the archive.