From 7a90ae8a0339b7b39cb3cdeb5439e86f3b1058d6 Mon Sep 17 00:00:00 2001 From: Thomas Zander Date: Wed, 30 Apr 2008 15:37:07 +0200 Subject: [PATCH] Make the matcher also read the data from the git standard excludes file --- Add.cpp | 7 +++-- Configuration.cpp | 7 +++++ Configuration.h | 4 +++ ExcludeMatcher.cpp | 92 +++++++++++++++++++++++++++++------------------------- ExcludeMatcher.h | 9 ++++-- 5 files changed, 73 insertions(+), 46 deletions(-) diff --git a/Add.cpp b/Add.cpp index 9fbb9ab..5573c3d 100644 --- a/Add.cpp +++ b/Add.cpp @@ -45,15 +45,18 @@ AbstractCommand::ReturnCodes Add::run() { if (! checkInRepository()) return NotInRepo; + CommandLineParser *args = CommandLineParser::instance(); moveToRoot(); - ExcludeMatcher excludeMatcher; + ExcludeMatcher excludeMatcher(m_config); + int argIndex = 0; foreach(QString arg, rebasedArguments()) { + ++argIndex; QFileInfo path(arg); if (! arg.endsWith('/') && path.isDir()) arg = arg + '/'; if (excludeMatcher.isExcluded(arg)) { - Logger::info() << "Skipping boring file: `" << arg << "'\n"; + Logger::info() << "Skipping boring file: `" << args->arguments()[argIndex] << "'\n"; continue; } if (path.exists()) { diff --git a/Configuration.cpp b/Configuration.cpp index 5493730..6e3b4a4 100644 --- a/Configuration.cpp +++ b/Configuration.cpp @@ -48,6 +48,12 @@ QDir Configuration::repository() const return m_repoDir; } +QDir Configuration::repositoryMetaDir() const +{ + const_cast (this)->readConfig(); + return m_repoMetaDataDir; +} + void Configuration::readConfig() { if (!m_dirty) @@ -60,6 +66,7 @@ void Configuration::readConfig() QDir git = dir; if (git.cd(".git")) { m_repoDir = dir; + m_repoMetaDataDir = git; QDir refs(git.absoluteFilePath("refs/heads")); m_emptyRepo = refs.count() == 2; // only '.' and '..' break; diff --git a/Configuration.h b/Configuration.h index 6470039..3430458 100644 --- a/Configuration.h +++ b/Configuration.h @@ -32,7 +32,10 @@ public: bool contains(const QString & key) const; QString optionArgument(const QString &optionName, const QString &defaultValue = QString()) const; + /// return the base directory of this repository. QDir repository() const; + /// returns the directory where the database and other meta data is stored. + QDir repositoryMetaDir() const; bool colorTerm() const; @@ -66,6 +69,7 @@ private: void fetchBranches(); QDir m_repoDir; + QDir m_repoMetaDataDir; QString m_section; bool m_dirty, m_emptyRepo, m_fetchedBranches; QHash m_options; diff --git a/ExcludeMatcher.cpp b/ExcludeMatcher.cpp index df6f726..c402761 100644 --- a/ExcludeMatcher.cpp +++ b/ExcludeMatcher.cpp @@ -22,71 +22,79 @@ #include -ExcludeMatcher::ExcludeMatcher() +ExcludeMatcher::ExcludeMatcher(const Configuration &configuration) + : m_configuration(&configuration) { + Q_ASSERT(QDir::current() == m_configuration->repository()); } bool ExcludeMatcher::isExcluded(const QString &entry) { - // TODO - // current dir should have a .git dir. [assert] - // entry is a relative path from our current dir. [assert] + Q_ASSERT(! entry.startsWith('/')); // assert relative dir + QString relativePath = "./"+ entry; if (m_baseMatches.isEmpty()) { - // TODO - // call git config --get core.excludesfile - // $GIT_DIR/info/exclude + // TODO call git config --get core.excludesfile + QString path = m_configuration->repositoryMetaDir().path() + "/info/exclude"; + readExcludes(path); + m_baseMatches << m_cachedMatches[path]; } // split entry into separate dirs. QStringList pathSegments = entry.split(QDir::separator(), QString::SkipEmptyParts); QString fileName = pathSegments.takeLast(); // remove last entry (the actual filename); - if (isExcluded(m_baseMatches, entry, fileName)) + if (isExcluded(m_baseMatches, relativePath, fileName)) return true; pathSegments.insert(0, "."); QString path; foreach(QString segment, pathSegments) { path = path + segment + QDir::separator(); - if (! m_cachedMatches.contains(path)) { - QList items; - QFile ignoreFile(path +".gitignore"); - if (ignoreFile.exists()) { - if (ignoreFile.open(QFile::ReadOnly)) { - QTextStream file(&ignoreFile); - int line=0; - while(true) { - ++line; - QString line = file.readLine(); - if (line.isNull()) - break; - if (line.isEmpty() || line[0] == '#') - continue; - IgnoreLine ignoreLine; - ignoreLine.inverted = line[0] == '!'; - if (ignoreLine.inverted) - line = line.mid(1); - ignoreLine.matchOnFileOnly = !line.contains('/'); - if (! ignoreLine.matchOnFileOnly && !line.startsWith('*')) - line = "*" + line; - QRegExp re(line, Qt::CaseInsensitive, QRegExp::Wildcard); - ignoreLine.regExp = re; - if (re.isValid()) - items << ignoreLine; - else - Logger::debug() << "invalid entry in " << ignoreFile.fileName() << " line " << line; - } - ignoreFile.close(); - } - } - m_cachedMatches.insert(path, items); - } - if (isExcluded(m_cachedMatches[path], entry, fileName)) + QString ignoreFile = path + ".gitignore"; + readExcludes(ignoreFile); + if (isExcluded(m_cachedMatches[ignoreFile], relativePath, fileName)) return true; } return false; } +void ExcludeMatcher::readExcludes(const QString &fileName) +{ + if (m_cachedMatches.contains(fileName)) + return; + QList items; + QFile ignoreFile(fileName); + if (ignoreFile.exists()) { + if (ignoreFile.open(QFile::ReadOnly)) { + QTextStream file(&ignoreFile); + int line=0; + while(true) { + ++line; + QString line = file.readLine(); + if (line.isNull()) + break; + if (line.isEmpty() || line[0] == '#') + continue; + IgnoreLine ignoreLine; + ignoreLine.inverted = line[0] == '!'; + if (ignoreLine.inverted) + line = line.mid(1); + ignoreLine.matchOnFileOnly = !line.contains('/'); + if (! ignoreLine.matchOnFileOnly && !line.startsWith('*')) + line = "*" + line; + QRegExp re(line, Qt::CaseInsensitive, QRegExp::Wildcard); + ignoreLine.regExp = re; + if (re.isValid()) + items << ignoreLine; + else + Logger::debug() << "invalid entry in " << ignoreFile.fileName() << " line " << line; + } + ignoreFile.close(); + } + } + m_cachedMatches.insert(fileName, items); +} + bool ExcludeMatcher::isExcluded(const QList &ignores, const QString &path, const QString &fileName) { //qDebug() << "isExcluded" << path << fileName; diff --git a/ExcludeMatcher.h b/ExcludeMatcher.h index faf0d6e..43c7cd2 100644 --- a/ExcludeMatcher.h +++ b/ExcludeMatcher.h @@ -23,9 +23,11 @@ #include #include +class Configuration; + class ExcludeMatcher { public: - ExcludeMatcher(); + ExcludeMatcher(const Configuration &configuration); bool isExcluded(const QString &entry); @@ -35,10 +37,13 @@ private: bool matchOnFileOnly, inverted; }; - bool isExcluded(const QList &ignores, const QString &path, const QString &filename); + bool isExcluded(const QList &ignores, const QString &path, const QString &fileName); + void readExcludes(const QString &fileName); QHash > m_cachedMatches; QList m_baseMatches; + + const Configuration *m_configuration; }; #endif -- 2.11.4.GIT