File indexing completed on 2025-01-19 04:22:45

0001 // Copyright (C) 2020 Hamed Masafi <hamed.masafi@gmail.com>
0002 // SPDX-License-Identifier: GPL-3.0-or-later
0003 
0004 #pragma once
0005 
0006 #include "blamedata.h"
0007 #include "commands/abstractcommand.h"
0008 #include "filestatus.h"
0009 #include "gitfile.h"
0010 #include "gitglobal.h"
0011 #include "gitremote.h"
0012 #include "libkommit_export.h"
0013 #include "stash.h"
0014 
0015 #include <QObject>
0016 #include <QString>
0017 
0018 namespace Git
0019 {
0020 
0021 class RemotesModel;
0022 class SubmodulesModel;
0023 class BranchesModel;
0024 class LogsModel;
0025 class StashesModel;
0026 class TagsModel;
0027 class AuthorsModel;
0028 
0029 enum LoadFlag {
0030     LoadNone = 0,
0031     LoadStashes = 1,
0032     LoadRemotes = 2,
0033     LoadSubmodules = 4,
0034     LoadBranches = 8,
0035     LoadLogs = 16,
0036     LoadTags = 32,
0037     LoadAll = LoadStashes | LoadRemotes | LoadSubmodules | LoadBranches | LoadLogs | LoadTags
0038 };
0039 Q_DECLARE_FLAGS(LoadFlags, LoadFlag)
0040 Q_DECLARE_OPERATORS_FOR_FLAGS(LoadFlags)
0041 
0042 class LIBKOMMIT_EXPORT Manager : public QObject
0043 {
0044     Q_OBJECT
0045 
0046     Q_PROPERTY(QString path READ path WRITE setPath NOTIFY pathChanged)
0047     Q_PROPERTY(bool isMerging READ isMerging WRITE setIsMerging NOTIFY isMergingChanged)
0048     Q_PROPERTY(bool isRebasing READ isRebasing WRITE setIsRebasing NOTIFY isRebasingChanged)
0049 
0050 public:
0051     enum ConfigType { ConfigGlobal, ConfigLocal };
0052 
0053     Manager();
0054     explicit Manager(const QString &path);
0055     static Manager *instance();
0056 
0057     // run
0058     QString run(const AbstractCommand &cmd) const;
0059     QByteArray runGit(const QStringList &args) const;
0060 
0061     // common actions
0062     void init(const QString &path);
0063     void commit(const QString &message) const;
0064     void push() const;
0065 
0066     // properties
0067     Q_REQUIRED_RESULT const QString &path() const;
0068     void setPath(const QString &newPath);
0069     Q_REQUIRED_RESULT bool isValid() const;
0070     Q_REQUIRED_RESULT bool isMerging() const;
0071     void setIsMerging(bool newIsMerging);
0072 
0073     Q_REQUIRED_RESULT const LoadFlags &loadFlags() const;
0074     void setLoadFlags(Git::LoadFlags newLoadFlags);
0075 
0076     // branches
0077     Q_REQUIRED_RESULT QString currentBranch() const;
0078     Q_REQUIRED_RESULT QString currentRemote() const;
0079     Q_REQUIRED_RESULT QPair<int, int> uniqueCommitsOnBranches(const QString &branch1, const QString &branch2) const;
0080     Q_REQUIRED_RESULT QStringList branches() const;
0081     Q_REQUIRED_RESULT QStringList remoteBranches() const;
0082 
0083     // tags
0084     Q_REQUIRED_RESULT QStringList tags() const;
0085     void createTag(const QString &name, const QString &message) const;
0086 
0087     // stashes
0088     QList<Stash> stashes();
0089     void createStash(const QString &name = QString()) const;
0090     Q_REQUIRED_RESULT bool removeStash(const QString &name) const;
0091     Q_REQUIRED_RESULT bool applyStash(const QString &name) const;
0092 
0093     // remotes
0094     Q_REQUIRED_RESULT QStringList remotes() const;
0095     Remote remoteDetails(const QString &remoteName);
0096     Q_REQUIRED_RESULT bool removeBranch(const QString &branchName) const;
0097     Q_REQUIRED_RESULT bool addRemote(const QString &name, const QString &url) const;
0098     Q_REQUIRED_RESULT bool removeRemote(const QString &name) const;
0099     Q_REQUIRED_RESULT bool renameRemote(const QString &name, const QString &newName) const;
0100 
0101     // config
0102     Q_REQUIRED_RESULT QString config(const QString &name, ConfigType type = ConfigLocal) const;
0103     Q_REQUIRED_RESULT bool configBool(const QString &name, ConfigType type = ConfigLocal) const;
0104     void setConfig(const QString &name, const QString &value, ConfigType type = ConfigLocal) const;
0105     void unsetConfig(const QString &name, ConfigType type = ConfigLocal) const;
0106 
0107     // files
0108     void addFile(const QString &file) const;
0109     Q_REQUIRED_RESULT QStringList ls(const QString &place) const;
0110     Q_REQUIRED_RESULT QString fileContent(const QString &place, const QString &fileName) const;
0111     void saveFile(const QString &place, const QString &fileName, const QString &localFile) const;
0112     void revertFile(const QString &filePath) const;
0113     void removeFile(const QString &file, bool cached) const;
0114     Q_REQUIRED_RESULT QStringList fileLog(const QString &fileName) const;
0115     BlameData blame(const File &file);
0116     Q_REQUIRED_RESULT QMap<QString, ChangeStatus> changedFiles() const;
0117     Q_REQUIRED_RESULT QMap<QString, ChangeStatus> changedFiles(const QString &hash) const;
0118     Q_REQUIRED_RESULT QStringList ignoredFiles() const;
0119     Q_REQUIRED_RESULT QList<FileStatus> repoFilesStatus() const;
0120 
0121     // notes
0122     Q_REQUIRED_RESULT QString readNote(const QString &branchName) const;
0123     void saveNote(const QString &branchName, const QString &note) const;
0124 
0125     // ignores
0126     bool isIgnored(const QString &path);
0127 
0128     // diffs
0129     Q_REQUIRED_RESULT QString diff(const QString &from, const QString &to) const;
0130     Q_REQUIRED_RESULT QList<FileStatus> diffBranch(const QString &from) const;
0131     Q_REQUIRED_RESULT QList<FileStatus> diffBranches(const QString &from, const QString &to) const;
0132 
0133     // models
0134     Q_REQUIRED_RESULT RemotesModel *remotesModel() const;
0135     Q_REQUIRED_RESULT SubmodulesModel *submodulesModel() const;
0136     Q_REQUIRED_RESULT BranchesModel *branchesModel() const;
0137     Q_REQUIRED_RESULT AuthorsModel *authorsModel() const;
0138     Q_REQUIRED_RESULT LogsModel *logsModel() const;
0139     Q_REQUIRED_RESULT StashesModel *stashesModel() const;
0140     Q_REQUIRED_RESULT TagsModel *tagsModel() const;
0141 
0142     bool isRebasing() const;
0143     void setIsRebasing(bool newIsRebasing);
0144 
0145 Q_SIGNALS:
0146     void pathChanged();
0147     void isMergingChanged();
0148 
0149     void isRebasingChanged();
0150 
0151     void modelsReady();
0152 
0153 private:
0154     QString mPath;
0155     bool mIsValid{false};
0156     QMap<QString, Remote> mRemotes;
0157     LoadFlags mLoadFlags{LoadAll};
0158     bool m_isMerging{false};
0159 
0160     QStringList readAllNonEmptyOutput(const QStringList &cmd) const;
0161     QString escapeFileName(const QString &filePath) const;
0162     void loadAsync();
0163 
0164     RemotesModel *const mRemotesModel;
0165     AuthorsModel *const mAuthorsModel;
0166     SubmodulesModel *const mSubmodulesModel;
0167     BranchesModel *const mBranchesModel;
0168     LogsModel *const mLogsCache;
0169     StashesModel *const mStashesCache;
0170     TagsModel *const mTagsModel;
0171 
0172     friend class Stash;
0173     friend class RemotesModel;
0174     friend class SubmodulesModel;
0175     friend class BranchesModel;
0176     friend class LogsModel;
0177     friend class StashesModel;
0178     friend class TagsModel;
0179     bool m_isRebasing;
0180 };
0181 
0182 } // namespace Git