# # add_file "git.cc" # # add_file "git.hh" # # patch "Makefile.am" # from [a29213bdecb6d15a331d45abb2cb78babe939a1c] # to [07a02113bc93f5dd744c82d739445dd8ab4a9392] # # patch "git.cc" # from [] # to [6ea227700999cd346f440e882e01635ca37c5e55] # # patch "git.hh" # from [] # to [455688c7759d9d2d749a89abf8f12d9347b38ed5] # # patch "git_export.cc" # from [0f72eaafd40c5e9f14b1db251905ae4f95525ff8] # to [026821e40c845cfdfdef5e81aa9de0befb46f68d] # # patch "git_import.cc" # from [4d5060ff9d4e757b430bc586191bd98af333674f] # to [3ce80f9a3ecd608ff4579b80709deb66b42429fd] # ======================================================================== --- Makefile.am a29213bdecb6d15a331d45abb2cb78babe939a1c +++ Makefile.am 07a02113bc93f5dd744c82d739445dd8ab4a9392 @@ -29,6 +29,7 @@ mkstemp.cc mkstemp.hh \ lcs.cc lcs.hh \ rcs_import.cc rcs_import.hh \ + git.cc git.hh \ git_import.cc git_import.hh \ git_export.cc git_export.hh \ revision.cc revision.hh \ ======================================================================== --- git.cc +++ git.cc 6ea227700999cd346f440e882e01635ca37c5e55 @@ -0,0 +1,151 @@ +// -*- mode: C++; c-file-style: "gnu"; indent-tabs-mode: nil -*- +// vim:sw=2: +// Copyright (C) 2005 Petr Baudis +// all rights reserved. +// licensed to the public under the terms of the GNU GPL (>= 2) +// see the file COPYING for details + +// Common utility functions for manipulating GIT-related stuff +// and communicating with GIT itself. +// Sponsored by Google's Summer of Code and SuSE + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef WIN32 + +#include + +#include +#include // strdup(), woo-hoo! + +#include +#include +#include +#include + +#include +#include +#include + +#include "app_state.hh" +#include "cert.hh" +#include "constants.hh" +#include "database.hh" +#include "file_io.hh" +#include "git.hh" +#include "mkstemp.hh" + +using namespace std; +using boost::shared_ptr; +using boost::scoped_ptr; + + +string const gitcommit_id_cert_name = "gitcommit-id"; +string const gitcommit_committer_cert_name = "gitcommit-committer"; + + +void +set_git_env(string const & name, string const & value) +{ + char *env_entry = strdup((name + "=" + value).c_str()); + putenv(env_entry); +} + +void +stream_grabline(istream &stream, string &line) +{ + // You can't hate C++ as much as I do. + char linebuf[256]; + stream.getline(linebuf, 256); + line = linebuf; +} + +int +git_tmpfile(string &tmpfile) +{ + char *tmpdir = getenv("TMPDIR"); + if (!tmpdir) + tmpdir = "/tmp"; + + tmpfile = string(tmpdir); + tmpfile += "/mtgit.XXXXXX"; + return monotone_mkstemp(tmpfile); +} + + +void +capture_git_cmd_output(boost::format const & fmt, filebuf &fb) +{ + string str; + try + { + str = fmt.str(); + } + catch (std::exception & e) + { + P(F("capture_git_cmd_output() formatter failed: %s") % e.what()); + throw e; + } + + string tmpfile; + int fd = git_tmpfile(tmpfile); + + string cmdline("(" + str + ") >" + tmpfile); + L(F("Capturing cmd output: %s") % cmdline); + N(system(cmdline.c_str()) == 0, + F("git command %s failed") % str); + fb.open(tmpfile.c_str(), ios::in); + close(fd); + delete_file(system_path(tmpfile)); +} + +void +capture_git_cmd_io(boost::format const & fmt, data const &input, filebuf &fbout) +{ + string str; + try + { + str = fmt.str(); + } + catch (std::exception & e) + { + P(F("capture_git_cmd_io() formatter failed: %s") % e.what()); + throw e; + } + + string intmpfile; + { + int fd = git_tmpfile(intmpfile); + filebuf fb; + fb.open(intmpfile.c_str(), ios::out); + close(fd); + ostream stream(&fb); + stream << input(); + } + + string outtmpfile; + int fd = git_tmpfile(outtmpfile); + string cmdline("(" + str + ") <" + intmpfile + " >" + outtmpfile); + L(F("Feeding cmd input and grabbing output: %s") % cmdline); + N(system(cmdline.c_str()) == 0, + F("git command %s failed") % str); + fbout.open(outtmpfile.c_str(), ios::in); + close(fd); + delete_file(system_path(outtmpfile)); + delete_file(system_path(intmpfile)); +} + +#endif ======================================================================== --- git.hh +++ git.hh 455688c7759d9d2d749a89abf8f12d9347b38ed5 @@ -0,0 +1,37 @@ +#ifndef __GIT_HH__ +#define __GIT_HH__ + +// Copyright (C) 2005 Petr Baudis +// all rights reserved. +// licensed to the public under the terms of the GNU GPL (>= 2) +// see the file COPYING for details + +// GIT "library" interface + +#include +#include + +#include "vocab.hh" +#include "database.hh" + +typedef hexenc git_object_id; + +struct +git_person +{ + std::string name, email; +}; + + +extern std::string const gitcommit_id_cert_name; +extern std::string const gitcommit_committer_cert_name; + + +void set_git_env(std::string const &name, std::string const &value); +void stream_grabline(std::istream &stream, std::string &line); +int git_tmpfile(std::string &tmpfile); + +void capture_git_cmd_output(boost::format const &fmt, std::filebuf &fbout); +void capture_git_cmd_io(boost::format const &fmt, data const &input, std::filebuf &fbout); + +#endif // __GIT_HH__ ======================================================================== --- git_export.cc 0f72eaafd40c5e9f14b1db251905ae4f95525ff8 +++ git_export.cc 026821e40c845cfdfdef5e81aa9de0befb46f68d @@ -48,6 +48,7 @@ #include "constants.hh" #include "database.hh" #include "file_io.hh" +#include "git.hh" #include "git_export.hh" #include "keys.hh" #include "manifest.hh" @@ -61,15 +62,7 @@ using boost::shared_ptr; using boost::scoped_ptr; -typedef hexenc git_object_id; - struct -git_person -{ - string name, email; -}; - -struct git_tree_entry { bool execute; @@ -121,108 +114,14 @@ }; - -static string const gitcommit_id_cert_name = "gitcommit-id"; -static string const gitcommit_committer_cert_name = "gitcommit-committer"; - /*** The raw GIT interface */ -static void -set_git_env(string const & name, string const & value) -{ - char *env_entry = strdup((name + "=" + value).c_str()); - putenv(env_entry); -} - -static void -stream_grabline(istream &stream, string &line) -{ - // You can't hate C++ as much as I do. - char linebuf[256]; - stream.getline(linebuf, 256); - line = linebuf; -} - - -static int -git_tmpfile(string &tmpfile) -{ - char *tmpdir = getenv("TMPDIR"); - if (!tmpdir) - tmpdir = "/tmp"; - - tmpfile = string(tmpdir); - tmpfile += "/mtgit.XXXXXX"; - return monotone_mkstemp(tmpfile); -} - -static void -capture_cmd_output(boost::format const & fmt, filebuf &fb) -{ - string str; - try - { - str = fmt.str(); - } - catch (std::exception & e) - { - P(F("capture_cmd_output() formatter failed: %s") % e.what()); - throw e; - } - - string tmpfile; - int fd = git_tmpfile(tmpfile); - string cmdline("(" + str + ") >" + tmpfile); - L(F("Capturing cmd output: %s") % cmdline); - N(system(cmdline.c_str()) == 0, - F("git command %s failed") % str); - fb.open(tmpfile.c_str(), ios::in); - close(fd); - delete_file(system_path(tmpfile)); -} - -static void -capture_cmd_io(boost::format const & fmt, data const &input, filebuf &fbout) -{ - string str; - try - { - str = fmt.str(); - } - catch (std::exception & e) - { - P(F("capture_cmd_io() formatter failed: %s") % e.what()); - throw e; - } - - string intmpfile; - { - int fd = git_tmpfile(intmpfile); - filebuf fb; - fb.open(intmpfile.c_str(), ios::out); - close(fd); - ostream stream(&fb); - stream << input(); - } - - string outtmpfile; - int fd = git_tmpfile(outtmpfile); - string cmdline("(" + str + ") <" + intmpfile + " >" + outtmpfile); - L(F("Feeding cmd input: %s") % cmdline); - N(system(cmdline.c_str()) == 0, - F("git command %s failed") % str); - fbout.open(outtmpfile.c_str(), ios::in); - close(fd); - delete_file(system_path(outtmpfile)); - delete_file(system_path(intmpfile)); -} - // XXX: Code duplication with git_db::load_revs(). static void get_gitrev_ancestry(git_object_id revision, set &ancestry) { filebuf fb; - capture_cmd_output(F("git-rev-list %s") % revision(), fb); + capture_git_cmd_output(F("git-rev-list %s") % revision(), fb); istream stream(&fb); stack st; @@ -287,7 +186,7 @@ N(system(cmdline.c_str()) == 0, F("Adding '%s' failed") % blobpath); filebuf fb; - capture_cmd_output(F("cd '%s' && git-ls-files --stage") % strpath, fb); + capture_git_cmd_output(F("cd '%s' && git-ls-files --stage") % strpath, fb); istream stream(&fb); string line; stream_grabline(stream, line); @@ -321,7 +220,7 @@ N(system(cmdline.c_str()) == 0, F("Writing tree index failed")); filebuf fb; - capture_cmd_output(F("git-write-tree"), fb); + capture_git_cmd_output(F("git-write-tree"), fb); istream stream(&fb); string line; stream_grabline(stream, line); @@ -358,7 +257,7 @@ cmdline += "-p " + (*i)() + " "; } filebuf fb; - capture_cmd_io(F("%s") % cmdline, mylogmsg, fb); + capture_git_cmd_io(F("%s") % cmdline, mylogmsg, fb); istream stream(&fb); string line; stream_grabline(stream, line); ======================================================================== --- git_import.cc 4d5060ff9d4e757b430bc586191bd98af333674f +++ git_import.cc 3ce80f9a3ecd608ff4579b80709deb66b42429fd @@ -47,6 +47,7 @@ #include "constants.hh" #include "database.hh" #include "file_io.hh" +#include "git.hh" #include "git_import.hh" #include "keys.hh" #include "manifest.hh" @@ -78,17 +79,9 @@ * the hash, but it wouldn't be as easy to code, so it's a TODO. */ -typedef hexenc git_object_id; - struct git_history; struct -git_person -{ - string name, email; -}; - -struct git_db { const system_path path; @@ -125,44 +118,11 @@ /*** The raw GIT interface */ -// This should change to libgit calls in the future - -static void -capture_cmd_output(boost::format const & fmt, filebuf &fb) -{ - string str; - try - { - str = fmt.str(); - } - catch (std::exception & e) - { - P(F("capture_cmd_output() formatter failed: %s") % e.what()); - throw e; - } - - char *tmpdir = getenv("TMPDIR"); - if (!tmpdir) - tmpdir = "/tmp"; - string tmpfile(tmpdir); - tmpfile += "/mtoutput.XXXXXX"; - int fd = monotone_mkstemp(tmpfile); - - string cmdline("(" + str + ") >" + tmpfile); - L(F("Capturing cmd output: %s") % cmdline); - N(system(cmdline.c_str()) == 0, - F("git command %s failed") % str); - fb.open(tmpfile.c_str(), ios::in); - close(fd); - delete_file(system_path(tmpfile)); -} - - void git_db::get_object(const string type, const git_object_id objid, filebuf &fb) { - capture_cmd_output(F("git-cat-file %s %s") % type % objid(), fb); + capture_git_cmd_output(F("git-cat-file %s %s") % type % objid(), fb); } void @@ -183,7 +143,7 @@ git_db::get_object_type(const git_object_id objid) { filebuf fb; - capture_cmd_output(F("git-cat-file -t %s") % objid(), fb); + capture_git_cmd_output(F("git-cat-file -t %s") % objid(), fb); istream stream(&fb); string type; @@ -201,7 +161,7 @@ excludestr += " \"^" + (*i)() + "\""; filebuf fb; - capture_cmd_output(F("git-rev-list --topo-order %s %s") + capture_git_cmd_output(F("git-rev-list --topo-order %s %s") % revision % excludestr, fb); istream stream(&fb); @@ -300,9 +260,6 @@ } -static string const gitcommit_id_cert_name = "gitcommit-id"; -static string const gitcommit_committer_cert_name = "gitcommit-committer"; - // TODO: Make git_heads_on_branch() and historical_gitrev_to_monorev() share // code.