git/list[1] front-page[2] threads[3] people[4] search[5] about
 

Re: Clone a repository with only the objects needed for a single tag

From
Junio C Hamano <junkio@cox.net>
Date
Nov 2, 2005, 09:20 UTC
Message-ID
<7voe53v21h.fsf@assigned-by-dhcp.cox.net>
In-Reply-To
<43687869.7060104@ust.hk>
Ben Lau <benlau@ust.hk> writes:
>  However, it has a problem when involves the gitk/git-log.

That's why I said anything that requires you to have a complete history would not work.

The shallow repository is by definition a *broken* repository; the refs are supposed to mean the repository has everything reachable from them, and many tools rely on that assumption, but the shallow setup deliberately breaks that assumption, so you need to be aware of what operations you can and cannot do without having the full history. Although using grafts to cauterize somewhat helps as you discovered, you are operating in "do it at your own risk" territory.

Having said that, here are the things that *should* work without having full history (not many):

        . git diff between your index, working tree, and commits
          your shallow setup happens to have.
        . git commit on top of any of the tip of branches your
          shallow copy started out with, including git am and git
          applymbox.
        . git fetch/pull over commit walker from a remote
          repository.
        . git push to send the work done in the shallow repository
          back into your mothership repository (running git pull on
          the mothership to fetch from the shallow copy probably
          would not work, unless you use commit walkers).
	. git whatchanged, git log, and gitk to view the work
	  you did in your shallow repository.

Creating packs in the mothership repository is certainly possible. You could instead do this:

	$ git-shallow-pack --all ;# in mothership
        $ mkdir -p /var/tmp/shallow
        $ tar cf - .git/HEAD .git/refs/ |
          (cd /var/tmp/shallow; git-init-db; tar xf -)
        $ mv pack-* /var/tmp/shallow/.git/objects/pack

If you want a bit deeper history, instead of giving '--all' to git-shallow-pack, you could probably say something silly like this:

	$ (git-rev-parse --all; git-rev-list --max-count=20 HEAD) |
          xargs git-shallow-pack

The shallow-pack script I sent earlier is probably not very useful in practice. To polish it to be somewhat more useful, it would probably need the following enhancements, at least:

	. Instead of taking 'git-rev-parse' arguments, take the
	  names of refs;
	. Instead of packing the objects contained in the
          commits and trees the named refs reference, include
          all blobs/trees/commits between the given refs and
          their common ancestor to create a pack;
	. Create a tarball that contains:
	  (1) the pack file created by the above procedure,
              stored in .git/objects/pack/.;
          (2) .git/refs/ to be used in the shallow copy; this
              should include only the refs given to the command
              to create the above pack.
	  (3) .git/info/grafts to cauterize the common ancestor
              commit and side branches merged into the lines you
              are taking (computing the latter may be somewhat
              expensive).

Then the command can be run in the mothership repository like this:

	$ cd linux-2.6
        $ git-shallow-pack v2.6.14 v2.6.14-rc2 master

to produce a tarball, which can be taken to another location. When extracted, it would contain all commits between the three named refs, and you could view the history across them.

Previous: Ben Lau
Message 6 of 6 in “Clone a repository with only the objects needed for a single tag”
  1. Ben LauNov 2, 2005
  2. Junio C HamanoNov 2, 2005
  3. Ben LauNov 2, 2005
  4. Andreas EricssonNov 2, 2005
  5. Ben LauNov 2, 2005
  6. Junio C HamanoNov 2, 2005

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.