Way quicker and easier to simply use the .gitignore to figure out if an important file has changed. This is probably chock full of bugs and memory leaks but it is working.

master
Zed A. Shaw 4 months ago
parent 83b6aa7cd0
commit 5c1b6d9243
  1. 2
      .gitignore
  2. 89
      watchgit.cpp

2
.gitignore vendored

@ -11,3 +11,5 @@ subprojects
*.csv *.csv
*.exe *.exe
*.dll *.dll
*~
[0-9]*

@ -14,9 +14,11 @@
#include <efsw/efsw.hpp> #include <efsw/efsw.hpp>
#include <regex> #include <regex>
#include <set> #include <set>
#include <filesystem>
using namespace std; using namespace std;
using namespace fmt; using namespace fmt;
namespace fs = std::filesystem;
#define BUF_MAX 1024 #define BUF_MAX 1024
@ -45,69 +47,6 @@ class GameEngine {
}; };
/*
* No idea what the semantics of this are. Will need
* to research git's dumb terminology to figure out why
* they have 4 different versions of the path for status.
*/
const char *unfuck_path(const git_status_entry *entry) {
if(entry->head_to_index != nullptr) {
if(entry->head_to_index->new_file.path) {
return entry->head_to_index->new_file.path;
} else {
return entry->head_to_index->old_file.path;
}
}
if(entry->index_to_workdir != nullptr) {
if(entry->index_to_workdir->new_file.path) {
return entry->index_to_workdir->new_file.path;
} else {
return entry->index_to_workdir->old_file.path;
}
}
return nullptr;
}
void add_status(const git_status_entry *entry, unsigned int status_flags, set<string> &updates) {
const char *path = unfuck_path(entry);
if(status_flags & GIT_STATUS_WT_NEW
|| status_flags & GIT_STATUS_INDEX_NEW)
{
updates.insert(string{path});
}
if(status_flags & GIT_STATUS_WT_MODIFIED
|| status_flags & GIT_STATUS_INDEX_MODIFIED)
{
updates.insert(string{path});
}
// need to confirm this gets the new name
if(status_flags & GIT_STATUS_WT_RENAMED
|| status_flags & GIT_STATUS_INDEX_RENAMED)
{
updates.insert(string{path});
}
}
void list_git_changes(set <string> &updates, git_repository* repo) {
git_status_options opts = GIT_STATUS_OPTIONS_INIT;
git_status_list *statuses = nullptr;
//TODO: does this leak?
int err = git_status_list_new(&statuses, repo, &opts);
dbc::check(err == 0, git_error_last()->message);
size_t count = git_status_list_entrycount(statuses);
for(size_t i=0; i < count; i++) {
const git_status_entry *entry = git_status_byindex(statuses, i);
add_status(entry, entry->status, updates);
}
}
class UpdateListener : public efsw::FileWatchListener { class UpdateListener : public efsw::FileWatchListener {
public: public:
@ -122,11 +61,25 @@ class UpdateListener : public efsw::FileWatchListener {
efsw::Action action, efsw::Action action,
std::string oldFilename) override std::string oldFilename) override
{ {
set<string> updates;
list_git_changes(updates, repo); // this is some gnarly BS here, probably tons
bool in_git = updates.contains(filename); // of memory leaks for now but it's working
// this makes it so we only get it set one time when somethign is in git int ignored = 1;
changes = changes || in_git; auto the_path = fs::path(dir) / fs::path(filename);
string full_path = the_path.lexically_normal().string();
std::replace(full_path.begin(),
full_path.end(), '\\', '/');
int rc = git_ignore_path_is_ignored(&ignored, repo, full_path.c_str());
dbc::check(rc == 0, "git ignored failed.");
if(!ignored) {
println("filename={}, ignored={}", full_path.c_str(), ignored);
changes = changes || !ignored;
}
} }
void reset_state() { void reset_state() {

Loading…
Cancel
Save