mxlib
c++ tools for analyzing astronomical data and other tasks by Jared R. Males. [git repo]
gitRepo.cpp
Go to the documentation of this file.
1 /** \file gitRepo.cpp
2  * \author Jared R. Males
3  * \brief Interrogate the current state of a git repository (definitions)
4  * \ingroup utils_files
5  */
6 
7 //***********************************************************************//
8 // Copyright 2021 Jared R. Males (jaredmales@gmail.com)
9 //
10 // This file is part of mxlib.
11 //
12 // mxlib is free software: you can redistribute it and/or modify
13 // it under the terms of the GNU General Public License as published by
14 // the Free Software Foundation, either version 3 of the License, or
15 // (at your option) any later version.
16 //
17 // mxlib is distributed in the hope that it will be useful,
18 // but WITHOUT ANY WARRANTY; without even the implied warranty of
19 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 // GNU General Public License for more details.
21 //
22 // You should have received a copy of the GNU General Public License
23 // along with mxlib. If not, see <http://www.gnu.org/licenses/>.
24 //***********************************************************************//
25 
26 #include "mxError.hpp"
27 #include "sys/gitRepo.hpp"
28 
29 #include "ipc/processInterface.hpp"
30 #include "ioutils/stringUtils.hpp"
31 #include "ioutils/fileUtils.hpp"
32 
33 
34 namespace mx
35 {
36 namespace sys
37 {
38 
40 {
41 }
42 
43 gitRepo::gitRepo(const std::string & d)
44 {
45  dir(d);
46 }
47 
48 void gitRepo::dir(const std::string & d)
49 {
50  m_dir = d;
51 
52  getGitName();
53  getGitHash();
56 
57 }
58 
59 std::string gitRepo::dir()
60 {
61  return m_dir;
62 }
63 
64 std::string gitRepo::gitDir()
65 {
66  return m_dir + "/.git";
67 }
68 
70 {
71  int retVal;
72  std::vector<std::string> stdOut, stdErr;
73 
74  if( ipc::runCommand( retVal, stdOut, stdErr, {"git", "--git-dir=" + gitDir(), "rev-parse", "--show-toplevel"}) < 0)
75  {
76  mxError("mx::sys::gitRepo::getGitName", MXE_PROCERR, "error running git command");
77  return -1;
78  }
79 
80  if(stdErr.size() > 0)
81  {
82  mxError("mx::sys::gitRepo::getGitName", MXE_PROCERR, "error returned by git");
83 
84  for(size_t n=0; n< stdErr.size(); ++n)
85  {
86  std::cerr << "err: " << stdErr[n] << "\n";
87  }
88 
89  return -1;
90  }
91 
92  if(stdOut.size() < 1)
93  {
94  mxError("mx::sys::gitRepo::getGitName", MXE_PROCERR, "nothing returned by git");
95  return -1;
96  }
97 
98  if(stdOut.size() > 1)
99  {
100  mxError("mx::sys::gitRepo::getGitName", MXE_PROCERR, "too much returned by git");
101  return -1;
102  }
103 
104  m_name = ioutils::pathFilename(stdOut[0]);
105 
106  return 0;
107 }
108 
110 {
111  int retVal;
112  std::vector<std::string> stdOut, stdErr;
113 
114  if(ipc::runCommand( retVal, stdOut, stdErr, {"git", "--git-dir=" + gitDir(), "--work-tree=" + dir(), "log", "-1", "--format=%H"}) < 0)
115  {
116  mxError("mx::sys::gitRepo::getGitName", MXE_PROCERR, "error running git command");
117  return -1;
118  }
119 
120  if(stdErr.size() > 0)
121  {
122  mxError("mx::sys::gitRepo::getGitName", MXE_PROCERR, "error returned by git");
123 
124  for(size_t n=0; n< stdErr.size(); ++n)
125  {
126  std::cerr << "err: " << stdErr[n] << "\n";
127  }
128 
129  return -1;
130  }
131 
132  if(stdOut.size() < 1)
133  {
134  mxError("mx::sys::gitRepo::getGitName", MXE_PROCERR, "nothing returned by git");
135  return -1;
136  }
137 
138  if(stdOut.size() > 1)
139  {
140  mxError("mx::sys::gitRepo::getGitName", MXE_PROCERR, "too much returned by git");
141  return -1;
142  }
143 
144  m_hash = stdOut[0];
145 
146  return 0;
147 }
148 
150 {
151  int retVal;
152  std::vector<std::string> stdOut, stdErr;
153 
154  if(ipc::runCommand( retVal, stdOut, stdErr, {"git", "--git-dir=" + gitDir(), "--work-tree=" + dir(), "diff-index", "HEAD", "--"}) < 0)
155  {
156  mxError("mx::sys::gitRepo::getGitName", MXE_PROCERR, "error running git command");
157  return -1;
158  }
159 
160  if(stdErr.size() > 0)
161  {
162  mxError("mx::sys::gitRepo::getGitName", MXE_PROCERR, "error returned by git");
163  for(size_t n=0; n< stdErr.size(); ++n)
164  {
165  std::cerr << "err: " << stdErr[n] << "\n";
166  }
167 
168  return -1;
169  }
170 
171  m_modified = (stdOut.size() > 0); //rv;
172 
173  return 0;
174 }
175 
177 {
178  int retVal;
179  std::vector<std::string> stdOut, stdErr;
180 
181  if(ipc::runCommand(retVal, stdOut, stdErr, {"git", "--git-dir=" + gitDir(), "--work-tree=" + dir(), "status"}) < 0)
182  {
183  mxError("mx::sys::gitRepo::getGitName", MXE_PROCERR, "error running git command");
184  return -1;
185  }
186 
187  if(stdErr.size() > 0)
188  {
189  mxError("mx::sys::gitRepo::getGitName", MXE_PROCERR, "error returned by git");
190 
191  for(size_t n=0; n< stdErr.size(); ++n)
192  {
193  std::cerr << "err: " << stdErr[n] << "\n";
194  }
195 
196  return -1;
197  }
198 
199  if(stdOut.size() < 1)
200  {
201  mxError("mx::sys::gitRepo::getGitName", MXE_PROCERR, "nothing returned by git");
202  return -1;
203  }
204 
205  m_modifiedFiles.clear();
206  m_deletedFiles.clear();
207  m_renamedFiles.clear();
208  m_renamedFiles2.clear();
209  m_untrackedFiles.clear();
210 
211  for(size_t n=0; n < stdOut.size(); ++n)
212  {
213  if(stdOut[n].find("On b") != std::string::npos)
214  {
215  m_branch = stdOut[n].substr(sizeof("On branch"));
216  }
217  else if(stdOut[n].find("Changes not") != std::string::npos)
218  {
219  //Changes not staged for commit
220 
221  ++n;
222  while(stdOut[n].size() > 0)
223  {
224  if(n >= stdOut.size()) break;
225 
226  if(stdOut[n].find("mod") != std::string::npos )
227  {
228  m_modifiedFiles.insert(ioutils::removeWhiteSpace(stdOut[n].substr(sizeof("modified:"))));
229  }
230  else if(stdOut[n].find("del") != std::string::npos )
231  {
232  m_deletedFiles.insert(ioutils::removeWhiteSpace(stdOut[n].substr(sizeof("deleted:"))));
233  }
234  else if(stdOut[n].find("ren") != std::string::npos )
235  {
236  size_t a = stdOut[n].find(" -> ");
237 
238  m_renamedFiles.insert(ioutils::removeWhiteSpace(stdOut[n].substr(sizeof("renamed:"), a-sizeof("renamed:"))));
239  m_renamedFiles2.insert(ioutils::removeWhiteSpace(stdOut[n].substr(a + sizeof(" ->"))));
240  }
241  ++n;
242  }
243  }
244  else if(stdOut[n].find("Changes to") != std::string::npos)
245  {
246  //Changes to be committed
247 
248  ++n;
249  while(stdOut[n].size() > 0)
250  {
251  if(n >= stdOut.size()) break;
252 
253  if(stdOut[n].find("mod") != std::string::npos )
254  {
255  m_modifiedFiles.insert(ioutils::removeWhiteSpace(stdOut[n].substr(sizeof("modified:"))));
256  }
257  else if(stdOut[n].find("del") != std::string::npos )
258  {
259  m_deletedFiles.insert(ioutils::removeWhiteSpace(stdOut[n].substr(sizeof("deleted:"))));
260  }
261  else if(stdOut[n].find("ren") != std::string::npos )
262  {
263  size_t a = stdOut[n].find(" -> ");
264 
265  m_renamedFiles.insert(ioutils::removeWhiteSpace(stdOut[n].substr(sizeof("renamed: "), a-sizeof("renamed:"))));
266  m_renamedFiles2.insert(ioutils::removeWhiteSpace(stdOut[n].substr(a + sizeof(" ->"))));
267  }
268  ++n;
269  }
270  }
271  else if(stdOut[n].find("Untracked") != std::string::npos)
272  {
273  //Untracked files:
274 
275  ++n;
276  ++n;
277  while(stdOut[n].size() > 0)
278  {
279  if(n >= stdOut.size()) break;
280  m_untrackedFiles.insert(ioutils::removeWhiteSpace(stdOut[n]));
281  ++n;
282  }
283  }
284  }
285 
286  return 0;
287 }
288 
289 std::string gitRepo::name()
290 {
291  return m_name;
292 }
293 
294 std::string gitRepo::branch()
295 {
296  return m_branch;
297 }
298 
299 std::string gitRepo::hash()
300 {
301  return m_hash;
302 }
303 
305 {
306  return m_modified;
307 }
308 
309 bool gitRepo::isNotCommitted(const std::string & file)
310 {
311  return ( m_modifiedFiles.count(file) + m_deletedFiles.count(file) + m_renamedFiles.count(file) +
312  m_renamedFiles2.count(file) + m_untrackedFiles.count(file) > 0);
313 }
314 
315 }
316 }
317 
int getGitName()
Get the name of the git repo.
Definition: gitRepo.cpp:69
std::string gitDir()
Get the current repo's .git directory.
Definition: gitRepo.cpp:64
std::set< std::string > m_renamedFiles
Files which git lists as renamed-from.
Definition: gitRepo.hpp:67
std::string m_branch
The current branch.
Definition: gitRepo.hpp:61
std::set< std::string > m_renamedFiles2
Files which git lists as renamed-to.
Definition: gitRepo.hpp:68
bool isNotCommitted(const std::string &file)
Check whether a file is listed as not committed.
Definition: gitRepo.cpp:309
std::string m_dir
The directory of the git repository.
Definition: gitRepo.hpp:57
int getGitHash()
Get the name of the current commit hash.
Definition: gitRepo.cpp:109
std::string branch()
Get the current branch.
Definition: gitRepo.cpp:294
std::string name()
Get the repo's name.
Definition: gitRepo.cpp:289
std::string m_name
The repo name.
Definition: gitRepo.hpp:60
std::set< std::string > m_untrackedFiles
Files which git lists as untracked.
Definition: gitRepo.hpp:69
std::set< std::string > m_deletedFiles
Files which git lists as deleted.
Definition: gitRepo.hpp:66
std::set< std::string > m_modifiedFiles
Files which git lists as modified.
Definition: gitRepo.hpp:65
std::string dir()
Get the current directory.
Definition: gitRepo.cpp:59
std::string m_hash
The complete commit hash.
Definition: gitRepo.hpp:62
bool modified()
Get whether the repo is modified.
Definition: gitRepo.cpp:304
gitRepo()
Default c'tor.
Definition: gitRepo.cpp:39
int getGitModified()
Get the modification status of the repo.
Definition: gitRepo.cpp:149
bool m_modified
The modification status, true or false.
Definition: gitRepo.hpp:63
int getGitFileState()
Get the list of modified files, and the branch name.
Definition: gitRepo.cpp:176
std::string hash()
Get the current commit hash.
Definition: gitRepo.cpp:299
Declarations of utilities for working with files.
Interrogate the current state of a git repository (declarations)
int runCommand(int &retVal, std::vector< std::string > &commandOutput, std::vector< std::string > &commandStderr, const std::vector< std::string > &commandList)
Runs a command (with parameters) passed in using fork/exec.
std::string pathFilename(const std::string &fname)
Get the base filename.
Definition: fileUtils.cpp:71
void removeWhiteSpace(std::string &outstr, const std::string &instr)
Remove all white space from a string.
Declares and defines the mxlib error reporting system.
The mxlib c++ namespace.
Definition: mxError.hpp:107
Process interface facilities.
Utilities for working with strings.