18

Using the OS X terminal,

How an you view the contents of these files as plain text?

Corey Floyd
  • 25,929
  • 31
  • 126
  • 154
  • 1
    These files are inherently not plain-text, and to view them as such, you need a program which converts them from their format into text. Git is a program with components designed to do precisely that. I would be extremely surprised if anyone has written another one. – Cascabel Oct 07 '09 at 15:38
  • So the objects (specifically commit objects) won't convert to plain text? – Corey Floyd Oct 07 '09 at 15:56
  • They are *at least* compressed using zlib (deflate) compression. – Jakub Narębski Oct 07 '09 at 17:22
  • 1
    @CoreyFloyd Of course they'll convert to plain text! That's what `git` is for! – lmat - Reinstate Monica Jul 11 '13 at 19:56
  • This can be broken into three questions: 1) calculate the hash: http://stackoverflow.com/questions/7225313/how-does-git-compute-file-hashes 2) If on a loose object, DEFLATE: http://stackoverflow.com/questions/3178566/deflate-command-line-tool 3) If in a packfile... learn how packfiles work and reimplement them :) http://stackoverflow.com/questions/9478023/is-the-git-binary-diff-algorithm-delta-storage-standardized/27462206 , http://stackoverflow.com/questions/76002/git-pack-file-entry-format – Ciro Santilli OurBigBook.com Dec 14 '14 at 09:12

5 Answers5

17
alias deflate="perl -MCompress::Zlib -e 'undef $/; print uncompress(<>)'"

deflate .git/objects/4b/3083256dedabd68e839d7717aa785424119990 | sha1sum
4b3083256dedabd68e839d7717aa785424119990  -
bwtaylor
  • 382
  • 2
  • 5
  • This answer works on any machine with perl, whereas the accepted answer refers to a specific tool `zpipe` which isn't immediately available on macOS, for example. It would be good if it described what the `perl` invocation was doing, though: loading the `zlib` module from the perl stdlib, then decompressing stdin. I love perl! – cosmicexplorer Jun 24 '19 at 13:35
  • I upvoted but it should be named "inflate" compress=deflate, uncompress=inflate – Hugues M. Jun 11 '20 at 09:13
11

I'm going to interpret your question in a different way. If you want to understand what the objects files ARE, you can use git to view them directly, without navigating the history log or using git checkout, diff etc. For instance:

For the file .git/objects/04/a42e9a7282340ef0256eaa6d59254227b8b141

Run the command

git show 04a42e

which combines the 04 from /04/ and the first four characters of the remaining number a42e.

> git show 04a42e
commit 04f7db976fa54c72fcc6350dd7d0aa06cb249df6
Author: Alex Brown <alex@XXXX.XXX>
Date:   Fri Jan 8 11:02:21 2010 +0000
a text file

diff --git a/1.txt b/1.txt
new file mode 100644
index 0000000..04a42e9
--- /dev/null
+++ b/1.txt
@@ -0,0 +1,3 @@
+Woo
+# boo
+# choo

This one is a commit, other objects may be file blobs, trees, etc.

Alex Brown
  • 41,819
  • 10
  • 94
  • 108
10

Look at “Object storage format” in Git User Manual.

It is raw compressed data using zlib. One can use zpipe from the 'zlib1g-dev' package. Compile the example with gcc -o zpipe zpipe.c -lz. It is not a standard .gz or something.

./zpipe -d < .git/objects/02/43019ddb4d94114e5a8580eec01baeea195133

prints the content of the blob (header+data)

If you want to check the SHA-1, you have to put the uncompressed blob in a file (myblob) and do

sha1sum myblob
Greg Bacon
  • 134,834
  • 32
  • 188
  • 245
xof
  • 116
  • 1
  • 2
9

If you want to view plain text form of git objects (commits and/or blobs i.e. file contents) without using git, it would not be easy, especially if repository is packed. Can't you install git locally, in your home directory (or its equivalent on MacOS X)?

The format for loose objects, stored as files in .git/objects/ fan-out directory, e.g. .git/objects/02/43019ddb4d94114e5a8580eec01baeea195133 (the fan-out directory and file name form SHA-1 identifier of object), is described e.g. in Chapter 9.2 "Git Objects" of "Pro Git" book (available on-line for free) and Chapter 7.1 "How Git Stores Objects" of "Git Community Book".

The pack format, where set of objects is stored in single file in .git/objects/pack/, e.g. .git/objects/pack/pack-1db7aa96d95149a4dd341490a3594181a24415ee.pack, is described in Documentation/technical/pack-format.txt and in Chapter 7.5 "The Packfile" of "Git Community Book" (and mentioned in Chapter 9.4 "Packfiles" of "Pro Git")


If you want to find latest commit, take a look first at .git/HEAD file to find current branch. It would contain something like the following:

ref: refs/heads/master

(if it contains SHA-1, you can take it as id of last commit, and skip a step). Then check e.g. .git/refs/heads/master to find where the branch points to. It would contain SHA-1 of a commit, e.g.:

dbc1b1f71052c084a84b5c395e1cb4b5ae526fcb

Last (most recent) commit would be probably in loose format; in this example it would be in .git/objects/db/c1b1f71052c084a84b5c395e1cb4b5ae526fcb file.

Jakub Narębski
  • 309,089
  • 65
  • 217
  • 230
0

The index is stored under .git/index.

It is a binary uncompressed format specified at: https://github.com/git/git/blob/master/Documentation/technical/index-format.txt, so the only way to read it is with a tool like hd.

The index file contains a list of files with their metadata, including inode, permissions, and modification time. It also contains the SHA-1 of the content, which is stored as an object, which means that when you do git add it may create new objects.

I encourage you to create a simple test repo like git init init && cd init && echo a > a && git add a, and then hd .git/index to verify the format field by field.

The following question focuses more on the index: What does the git index contain EXACTLY?

Community
  • 1
  • 1
Ciro Santilli OurBigBook.com
  • 347,512
  • 102
  • 1,199
  • 985