githandler.cpp 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. #include "githandler.h"
  2. #include <QDebug>
  3. #include <QUrl>
  4. #include <QFileSystemWatcher>
  5. #include <QGuiApplication>
  6. #include <QClipboard>
  7. #include <qqml.h>
  8. #include <gitrepository.h>
  9. #include <gitbranch.h>
  10. #include <gitdiff.h>
  11. #include <commitmodel.h>
  12. #include <tagmodel.h>
  13. #include <git2.h>
  14. #include <colorhandler.h>
  15. #include <commitgraph.h>
  16. #include <graphpoint.h>
  17. #include <branchlistmodel.h>
  18. #include <taglistmodel.h>
  19. #include <gitconsole.h>
  20. GitHandler::GitHandler() : QObject()
  21. ,m_repositories(new RepositoryModel(this))
  22. ,m_commits(nullptr)
  23. ,m_graph(nullptr)
  24. ,m_activeRepo(nullptr)
  25. ,m_activeDiff(nullptr)
  26. ,m_branchList(new BranchListModel(this))
  27. ,m_tagList(new TagListModel(this))
  28. ,m_activeRepoWatcher(new QFileSystemWatcher(this))
  29. ,m_console(new GitConsole(this))
  30. {
  31. git_libgit2_init();
  32. }
  33. GitHandler::~GitHandler()
  34. {
  35. git_libgit2_shutdown();
  36. }
  37. void GitHandler::open(const QUrl &url)
  38. {
  39. if(url.isLocalFile()) {
  40. open(url.toLocalFile());
  41. }
  42. }
  43. void GitHandler::open(const QString &path)
  44. {
  45. qDebug() << "path" << path;
  46. git_buf root = {0,0,0};
  47. if(git_repository_discover(&root, path.toUtf8().data(), 0, NULL) != 0) {
  48. qDebug() << lastError();
  49. return;
  50. }
  51. if(m_activeRepo) {
  52. m_activeRepoWatcher->removePath(m_activeRepo->root());
  53. }
  54. m_activeRepo = new GitRepository(QString::fromUtf8(root.ptr, root.size));
  55. if(!m_activeRepo->isValid()) {
  56. qDebug() << lastError();
  57. return;
  58. }
  59. ColorHandler::instance().updateColors(m_activeRepo);
  60. m_constantHead = m_activeRepo->head();
  61. m_console->setRepository(m_activeRepo);
  62. connect(m_activeRepo, &GitRepository::branchesChanged, this, &GitHandler::updateModels);
  63. updateModels();
  64. m_activeRepoWatcher->addPath(m_activeRepo->root());
  65. connect(m_activeRepoWatcher, &QFileSystemWatcher::directoryChanged, m_activeRepo, &GitRepository::readBranches);
  66. connect(m_activeRepoWatcher, &QFileSystemWatcher::directoryChanged, m_activeRepo, &GitRepository::readRemotes);
  67. connect(m_activeRepoWatcher, &QFileSystemWatcher::directoryChanged, m_activeRepo, &GitRepository::readTags);
  68. connect(m_activeRepoWatcher, &QFileSystemWatcher::directoryChanged, this, &GitHandler::updateModels);
  69. //TODO: opened repositories configuraion TBD
  70. // m_repositories->add(m_activeRepo);
  71. }
  72. QString GitHandler::lastError() const
  73. {
  74. const git_error *e = giterr_last();
  75. if(e) {
  76. return QString("(%1): %2").arg(e->klass).arg(e->message);
  77. giterr_clear();
  78. }
  79. giterr_clear();
  80. return QString();
  81. }
  82. GitDiff* GitHandler::diff(GitCommit* a, GitCommit* b)
  83. {
  84. if(!m_activeDiff.isNull()) {
  85. m_activeDiff->deleteLater();
  86. }
  87. Q_ASSERT_X(a->repository() == b->repository(), "GitHandler", "Cross repository diff requested");
  88. m_activeDiff = new GitDiff(a->raw(), b->raw(), a->repository());
  89. return m_activeDiff.data();
  90. }
  91. void GitHandler::setActiveDiff(GitDiff* activeDiff)
  92. {
  93. if (m_activeDiff == activeDiff)
  94. return;
  95. m_activeDiff = activeDiff;
  96. emit activeDiffChanged(activeDiff);
  97. }
  98. GitDiff* GitHandler::activeDiff() const
  99. {
  100. return m_activeDiff.data();
  101. }
  102. void GitHandler::pull() const
  103. {
  104. // git_remote_fetch(m_activeRepo->remote)
  105. }
  106. void GitHandler::updateModels()
  107. {
  108. if(!m_activeRepo) {
  109. return;
  110. }
  111. m_activeRepo->updateHead();
  112. BranchContainer &branches = m_activeRepo->branches();
  113. CommitGraph* graph = new CommitGraph();
  114. bool headIsBranch = false;
  115. //TODO: Need to think about constant head more deeply
  116. // foreach(GitBranch* branch, branches) {
  117. // if(branch->oid() == m_constantHead) {
  118. // graph->addHead(branch);
  119. // headIsBranch = true;
  120. // break;
  121. // }
  122. // }
  123. if(!headIsBranch) {
  124. graph->addHead(m_activeRepo->head());
  125. }
  126. foreach(GitBranch* branch, branches) {
  127. qDebug() << "Next head " << branch->fullName();
  128. graph->addHead(branch);
  129. }
  130. m_graph->deleteLater();
  131. m_graph = graph;
  132. emit graphChanged(graph);
  133. m_commits = CommitModel::fromGraph(m_graph);
  134. emit commitsChanged(m_commits);
  135. m_branchList->reset(m_activeRepo->branches().values());
  136. m_tagList->reset(m_activeRepo->tags().values());
  137. }
  138. void GitHandler::copySha1(const QString& sha1)
  139. {
  140. QGuiApplication::clipboard()->setText(sha1);
  141. }