Skip to content
Snippets Groups Projects
gitclient.cpp 151 KiB
Newer Older
hjk's avatar
hjk committed
/****************************************************************************
con's avatar
con committed
**
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
hjk's avatar
hjk committed
** Contact: http://www.qt-project.org/legal
con's avatar
con committed
**
hjk's avatar
hjk committed
** This file is part of Qt Creator.
con's avatar
con committed
**
hjk's avatar
hjk committed
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia.  For licensing terms and
** conditions see http://qt.digia.com/licensing.  For further information
** use the contact form at http://qt.digia.com/contact-us.
** GNU Lesser General Public License Usage
hjk's avatar
hjk committed
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Digia gives you certain additional
** rights.  These rights are described in the Digia Qt LGPL Exception
con's avatar
con committed
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
hjk's avatar
hjk committed
****************************************************************************/
hjk's avatar
hjk committed

con's avatar
con committed
#include "gitclient.h"
#include "gitutils.h"
con's avatar
con committed
#include "commitdata.h"
hjk's avatar
hjk committed
#include "gitconstants.h"
#include "gitplugin.h"
#include "gitversioncontrol.h"
#include "mergetool.h"
con's avatar
con committed

#include <vcsbase/submitfilemodel.h>

con's avatar
con committed
#include <coreplugin/editormanager/editormanager.h>
hjk's avatar
hjk committed
#include <coreplugin/icore.h>
#include <coreplugin/vcsmanager.h>
#include <coreplugin/iversioncontrol.h>
#include <coreplugin/coreconstants.h>
#include <utils/hostosinfo.h>
hjk's avatar
hjk committed
#include <utils/qtcassert.h>
#include <utils/qtcprocess.h>
#include <utils/synchronousprocess.h>
#include <utils/fileutils.h>
Tobias Hunger's avatar
Tobias Hunger committed
#include <vcsbase/command.h>
hjk's avatar
hjk committed
#include <vcsbase/vcsbaseeditor.h>
#include <vcsbase/vcsbaseeditorparameterwidget.h>
#include <vcsbase/vcsbaseoutputwindow.h>
#include <vcsbase/vcsbaseplugin.h>
con's avatar
con committed

#include <diffeditor/diffeditor.h>
#include <diffeditor/diffshoweditor.h>
#include <diffeditor/diffeditorconstants.h>

#include <QCoreApplication>
#include <QFileInfo>
#include <QHash>
#include <QRegExp>
#include <QSignalMapper>
#include <QTime>
con's avatar
con committed

#include <QMessageBox>
#include <QPushButton>
#include <QToolButton>
#include <QTextCodec>
con's avatar
con committed

static const char GIT_DIRECTORY[] = ".git";
static const char graphLogFormatC[] = "%h %d %an %s %ci";
static const char HEAD[] = "HEAD";
static const char noColorOption[] = "--no-color";
static const char decorateOption[] = "--decorate";
con's avatar
con committed

namespace Git {
namespace Internal {

using VcsBase::VcsBasePlugin;

class GitDiffSwitcher : public QObject
{
    Q_OBJECT

public:
    enum DiffType {
        DiffRepository,
        DiffFile,
        DiffFileList,
        DiffProjectList,
        DiffBranch,
        DiffShow
    };

    GitDiffSwitcher(Core::IEditor *parentEditor, GitClient *gitClient, GitClient::DiffEditorType switchToType)
        : QObject(parentEditor),
          m_editor(parentEditor),
          m_gitClient(gitClient),
          m_editorType(switchToType)
    {
        QIcon actionIcon = switchToType == GitClient::SideBySideDiffEditor
                ? QIcon(QLatin1String(Core::Constants::ICON_SIDE_BY_SIDE_DIFF))
                : QIcon(QLatin1String(Core::Constants::ICON_TEXT_DIFF));

        const QString actionToolTip = switchToType == GitClient::SideBySideDiffEditor
                ? tr("Switch to Side By Side Diff Editor")
                : tr("Switch to Text Diff Editor");

        QAction *switchAction = new QAction(actionIcon, actionToolTip, parentEditor);
        parentEditor->toolBar()->addAction(switchAction);
        connect(switchAction, SIGNAL(triggered()), this, SLOT(execute()));
    }

    void setWorkingDirectory(const QString &workingDir) { m_workingDirectory = workingDir; }
    void setDiffType(DiffType type) { m_diffType = type; }
    void setFileName(const QString &fileName) { m_fileName = fileName; }
    void setFileList(const QStringList &stagedFiles, const QStringList &unstagedFiles)
    {
        m_stagedFiles = stagedFiles;
        m_unstagedFiles = unstagedFiles;
    }
    void setProjectList(const QStringList &projectFiles) { m_projectFiles = projectFiles; }
    void setBranchName(const QString &branchName) { m_branchName = branchName; }
    void setId(const QString &id) { m_id = id; }
    void setDisplayName(const QString &displayName) { m_displayName = displayName; }
    void setBaseArguments(const QStringList &args) { m_baseArguments = args; }

public slots:
    void execute();

private:
    Core::IEditor *m_editor;
    GitClient *m_gitClient;
    QString m_workingDirectory;
    DiffType m_diffType;
    GitClient::DiffEditorType m_editorType;
    QString m_fileName;
    QStringList m_stagedFiles;
    QStringList m_unstagedFiles;
    QStringList m_projectFiles;
    QString m_branchName;
    QString m_id;
    QString m_displayName;
    QStringList m_baseArguments;
};

void GitDiffSwitcher::execute()
{
    switch (m_diffType) {
    case DiffRepository:
        m_gitClient->diff(m_workingDirectory, QStringList(), QStringList(), m_editorType);
        break;
    case DiffFile:
        m_gitClient->diff(m_workingDirectory, m_fileName, m_editorType);
        break;
    case DiffFileList:
        m_gitClient->diff(m_workingDirectory, m_unstagedFiles, m_stagedFiles, m_editorType);
        break;
    case DiffProjectList:
        m_gitClient->diff(m_workingDirectory, m_projectFiles, QStringList(), m_editorType);
        break;
    case DiffBranch:
        m_gitClient->diffBranch(m_workingDirectory, m_baseArguments, m_branchName, m_editorType);
        break;
    case DiffShow:
        m_gitClient->show(m_fileName, m_id, m_baseArguments, m_displayName, m_editorType);
        break;
    default:
        break;
    }
    Core::EditorManager::closeEditor(m_editor, false);
class GitDiffHandler : public QObject
{
    Q_OBJECT

public:
    enum RevisionType {
        WorkingTree,
        Index,
        Other
    };

    struct Revision {
        Revision() : type(WorkingTree) { }
        Revision(RevisionType t) : type(t) { }
        Revision(RevisionType t, const QString &i) : type(t), id(i) { }
        RevisionType type;
        QString id; // can be sha or HEAD
        QString infoText() const
        {
            switch (type) {
Loading
Loading full blame...