githandler.cpp 4.6 KB

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