diff --git a/src/plugins/git/gitclient.cpp b/src/plugins/git/gitclient.cpp
index f3d507171d2d492986586676ad02bb7af5c1764a..281a9572a215079dae27ad6176349236f7039f73 100644
--- a/src/plugins/git/gitclient.cpp
+++ b/src/plugins/git/gitclient.cpp
@@ -65,8 +65,6 @@ const char *const kGitCommand = "git";
 const char *const kGitDirectoryC = ".git";
 const char *const kBranchIndicatorC = "# On branch";
 
-enum { untrackedFilesInCommit = 0 };
-
 static inline QString msgServerFailure()
 {
     return GitClient::tr(
@@ -631,7 +629,7 @@ GitClient::StatusResult GitClient::gitStatus(const QString &workingDirectory,
     # Changed but not updated:
     #<tab>modified:<blanks>git.pro
     # Untracked files:
-    #<tab>modified:<blanks>git.pro
+    #<tab>git.pro
     \endcode
 */
 static bool parseFiles(const QString &output, CommitData *d)
@@ -677,7 +675,7 @@ static bool parseFiles(const QString &output, CommitData *d)
                                 d->unstagedFiles.push_back(trimFileSpecification(fileSpec));
                                 break;
                             case UntrackedFiles:
-                                d->untrackedFiles.push_back(QLatin1String("untracked: ") + fileSpec);
+                                d->untrackedFiles.push_back(fileSpec);
                                 break;
                             case None:
                                 break;
@@ -691,6 +689,25 @@ static bool parseFiles(const QString &output, CommitData *d)
     return !d->stagedFiles.empty() || !d->unstagedFiles.empty() || !d->untrackedFiles.empty();
 }
 
+// Filter out untracked files that are not part of the project
+static void filterUntrackedFilesOfProject(const QString &repoDir, QStringList *l)
+{
+    if (l->empty())
+        return;
+    const QStringList nativeProjectFiles = VCSBase::VCSBaseSubmitEditor::currentProjectFiles(true);
+    if (nativeProjectFiles.empty())
+        return;
+    const QDir repoDirectory(repoDir);
+    for (QStringList::iterator it = l->begin(); it != l->end(); ) {
+        const QString path = QDir::toNativeSeparators(repoDirectory.absoluteFilePath(*it));
+        if (nativeProjectFiles.contains(path)) {
+            ++it;
+        } else {
+            it = l->erase(it);
+        }
+    }
+}
+
 bool GitClient::getCommitData(const QString &workingDirectory,
                               QString *commitTemplate,
                               CommitData *d,
@@ -726,7 +743,7 @@ bool GitClient::getCommitData(const QString &workingDirectory,
 
     // Run status. Note that it has exitcode 1 if there are no added files.
     QString output;
-    switch (gitStatus(repoDirectory, untrackedFilesInCommit, &output, errorMessage)) {
+    switch (gitStatus(repoDirectory, true, &output, errorMessage)) {
     case  StatusChanged:
         break;
     case StatusUnchanged:
@@ -758,6 +775,16 @@ bool GitClient::getCommitData(const QString &workingDirectory,
         *errorMessage = msgParseFilesFailed();
         return false;
     }
+    // Filter out untracked files that are not part of the project and,
+    // for symmetry, insert the prefix "untracked:" (as "added:" or ":modified"
+    // for staged files).
+    filterUntrackedFilesOfProject(repoDirectory, &d->untrackedFiles);
+    if (!d->untrackedFiles.empty()) {
+        const QString untrackedPrefix = QLatin1String("untracked: ");
+        const QStringList::iterator pend = d->untrackedFiles.end();
+        for (QStringList::iterator it = d->untrackedFiles.begin(); it != pend; ++it)
+            it->insert(0, untrackedPrefix);
+    }
 
     d->panelData.author = readConfigValue(workingDirectory, QLatin1String("user.name"));
     d->panelData.email = readConfigValue(workingDirectory, QLatin1String("user.email"));
@@ -853,8 +880,8 @@ GitClient::RevertResult GitClient::revertI(QStringList files, bool *ptrToIsDirec
     case StatusFailed:
         return RevertFailed;
     }
-    CommitData d;
-    if (!parseFiles(output, &d)) {
+    CommitData data;
+    if (!parseFiles(output, &data)) {
         *errorMessage = msgParseFilesFailed();
         return RevertFailed;
     }
@@ -870,8 +897,8 @@ GitClient::RevertResult GitClient::revertI(QStringList files, bool *ptrToIsDirec
 
     // From the status output, determine all modified [un]staged files.
     const QString modifiedPattern = QLatin1String("modified: ");
-    const QStringList allStagedFiles = GitSubmitEditor::statusListToFileList(d.stagedFiles.filter(modifiedPattern));
-    const QStringList allUnstagedFiles = GitSubmitEditor::statusListToFileList(d.unstagedFiles.filter(modifiedPattern));
+    const QStringList allStagedFiles = GitSubmitEditor::statusListToFileList(data.stagedFiles.filter(modifiedPattern));
+    const QStringList allUnstagedFiles = GitSubmitEditor::statusListToFileList(data.unstagedFiles.filter(modifiedPattern));
     // Unless a directory was passed, filter all modified files for the
     // argument file list.
     QStringList stagedFiles = allStagedFiles;
@@ -882,7 +909,7 @@ GitClient::RevertResult GitClient::revertI(QStringList files, bool *ptrToIsDirec
         unstagedFiles = allUnstagedFiles.toSet().intersect(filesSet).toList();
     }
     if (Git::Constants::debug)
-        qDebug() << Q_FUNC_INFO << d.stagedFiles << d.unstagedFiles << allStagedFiles << allUnstagedFiles << stagedFiles << unstagedFiles;
+        qDebug() << Q_FUNC_INFO << data.stagedFiles << data.unstagedFiles << allStagedFiles << allUnstagedFiles << stagedFiles << unstagedFiles;
 
     if (stagedFiles.empty() && unstagedFiles.empty())
         return RevertUnchanged;
diff --git a/src/plugins/perforce/perforceplugin.cpp b/src/plugins/perforce/perforceplugin.cpp
index 88783eb40ca1ecdfe83f7e3f9723755fcf3e1abc..0ad0224d1ca191b911ab9d2ed5fedd3a55ad8874 100644
--- a/src/plugins/perforce/perforceplugin.cpp
+++ b/src/plugins/perforce/perforceplugin.cpp
@@ -463,22 +463,8 @@ void PerforcePlugin::diffCurrentFile()
 
 void PerforcePlugin::diffCurrentProject()
 {
-    QTC_ASSERT(m_projectExplorer, return);
-    QStringList files;
     QString name;
-    ProjectExplorer::Project *currentProject = m_projectExplorer->currentProject();
-    if (currentProject) {
-        files << currentProject->files(ProjectExplorer::Project::ExcludeGeneratedFiles);
-        name = currentProject->name();
-    } else if (m_projectExplorer->session()) {
-        name = m_projectExplorer->session()->file()->fileName();
-        QList<ProjectExplorer::Project *> projects = m_projectExplorer->session()->projects();
-        foreach (ProjectExplorer::Project *project, projects)
-            files << project->files(ProjectExplorer::Project::ExcludeGeneratedFiles);
-    }
-    QStringList nativeFiles;
-    foreach (const QString &f, files)
-        nativeFiles << QDir::toNativeSeparators(f);
+    const QStringList nativeFiles = VCSBase::VCSBaseSubmitEditor::currentProjectFiles(true, &name);
     p4Diff(nativeFiles, name);
 }
 
@@ -538,23 +524,8 @@ void PerforcePlugin::submit()
     m_changeTmpFile->seek(0);
 
     // Assemble file list of project
-    QTC_ASSERT(m_projectExplorer, return);
-    QStringList files;
     QString name;
-    ProjectExplorer::Project *currentProject = m_projectExplorer->currentProject();
-    if (currentProject) {
-        files << currentProject->files(ProjectExplorer::Project::ExcludeGeneratedFiles);
-        name = currentProject->name();
-    } else if (m_projectExplorer->session()) {
-        name = m_projectExplorer->session()->file()->fileName();
-        QList<ProjectExplorer::Project *> projects = m_projectExplorer->session()->projects();
-        foreach (ProjectExplorer::Project *project, projects)
-            files << project->files(ProjectExplorer::Project::ExcludeGeneratedFiles);
-    }
-    QStringList nativeFiles;
-    foreach (const QString &f, files)
-        nativeFiles << QDir::toNativeSeparators(f);
-
+    const QStringList nativeFiles = VCSBase::VCSBaseSubmitEditor::currentProjectFiles(true, &name);
     PerforceResponse result2 = runP4Cmd(QStringList(QLatin1String("fstat")), nativeFiles,
                                         CommandToWindow|StdErrToWindow|ErrorToWindow);
     if (result2.error) {
diff --git a/src/plugins/vcsbase/vcsbasesubmiteditor.cpp b/src/plugins/vcsbase/vcsbasesubmiteditor.cpp
index 152a51c386459f47e3fd957b7bc0f09b5bf37459..9d668f16a767735ca789f369e0315ff050cd432f 100644
--- a/src/plugins/vcsbase/vcsbasesubmiteditor.cpp
+++ b/src/plugins/vcsbase/vcsbasesubmiteditor.cpp
@@ -42,11 +42,15 @@
 #include <utils/submiteditorwidget.h>
 #include <find/basetextfind.h>
 
+#include <projectexplorer/projectexplorer.h>
+#include <projectexplorer/session.h>
+
 #include <QtGui/QToolBar>
 #include <QtGui/QStyle>
 #include <QtCore/QPointer>
 #include <QtCore/QFileInfo>
 #include <QtCore/QFile>
+#include <QtCore/QDir>
 #include <QtCore/QTextStream>
 #include <QtCore/QDebug>
 
@@ -299,4 +303,32 @@ QIcon VCSBaseSubmitEditor::submitIcon()
     return QIcon(QLatin1String(":/vcsbase/images/submit.png"));
 }
 
+QStringList VCSBaseSubmitEditor::currentProjectFiles(bool nativeSeparators, QString *name)
+{
+    if (name)
+        name->clear();
+    ProjectExplorer::ProjectExplorerPlugin *projectExplorer = ExtensionSystem::PluginManager::instance()->getObject<ProjectExplorer::ProjectExplorerPlugin>();
+    if (!projectExplorer)
+        return QStringList();
+    QStringList files;
+    if (const ProjectExplorer::Project *currentProject = projectExplorer->currentProject()) {
+        files << currentProject->files(ProjectExplorer::Project::ExcludeGeneratedFiles);
+        if (name)
+            *name = currentProject->name();
+    } else {
+        if (const ProjectExplorer::SessionManager *session = projectExplorer->session()) {
+            if (name)
+                *name = session->file()->fileName();
+        const QList<ProjectExplorer::Project *> projects = session->projects();
+        foreach (ProjectExplorer::Project *project, projects)
+            files << project->files(ProjectExplorer::Project::ExcludeGeneratedFiles);
+        }
+    }
+    if (nativeSeparators && !files.empty()) {
+        const QStringList::iterator end = files.end();
+        for (QStringList::iterator it = files.begin(); it != end; ++it)
+            *it = QDir::toNativeSeparators(*it);
+    }
+    return files;
+}
 } // namespace VCSBase
diff --git a/src/plugins/vcsbase/vcsbasesubmiteditor.h b/src/plugins/vcsbase/vcsbasesubmiteditor.h
index 91a43b06d41371fb0626c56b3fd9906395fad9a3..72553672411b003cdd3c0012e7b5df2157edd443 100644
--- a/src/plugins/vcsbase/vcsbasesubmiteditor.h
+++ b/src/plugins/vcsbase/vcsbasesubmiteditor.h
@@ -126,6 +126,10 @@ public:
     static QIcon diffIcon();
     static QIcon submitIcon();
 
+    // Utility returning all project files in case submit lists need to
+    // be restricted to them
+    static QStringList currentProjectFiles(bool nativeSeparators, QString *name = 0);
+
 signals:
     void diffSelectedFiles(const QStringList &files);