1+ #include < cppgit2/repository.hpp>
2+ #include < cstdio>
3+ #include < iomanip>
4+ #include < iostream>
5+ using namespace cppgit2 ;
6+
7+ void print_signature (const std::string &header, const signature &sig) {
8+ char sign;
9+ auto offset = sig.offset ();
10+ if (offset < 0 ) {
11+ sign = ' -' ;
12+ offset = -offset;
13+ } else {
14+ sign = ' +' ;
15+ }
16+
17+ auto hours = offset / 60 ;
18+ auto minutes = offset % 60 ;
19+
20+ std::cout << header << " "
21+ << sig.name () << " "
22+ << " <" << sig.email () << " > "
23+ << sig.time () << " "
24+ << sign;
25+ std::cout << std::setw (2 ) << hours << minutes << std::endl;
26+ }
27+
28+ // Printing out a blob is simple, get the contents and print
29+ void show_blob (const blob &blob) {
30+ std::fwrite (blob.raw_contents (), blob.raw_size (), 1 , stdout);
31+ }
32+
33+ // Show each entry with its type, id and attributes
34+ void show_tree (const tree &tree) {
35+ size_t count = tree.size ();
36+ for (size_t i = 0 ; i < tree.size (); ++i) {
37+ auto entry = tree.lookup_entry_by_index (i);
38+
39+ std::cout << std::oct << std::setw (6 ) << static_cast <git_filemode_t >(entry.filemode ());
40+ std::cout << " " << object::object_type_to_string (entry.type ())
41+ << " " << tree.id ().to_hex_string ()
42+ << " \t " << entry.filename () << std::endl;
43+ }
44+ }
45+
46+ // Commits and tags have a few interesting fields in their header.
47+ void show_commit (const commit &commit) {
48+ std::cout << " tree " << commit.id ().to_hex_string () << std::endl;
49+
50+ for (size_t i = 0 ; i < commit.parent_count (); ++i)
51+ std::cout << " parent " << commit.parent_id (i).to_hex_string () << std::endl;
52+
53+ print_signature (" author" , commit.author ());
54+ print_signature (" committer" , commit.committer ());
55+
56+ auto message = commit.message ();
57+ if (!message.empty ())
58+ std::cout << " \n " << message << std::endl;
59+ }
60+
61+ void show_tag (const tag &tag) {
62+ std::cout << " object " << tag.id ().to_hex_string () << std::endl;
63+ std::cout << " type " << object::object_type_to_string (tag.target_type ()) << std::endl;
64+ std::cout << " tag " << tag.name () << std::endl;
65+ print_signature (" tagger" , tag.tagger ());
66+
67+ auto tag_message = tag.message ();
68+ if (!tag_message.empty ())
69+ std::cout << " \n " << tag_message << std::endl;
70+ }
71+
72+ int main (int argc, char **argv) {
73+ if (argc == 3 ) {
74+ auto repo_path = repository::discover_path (" ." );
75+ auto repo = repository::open (repo_path);
76+
77+ enum class actions { size, type, pretty };
78+ actions action;
79+
80+ if (strncmp (argv[1 ], " -s" , 2 ) == 0 ) {
81+ action = actions::size;
82+ } else if (strncmp (argv[1 ], " -t" , 2 ) == 0 ) {
83+ action = actions::type;
84+ } else if (strncmp (argv[1 ], " -p" , 2 ) == 0 ) {
85+ action = actions::pretty;
86+ }
87+
88+ auto revision_str = argv[2 ];
89+ auto object = repo.revparse_to_object (revision_str);
90+
91+ switch (action) {
92+ case actions::type:
93+ std::cout << object::object_type_to_string (object.type ()) << std::endl;
94+ break ;
95+ case actions::size:
96+ std::cout << repo.odb ().read (object.id ()).size () << std::endl;
97+ break ;
98+ case actions::pretty:
99+ switch (object.type ()) {
100+ case object::object_type::blob:
101+ show_blob (object.as_blob ());
102+ break ;
103+ case object::object_type::commit:
104+ show_commit (object.as_commit ());
105+ break ;
106+ case object::object_type::tree:
107+ show_tree (object.as_tree ());
108+ break ;
109+ case object::object_type::tag:
110+ show_tag (object.as_tag ());
111+ break ;
112+ default :
113+ std::cout << " unknown " << revision_str << std::endl;
114+ break ;
115+ }
116+ break ;
117+ }
118+
119+ } else {
120+ std::cout << " Usage: ./executable (-s | -t | -p) <object>\n " ;
121+ }
122+ }
0 commit comments