Creating archives from a tree

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.

Getting ready

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

How to do it...

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

There's more…

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.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset