{"thread":{"id":"50704","subject":"Refresh index without discard_index + repo_read_index","startedAt":"2019-03-09T19:59:58Z","lastAt":"2019-03-11T16:00:35Z","messageCount":2,"participants":["Roman Perepelitsa"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"371050","messageId":"CAN=4vMp1+=hmdRiuC1Y-4w2iKbSuwgAi54ozDzK2dGwn7J=QUQ@mail.gmail.com","threadId":"50704","inReplyTo":null,"subject":"Refresh index without discard_index + repo_read_index","fromName":"Roman Perepelitsa","fromEmail":"roman.perepelitsa@gmail.com","sentAt":"2019-03-09T19:59:45Z","receivedAt":"2019-03-09T19:59:58Z","isPatch":false,"sender":{"key":"roman.perepelitsa@gmail.com","avatar":null},"body":"I’m writing a program that reads stdin in a loop and prints the\nequivalent of `git status` whenever it reads a character. It always\nprints its results for the same repository, the same pathspec, etc.\nThe input characters have no effect on the output, only the sate of\nthe repository does.\nI’m hoping that I can make it produce results faster than a bash\nscript that literally calls `git status` in a loop. I’m thinking that\nmaybe I can keep some caches around so that I don’t have to redo all\nthe work on every iteration that git status does.\n\nWhat I cannot figure out is how to refresh the index so that it picks\nup all the changes that might have happened to the repository and\nworkdir since the last iteration. Here’s what I have:\n\n```c\n#include <stdio.h>\n#include <string.h>\n\n#define USE_THE_INDEX_COMPATIBILITY_MACROS\n#include \"cache.h\"\n#include \"wt-status.h\"\n#include \"pathspec.h\"\n#include \"repository.h\"\n\nint cmd_multi_status(int argc, const char** argv, const char* prefix) {\n  struct pathspec pathspec;\n  memset(&pathspec, 0, sizeof(pathspec));\n  repo_read_index(the_repository);\n  while (getchar() != EOF) {\n    refresh_index(&the_index,\n                  REFRESH_QUIET | REFRESH_UNMERGED | REFRESH_REALLY,\n                  &pathspec, NULL, NULL);\n    int uncommitted = has_uncommitted_changes(the_repository, 1);\n    int unstaged = has_unstaged_changes(the_repository, 1);\n    int untracked = has_untracked(the_repository);  // I added this to\nwt-status.h\n    printf(\"%d %d %d\\n\", uncommitted, unstaged, untracked);\n  }\n  return 0;\n}\n```\n\nThis produces correct results on the first iteration but then it\ndoesn’t pick up all changes. I’ve hacked some code in preload-index.c\nand cache.c so that it picks up more changes but I still cannot detect\nwhen an unstaged file becomes uncommitted or the other way around.\n\nAny pointers would be greatly appreciated.\n\nRoman.\n\nP.S.\n\nI have working code that uses libgit2. Updating the index with\n`git_index_read(index, 0)` works as expected and is indeed faster than\ndiscarding the index and starting from scratch. But it's still slower\nthan `git status` on large repositories, especially with many ignored\nfiles.\n"},{"id":"371157","messageId":"CAN=4vMpN2UrZvJSedCyP=oh7aXTj5hWg9Yq6tfdTxMd895Rpxg@mail.gmail.com","threadId":"50704","inReplyTo":"CAN=4vMp1+=hmdRiuC1Y-4w2iKbSuwgAi54ozDzK2dGwn7J=QUQ@mail.gmail.com","subject":"Re: Refresh index without discard_index + repo_read_index","fromName":"Roman Perepelitsa","fromEmail":"roman.perepelitsa@gmail.com","sentAt":"2019-03-11T16:00:20Z","receivedAt":"2019-03-11T16:00:35Z","isPatch":false,"sender":{"key":"roman.perepelitsa@gmail.com","avatar":null},"body":"In the end I managed to patch diffing code in libgit2\n(git_diff_tree_to_index and git_diff_index_to_workdir) to make it\nabout 4x faster. It's now faster than `git status`, so good enough for\nme.\n\nI'm still curious whether it's possible to refresh index in git (not\nlibgit2), so please chime if if you know.\n\nRoman.\n\nOn Sat, Mar 9, 2019 at 8:59 PM Roman Perepelitsa\n<roman.perepelitsa@gmail.com> wrote:\n>\n> I’m writing a program that reads stdin in a loop and prints the\n> equivalent of `git status` whenever it reads a character. It always\n> prints its results for the same repository, the same pathspec, etc.\n> The input characters have no effect on the output, only the sate of\n> the repository does.\n> I’m hoping that I can make it produce results faster than a bash\n> script that literally calls `git status` in a loop. I’m thinking that\n> maybe I can keep some caches around so that I don’t have to redo all\n> the work on every iteration that git status does.\n>\n> What I cannot figure out is how to refresh the index so that it picks\n> up all the changes that might have happened to the repository and\n> workdir since the last iteration. Here’s what I have:\n>\n> ```c\n> #include <stdio.h>\n> #include <string.h>\n>\n> #define USE_THE_INDEX_COMPATIBILITY_MACROS\n> #include \"cache.h\"\n> #include \"wt-status.h\"\n> #include \"pathspec.h\"\n> #include \"repository.h\"\n>\n> int cmd_multi_status(int argc, const char** argv, const char* prefix) {\n>   struct pathspec pathspec;\n>   memset(&pathspec, 0, sizeof(pathspec));\n>   repo_read_index(the_repository);\n>   while (getchar() != EOF) {\n>     refresh_index(&the_index,\n>                   REFRESH_QUIET | REFRESH_UNMERGED | REFRESH_REALLY,\n>                   &pathspec, NULL, NULL);\n>     int uncommitted = has_uncommitted_changes(the_repository, 1);\n>     int unstaged = has_unstaged_changes(the_repository, 1);\n>     int untracked = has_untracked(the_repository);  // I added this to\n> wt-status.h\n>     printf(\"%d %d %d\\n\", uncommitted, unstaged, untracked);\n>   }\n>   return 0;\n> }\n> ```\n>\n> This produces correct results on the first iteration but then it\n> doesn’t pick up all changes. I’ve hacked some code in preload-index.c\n> and cache.c so that it picks up more changes but I still cannot detect\n> when an unstaged file becomes uncommitted or the other way around.\n>\n> Any pointers would be greatly appreciated.\n>\n> Roman.\n>\n> P.S.\n>\n> I have working code that uses libgit2. Updating the index with\n> `git_index_read(index, 0)` works as expected and is indeed faster than\n> discarding the index and starting from scratch. But it's still slower\n> than `git status` on large repositories, especially with many ignored\n> files.\n"}]}