1 /*
2     Copyright (C) 2009 Andrew Caudwell (acaudwell@gmail.com)
3 
4     This program is free software; you can redistribute it and/or
5     modify it under the terms of the GNU General Public License
6     as published by the Free Software Foundation; either version
7     3 of the License, or (at your option) any later version.
8 
9     This program is distributed in the hope that it will be useful,
10     but WITHOUT ANY WARRANTY; without even the implied warranty of
11     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12     GNU General Public License for more details.
13 
14     You should have received a copy of the GNU General Public License
15     along with this program.  If not, see <http://www.gnu.org/licenses/>.
16 */
17 
18 #include "gitraw.h"
19 
20 Regex git_raw_commit("^commit ([0-9a-z]+)");
21 Regex git_raw_tree("^tree ([0-9a-z]+)");
22 Regex git_raw_parent("^parent ([0-9a-z]+)");
23 Regex git_raw_author("^author (.+) <([^@>]+)@?([^>]*)> (\\d+) ([-+]\\d+)");
24 Regex git_raw_committer("^committer (.+) <([^@>]+)@?([^>]*)> (\\d+) ([-+]\\d+)");
25 Regex git_raw_file("^:[0-9]+ [0-9]+ [0-9a-z]+\\.* ([0-9a-z]+)\\.* ([A-Z])[ \\t]+(.+)");
26 
27 // parse git log entries
28 
29 // NOTE: this format is deprecated and exists
30 // to allow existing log files produced in this format to work
31 
32 std::string gGourceGitRawLogCommand = "git log --reverse --raw --pretty=raw";
33 
GitRawCommitLog(const std::string & logfile)34 GitRawCommitLog::GitRawCommitLog(const std::string& logfile) : RCommitLog(logfile, 'c') {
35 
36     log_command = gGourceGitRawLogCommand;
37 }
38 
parseCommit(RCommit & commit)39 bool GitRawCommitLog::parseCommit(RCommit& commit) {
40 
41     std::string line;
42     std::vector<std::string> entries;
43 
44     //read commit ref/ branch
45     if(!logf->getNextLine(line)) return false;
46 
47     //commit
48     if(!git_raw_commit.match(line, &entries)) return false;
49 
50     if(!logf->getNextLine(line)) return false;
51 
52     //tree
53     if(!git_raw_tree.match(line, &entries)) return false;
54 
55     if(!logf->getNextLine(line)) return false;
56 
57     //0 or more parents
58     while(git_raw_parent.match(line, &entries)) {
59         if(!logf->getNextLine(line)) return false;
60     }
61 
62     //author - used for display name
63     if(!git_raw_author.match(line, &entries)) return false;
64 
65     commit.username = entries[0];
66 
67     if(!logf->getNextLine(line)) return false;
68 
69     //committer - used for time (most likely cronological)
70     if(!git_raw_committer.match(line, &entries)) return false;
71 
72     commit.timestamp = atol(entries[3].c_str());
73 
74     //blank line before message
75     if(!logf->getNextLine(line)) return false;
76 
77     //read commit message
78     while(logf->getNextLine(line) && line.size()) {
79     }
80 
81     //read files
82     while(logf->getNextLine(line) && line.size()) {
83         //debugLog("file??? %s\n", line.c_str());
84 
85         if(git_raw_file.match(line, &entries)) {
86                 commit.addFile(entries[2], entries[1]);
87         }
88     }
89 
90 //    commit.debug();
91 
92     return true;
93 }
94