diff --git a/src/plugins/git/gerrit/gerritplugin.cpp b/src/plugins/git/gerrit/gerritplugin.cpp index 71637952f00989c5392d72d01a57313cd5809d6e..c1687fb7971f7f3407cf2f90815f1c2286456d7a 100644 --- a/src/plugins/git/gerrit/gerritplugin.cpp +++ b/src/plugins/git/gerrit/gerritplugin.cpp @@ -511,21 +511,19 @@ void GerritPlugin::fetch(const QSharedPointer<Gerrit::Internal::GerritChange> &c } } - if (!verifiedRepository && QFile::exists(repository + QLatin1String("/.gitmodules"))) { - QMap<QString,QString> submodules = gitClient->synchronousSubmoduleList(repository); - - QMap<QString,QString>::const_iterator i = submodules.constBegin(); - while (i != submodules.constEnd()) { - QString remote = i.value(); + if (!verifiedRepository) { + Git::Internal::SubmoduleDataMap submodules = gitClient->submoduleList(repository); + foreach (const Git::Internal::SubmoduleData &submoduleData, submodules) { + QString remote = submoduleData.url; if (remote.endsWith(QLatin1String(".git"))) remote.chop(4); if (remote.contains(m_parameters->host) && remote.endsWith(change->project) - && QFile::exists(repository + QLatin1Char('/') + i.key())) { - repository = QDir::cleanPath(repository + QLatin1Char('/') + i.key()); + && QFile::exists(repository + QLatin1Char('/') + submoduleData.dir)) { + repository = QDir::cleanPath(repository + QLatin1Char('/') + + submoduleData.dir); verifiedRepository = true; break; } - ++i; } } diff --git a/src/plugins/git/gitclient.cpp b/src/plugins/git/gitclient.cpp index 15befd0406a434eca8f129799b916f624c77c1e2..ed2172c60573a338145e190d1c529afa74056151 100644 --- a/src/plugins/git/gitclient.cpp +++ b/src/plugins/git/gitclient.cpp @@ -1962,21 +1962,59 @@ QMap<QString,QString> GitClient::synchronousRemotesList(const QString &workingDi return result; } -// function returns submodules in format path=url -QMap<QString,QString> GitClient::synchronousSubmoduleList(const QString &workingDirectory) +SubmoduleDataMap GitClient::submoduleList(const QString &workingDirectory) { - QMap<QString,QString> result; - if (!QFile::exists(workingDirectory + QLatin1String("/.gitmodules"))) + SubmoduleDataMap result; + QString gitmodulesFileName = workingDirectory + QLatin1String("/.gitmodules"); + if (!QFile::exists(gitmodulesFileName)) return result; - QSettings gitmodulesFile(workingDirectory + QLatin1String("/.gitmodules"), QSettings::IniFormat); + static QMap<QString, SubmoduleDataMap> cachedSubmoduleData; + + if (cachedSubmoduleData.contains(workingDirectory)) + return cachedSubmoduleData.value(workingDirectory); + QStringList args(QLatin1String("-l")); + + QStringList allConfigs = readConfig(workingDirectory, args).split(QLatin1Char('\n')); + const QString submoduleLineStart = QLatin1String("submodule."); + foreach (const QString &configLine, allConfigs) { + if (!configLine.startsWith(submoduleLineStart)) + continue; + + int nameStart = submoduleLineStart.size(); + int nameEnd = configLine.indexOf(QLatin1Char('.'), nameStart); + + QString submoduleName = configLine.mid(nameStart, nameEnd - nameStart); + + SubmoduleData submoduleData; + if (result.contains(submoduleName)) + submoduleData = result[submoduleName]; - foreach (const QString &submoduleGroup, gitmodulesFile.childGroups()) { - gitmodulesFile.beginGroup(submoduleGroup); - result.insertMulti(gitmodulesFile.value(QLatin1String("path")).toString(), - gitmodulesFile.value(QLatin1String("url")).toString()); - gitmodulesFile.endGroup(); + if (configLine.mid(nameEnd, 5) == QLatin1String(".url=")) + submoduleData.url = configLine.mid(nameEnd + 5); + else if (configLine.mid(nameEnd, 8) == QLatin1String(".ignore=")) + submoduleData.ignore = configLine.mid(nameEnd + 8); + else + continue; + + result.insert(submoduleName, submoduleData); + } + + // if config found submodules + if (!result.isEmpty()) { + QSettings gitmodulesFile(gitmodulesFileName, QSettings::IniFormat); + + foreach (const QString &submoduleName, result.keys()) { + gitmodulesFile.beginGroup(QLatin1String("submodule \"") + + submoduleName + QLatin1Char('"')); + result[submoduleName].dir = gitmodulesFile.value(QLatin1String("path")).toString(); + QString ignore = gitmodulesFile.value(QLatin1String("ignore")).toString(); + if (!ignore.isEmpty() && result[submoduleName].ignore.isEmpty()) + result[submoduleName].ignore = ignore; + gitmodulesFile.endGroup(); + } } + cachedSubmoduleData.insert(workingDirectory, result); return result; } @@ -2172,7 +2210,7 @@ void GitClient::submoduleUpdate(const QString &workingDirectory) void GitClient::promptSubmoduleUpdate(const QString &workingDirectory) { - if (!QFile::exists(workingDirectory + QLatin1String("/.gitmodules"))) + if (submoduleList(workingDirectory).isEmpty()) return; if (QMessageBox::question(Core::ICore::mainWindow(), tr("Submodules Found"), diff --git a/src/plugins/git/gitclient.h b/src/plugins/git/gitclient.h index d71b47ac888f831075b22cd4f3de46b45f7db94f..414efe65216b7ba4e4cff578ae018748a8e66871 100644 --- a/src/plugins/git/gitclient.h +++ b/src/plugins/git/gitclient.h @@ -86,6 +86,16 @@ enum StashFlag { NoPrompt = 0x02 }; +class SubmoduleData +{ +public: + QString dir; + QString url; + QString ignore; +}; + +typedef QMap<QString, SubmoduleData> SubmoduleDataMap; + class GitClient : public QObject { Q_OBJECT @@ -200,7 +210,7 @@ public: QMap<QString,QString> synchronousRemotesList(const QString &workingDirectory, QString *errorMessage = 0); - QMap<QString,QString> synchronousSubmoduleList(const QString &workingDirectory); + SubmoduleDataMap submoduleList(const QString &workingDirectory); bool synchronousShow(const QString &workingDirectory, const QString &id, QString *output, QString *errorMessage); diff --git a/src/plugins/git/gitplugin.cpp b/src/plugins/git/gitplugin.cpp index 55dcce5364895a7e0a64aad5d40b1a17b884b04a..1eb1ec4215ffc0d271e9ae98c0443d53f7c0b4ea 100644 --- a/src/plugins/git/gitplugin.cpp +++ b/src/plugins/git/gitplugin.cpp @@ -1323,8 +1323,9 @@ void GitPlugin::updateActions(VcsBase::VcsBasePlugin::ActionState as) foreach (QAction *repositoryAction, m_repositoryActions) repositoryAction->setEnabled(repositoryEnabled); + m_submoduleUpdateAction->setVisible(repositoryEnabled - && QFile::exists(currentState().topLevel() + QLatin1String("/.gitmodules"))); + && !m_gitClient->submoduleList(currentState().topLevel()).isEmpty()); updateContinueAndAbortCommands(); updateRepositoryBrowserAction();