diff --git a/src/plugins/diffeditor/diffeditorreloader.h b/src/plugins/diffeditor/diffeditorreloader.h
index e1b6408e56a12c9f3ae69d5f16ceb17a46d7a901..70d1119e0438370d8225cf67c9af5da830b08678 100644
--- a/src/plugins/diffeditor/diffeditorreloader.h
+++ b/src/plugins/diffeditor/diffeditorreloader.h
@@ -46,6 +46,7 @@ public:
     ~DiffEditorReloader();
 
     bool isReloading() const;
+    DiffEditorController *controller() const;
 
 public slots:
     void requestReload();
@@ -55,7 +56,6 @@ protected:
     // inside reload() (for synchronous reload)
     // or later (for asynchronous reload)
     virtual void reload() = 0;
-    DiffEditorController *controller() const;
     void setController(DiffEditorController *controller);
 
 protected slots:
diff --git a/src/plugins/git/gitclient.cpp b/src/plugins/git/gitclient.cpp
index d5bd8df3ce23c0d080b0f49a00aa6cf06cce5d7a..34a04dc4afb69da069ac7148c1e02512c4bd4aa4 100644
--- a/src/plugins/git/gitclient.cpp
+++ b/src/plugins/git/gitclient.cpp
@@ -807,18 +807,36 @@ VcsBaseEditorWidget *GitClient::findExistingVCSEditor(const char *registerDynami
     return rc;
 }
 
-DiffEditor::DiffEditorDocument *GitClient::createDiffEditor(const QString &documentId,
-                                                            const QString &source,
-                                                            const QString &title) const
-{
-    DiffEditor::DiffEditorDocument *diffEditorDocument = DiffEditor::DiffEditorManager::findOrCreate(documentId, title);
-    QTC_ASSERT(diffEditorDocument, return 0);
-    VcsBasePlugin::setSource(diffEditorDocument, source);
+GitDiffEditorReloader *GitClient::findOrCreateDiffEditor(const QString &documentId,
+                                                         const QString &source,
+                                                         const QString &title,
+                                                         const QString &workingDirectory) const
+{
+    DiffEditor::DiffEditorController *controller = 0;
+    GitDiffEditorReloader *reloader = 0;
+    DiffEditor::DiffEditorDocument *diffEditorDocument = DiffEditor::DiffEditorManager::find(documentId);
+    if (diffEditorDocument) {
+        controller = diffEditorDocument->controller();
+        reloader = static_cast<GitDiffEditorReloader *>(controller->reloader());
+    } else {
+        diffEditorDocument = DiffEditor::DiffEditorManager::findOrCreate(documentId, title);
+        QTC_ASSERT(diffEditorDocument, return 0);
+        controller = diffEditorDocument->controller();
+
+        connect(controller, SIGNAL(chunkActionsRequested(QMenu*,int,int)),
+                this, SLOT(slotChunkActionsRequested(QMenu*,int,int)), Qt::DirectConnection);
+        connect(controller, SIGNAL(expandBranchesRequested(QString)),
+                this, SLOT(branchesForCommit(QString)));
+
+        reloader = new GitDiffEditorReloader(controller);
+        controller->setReloader(reloader);
 
-    connect(diffEditorDocument->controller(), SIGNAL(chunkActionsRequested(QMenu*,int,int)),
-            this, SLOT(slotChunkActionsRequested(QMenu*,int,int)), Qt::DirectConnection);
+        reloader->setWorkingDirectory(workingDirectory);
+    }
 
-    return diffEditorDocument;
+    VcsBasePlugin::setSource(diffEditorDocument, source);
+    EditorManager::activateEditorForDocument(diffEditorDocument);
+    return reloader;
 }
 
 void GitClient::slotChunkActionsRequested(QMenu *menu, int diffFileIndex, int chunkIndex)
@@ -966,78 +984,54 @@ VcsBaseEditorWidget *GitClient::createVcsEditor(
     return rc;
 }
 
-void GitClient::diff(const QString &workingDirectory,
-                     const QStringList &unstagedFileNames,
-                     const QStringList &stagedFileNames) const
+void GitClient::diffFiles(const QString &workingDirectory,
+                          const QStringList &unstagedFileNames,
+                          const QStringList &stagedFileNames) const
 {
-    GitDiffEditorReloader::DiffType diffType = GitDiffEditorReloader::DiffProjectList;
-
-    if (unstagedFileNames.empty() && stagedFileNames.empty())
-        diffType = GitDiffEditorReloader::DiffRepository;
-    else if (!stagedFileNames.empty())
-        diffType = GitDiffEditorReloader::DiffFileList;
-
-    QString title = tr("Git Diff Projects");
-    QString documentTypeId = QLatin1String("Projects:");
-    if (diffType ==  GitDiffEditorReloader::DiffRepository) {
-        title = tr("Git Diff Repository");
-        documentTypeId = QLatin1String("Repository:");
-    } else if (diffType == GitDiffEditorReloader::DiffFileList) {
-        title = tr("Git Diff Files");
-        documentTypeId = QLatin1String("Files:");
-    }
-
-    const QString documentId = documentTypeId + workingDirectory;
-
-    DiffEditor::DiffEditorDocument *diffEditorDocument =
-            DiffEditor::DiffEditorManager::find(documentId);
-    if (!diffEditorDocument) {
-        diffEditorDocument = createDiffEditor(documentId, workingDirectory, title);
-
-        DiffEditor::DiffEditorController *controller = diffEditorDocument->controller();
-        GitDiffEditorReloader *reloader = new GitDiffEditorReloader(controller);
-        controller->setReloader(reloader);
-
-        reloader->setWorkingDirectory(workingDirectory);
-    }
-
-    DiffEditor::DiffEditorController *controller = diffEditorDocument->controller();
-    GitDiffEditorReloader *reloader = static_cast<GitDiffEditorReloader *>(controller->reloader());
-    reloader->setDiffType(diffType);
-    // we force setFileList, since the lists can be different
-    // e.g. when double click for the second time on different file inside commit editor
-    if (diffType == GitDiffEditorReloader::DiffFileList)
-        reloader->setFileList(stagedFileNames, unstagedFileNames);
-    else if (diffType == GitDiffEditorReloader::DiffProjectList) // the same when unstaged file was clicked
-        reloader->setProjectList(unstagedFileNames);
+    GitDiffEditorReloader *reloader = findOrCreateDiffEditor(QLatin1String("Files:") + workingDirectory,
+                                                             workingDirectory,
+                                                             tr("Git Diff Files"),
+                                                             workingDirectory);
+    QTC_ASSERT(reloader, return);
+    reloader->setDiffType(GitDiffEditorReloader::DiffFileList);
+    reloader->setFileList(stagedFileNames, unstagedFileNames);
+    reloader->requestReload();
+}
 
-    diffEditorDocument->controller()->requestReload();
+void GitClient::diffProject(const QString &workingDirectory, const QString &projectDirectory) const
+{
+    GitDiffEditorReloader *reloader = findOrCreateDiffEditor(QLatin1String("Project:") + workingDirectory,
+                                                             workingDirectory,
+                                                             tr("Git Diff Project"),
+                                                             workingDirectory);
+    QTC_ASSERT(reloader, return);
+    reloader->setDiffType(GitDiffEditorReloader::DiffProjectList);
+    reloader->setProjectList(QStringList(projectDirectory));
+    reloader->requestReload();
+}
 
-    EditorManager::activateEditorForDocument(diffEditorDocument);
+void GitClient::diffRepository(const QString &workingDirectory) const
+{
+    GitDiffEditorReloader *reloader = findOrCreateDiffEditor(QLatin1String("Repository:") + workingDirectory,
+                                                             workingDirectory,
+                                                             tr("Git Diff Repository"),
+                                                             workingDirectory);
+    QTC_ASSERT(reloader, return);
+    reloader->setDiffType(GitDiffEditorReloader::DiffRepository);
+    reloader->requestReload();
 }
 
-void GitClient::diff(const QString &workingDirectory, const QString &fileName) const
+void GitClient::diffFile(const QString &workingDirectory, const QString &fileName) const
 {
     const QString title = tr("Git Diff \"%1\"").arg(fileName);
     const QString sourceFile = VcsBaseEditor::getSource(workingDirectory, fileName);
     const QString documentId = QLatin1String("File:") + sourceFile;
-    DiffEditor::DiffEditorDocument *diffEditorDocument =
-            DiffEditor::DiffEditorManager::find(documentId);
-    if (!diffEditorDocument) {
-        diffEditorDocument = createDiffEditor(documentId, sourceFile, title);
-
-        DiffEditor::DiffEditorController *controller = diffEditorDocument->controller();
-        GitDiffEditorReloader *reloader = new GitDiffEditorReloader(controller);
-        controller->setReloader(reloader);
-
-        reloader->setWorkingDirectory(workingDirectory);
-        reloader->setDiffType(GitDiffEditorReloader::DiffFile);
-        reloader->setFileName(fileName);
-    }
-
-    diffEditorDocument->controller()->requestReload();
-
-    EditorManager::activateEditorForDocument(diffEditorDocument);
+    GitDiffEditorReloader *reloader = findOrCreateDiffEditor(documentId, sourceFile,
+                                                             title, workingDirectory);
+    QTC_ASSERT(reloader, return);
+    reloader->setDiffType(GitDiffEditorReloader::DiffFile);
+    reloader->setFileName(fileName);
+    reloader->requestReload();
 }
 
 void GitClient::diffBranch(const QString &workingDirectory,
@@ -1045,23 +1039,12 @@ void GitClient::diffBranch(const QString &workingDirectory,
 {
     const QString title = tr("Git Diff Branch \"%1\"").arg(branchName);
     const QString documentId = QLatin1String("Branch:") + branchName;
-    DiffEditor::DiffEditorDocument *diffEditorDocument =
-            DiffEditor::DiffEditorManager::find(documentId);
-    if (!diffEditorDocument) {
-        diffEditorDocument = createDiffEditor(documentId, workingDirectory, title);
-
-        DiffEditor::DiffEditorController *controller = diffEditorDocument->controller();
-        GitDiffEditorReloader *reloader = new GitDiffEditorReloader(controller);
-        controller->setReloader(reloader);
-
-        reloader->setWorkingDirectory(workingDirectory);
-        reloader->setDiffType(GitDiffEditorReloader::DiffBranch);
-        reloader->setBranchName(branchName);
-    }
-
-    diffEditorDocument->controller()->requestReload();
-
-    EditorManager::activateEditorForDocument(diffEditorDocument);
+    GitDiffEditorReloader *reloader = findOrCreateDiffEditor(documentId, workingDirectory,
+                                                             title, workingDirectory);
+    QTC_ASSERT(reloader, return);
+    reloader->setDiffType(GitDiffEditorReloader::DiffBranch);
+    reloader->setBranchName(branchName);
+    reloader->requestReload();
 }
 
 void GitClient::merge(const QString &workingDirectory,
@@ -1171,29 +1154,13 @@ void GitClient::show(const QString &source, const QString &id, const QString &na
     if (!repoDirectory.isEmpty())
         workingDirectory = repoDirectory;
     const QString documentId = QLatin1String("Show:") + id;
-    DiffEditor::DiffEditorDocument *diffEditorDocument =
-            DiffEditor::DiffEditorManager::find(documentId);
-    if (!diffEditorDocument) {
-        diffEditorDocument = createDiffEditor(documentId, source, title);
-
-        connect(diffEditorDocument->controller(), SIGNAL(expandBranchesRequested(QString)),
-                this, SLOT(branchesForCommit(QString)));
-
-        diffEditorDocument->controller()->setDescriptionEnabled(true);
-
-        DiffEditor::DiffEditorController *controller = diffEditorDocument->controller();
-        GitDiffEditorReloader *reloader = new GitDiffEditorReloader(controller);
-        controller->setReloader(reloader);
-
-        reloader->setWorkingDirectory(workingDirectory);
-        reloader->setDiffType(GitDiffEditorReloader::DiffShow);
-        reloader->setFileName(source);
-        reloader->setId(id);
-    }
-
-    diffEditorDocument->controller()->requestReload();
-
-    EditorManager::activateEditorForDocument(diffEditorDocument);
+    GitDiffEditorReloader *reloader = findOrCreateDiffEditor(documentId, source, title, workingDirectory);
+    QTC_ASSERT(reloader, return);
+    reloader->setDiffType(GitDiffEditorReloader::DiffShow);
+    reloader->setFileName(source);
+    reloader->setId(id);
+    reloader->controller()->setDescriptionEnabled(true);
+    reloader->requestReload();
 }
 
 void GitClient::saveSettings()
diff --git a/src/plugins/git/gitclient.h b/src/plugins/git/gitclient.h
index 9dda535bbfcc1a03090ddefc32096cc67824f9b5..9e14e820f19e2548718e8e80980f621ee67b2519 100644
--- a/src/plugins/git/gitclient.h
+++ b/src/plugins/git/gitclient.h
@@ -71,6 +71,7 @@ namespace Git {
 namespace Internal {
 
 class CommitData;
+class GitDiffEditorReloader;
 struct GitSubmitEditorPanelData;
 class Stash;
 
@@ -143,10 +144,13 @@ public:
     QString findGitDirForRepository(const QString &repositoryDir) const;
     bool managesFile(const QString &workingDirectory, const QString &fileName) const;
 
-    void diff(const QString &workingDirectory, const QString &fileName) const;
-    void diff(const QString &workingDirectory,
-              const QStringList &unstagedFileNames,
-              const QStringList &stagedFileNames = QStringList()) const;
+    void diffFile(const QString &workingDirectory, const QString &fileName) const;
+    void diffFiles(const QString &workingDirectory,
+                   const QStringList &unstagedFileNames,
+                   const QStringList &stagedFileNames) const;
+    void diffProject(const QString &workingDirectory,
+                     const QString &projectDirectory) const;
+    void diffRepository(const QString &workingDirectory) const;
     void diffBranch(const QString &workingDirectory,
                     const QString &branchName) const;
     void merge(const QString &workingDirectory, const QStringList &unmergedFileNames = QStringList());
@@ -363,6 +367,7 @@ private:
                                                         const QString &dynamicPropertyValue) const;
 
     enum CodecType { CodecSource, CodecLogOutput, CodecNone };
+
     VcsBase::VcsBaseEditorWidget *createVcsEditor(Core::Id kind,
                                             QString title,
                                             const QString &source,
@@ -370,9 +375,11 @@ private:
                                             const char *registerDynamicProperty,
                                             const QString &dynamicPropertyValue,
                                             VcsBase::VcsBaseEditorParameterWidget *configWidget) const;
-    DiffEditor::DiffEditorDocument *createDiffEditor(const QString &documentId,
-                                             const QString &source,
-                                             const QString &title) const;
+
+    GitDiffEditorReloader *findOrCreateDiffEditor(const QString &documentId,
+                                                  const QString &source,
+                                                  const QString &title,
+                                                  const QString &workingDirectory) const;
 
     VcsBase::VcsCommand *createCommand(const QString &workingDirectory,
                              VcsBase::VcsBaseEditorWidget* editor = 0,
diff --git a/src/plugins/git/gitplugin.cpp b/src/plugins/git/gitplugin.cpp
index 0bd09f0e9fc803e4c36dc033ed20b754233ee63f..c449e955c5e52511b644e0d77ad81d79a01eb80e 100644
--- a/src/plugins/git/gitplugin.cpp
+++ b/src/plugins/git/gitplugin.cpp
@@ -677,7 +677,7 @@ GitVersionControl *GitPlugin::gitVersionControl() const
 
 void GitPlugin::submitEditorDiff(const QStringList &unstaged, const QStringList &staged)
 {
-    m_gitClient->diff(m_submitRepository, unstaged, staged);
+    m_gitClient->diffFiles(m_submitRepository, unstaged, staged);
 }
 
 void GitPlugin::submitEditorMerge(const QStringList &unmerged)
@@ -689,7 +689,7 @@ void GitPlugin::diffCurrentFile()
 {
     const VcsBasePluginState state = currentState();
     QTC_ASSERT(state.hasFile(), return);
-    m_gitClient->diff(state.currentFileTopLevel(), state.relativeCurrentFile());
+    m_gitClient->diffFile(state.currentFileTopLevel(), state.relativeCurrentFile());
 }
 
 void GitPlugin::diffCurrentProject()
@@ -697,15 +697,17 @@ void GitPlugin::diffCurrentProject()
     const VcsBasePluginState state = currentState();
     QTC_ASSERT(state.hasProject(), return);
     const QString relativeProject = state.relativeCurrentProject();
-    m_gitClient->diff(state.currentProjectTopLevel(),
-                      relativeProject.isEmpty() ? QStringList() : QStringList(relativeProject));
+    if (relativeProject.isEmpty())
+        m_gitClient->diffRepository(state.currentProjectTopLevel());
+    else
+        m_gitClient->diffProject(state.currentProjectTopLevel(), relativeProject);
 }
 
 void GitPlugin::diffRepository()
 {
     const VcsBasePluginState state = currentState();
     QTC_ASSERT(state.hasTopLevel(), return);
-    m_gitClient->diff(state.topLevel(), QStringList());
+    m_gitClient->diffRepository(state.topLevel());
 }
 
 void GitPlugin::logFile()