2 * This file is part of the vng project
3 * Copyright (C) 2008 Thomas Zander <tzander@trolltech.com>
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
19 #include "ExcludeMatcher.h"
20 #include "GitRunner.h"
25 ExcludeMatcher::ExcludeMatcher(const Configuration
&configuration
)
26 : m_configuration(&configuration
)
30 bool ExcludeMatcher::isExcluded(const QString
&entry
)
32 Q_ASSERT(QDir::current() == m_configuration
->repository());
33 Q_ASSERT(! entry
.startsWith('/')); // assert relative dir
34 QString relativePath
= "./"+ entry
;
35 if (m_baseMatches
.isEmpty()) {
36 // TODO call git config --get core.excludesfile
37 QString path
= m_configuration
->repositoryMetaDir().path() + "/info/exclude";
39 m_baseMatches
<< m_cachedMatches
[path
];
42 // split entry into separate dirs.
43 QStringList pathSegments
= entry
.split(QDir::separator(), QString::SkipEmptyParts
);
44 QString fileName
= pathSegments
.takeLast(); // remove last entry (the actual filename);
46 if (isExcluded(m_baseMatches
, relativePath
, fileName
))
49 pathSegments
.insert(0, ".");
51 foreach(QString segment
, pathSegments
) {
52 path
= path
+ segment
+ QDir::separator();
53 QString ignoreFile
= path
+ ".gitignore";
54 readExcludes(ignoreFile
);
55 if (isExcluded(m_cachedMatches
[ignoreFile
], relativePath
, fileName
))
61 void ExcludeMatcher::readExcludes(const QString
&fileName
)
63 if (m_cachedMatches
.contains(fileName
))
65 QList
<IgnoreLine
> items
;
66 QFile
ignoreFile(fileName
);
67 if (ignoreFile
.exists()) {
68 if (ignoreFile
.open(QFile::ReadOnly
)) {
69 QTextStream
file(&ignoreFile
);
73 QString line
= file
.readLine();
76 if (line
.isEmpty() || line
[0] == '#')
78 IgnoreLine ignoreLine
;
79 ignoreLine
.inverted
= line
[0] == '!';
80 if (ignoreLine
.inverted
)
82 ignoreLine
.matchOnFileOnly
= !line
.contains('/');
83 if (! ignoreLine
.matchOnFileOnly
&& !line
.startsWith('*'))
85 QRegExp
re(line
, Qt::CaseInsensitive
, QRegExp::Wildcard
);
86 ignoreLine
.regExp
= re
;
90 Logger::debug() << "invalid entry in " << ignoreFile
.fileName() << " line " << line
;
95 m_cachedMatches
.insert(fileName
, items
);
98 bool ExcludeMatcher::isExcluded(const QList
<IgnoreLine
> &ignores
, const QString
&path
, const QString
&fileName
)
100 //qDebug() << "isExcluded" << path << fileName;
101 foreach (IgnoreLine il
, ignores
) {
103 if (il
.matchOnFileOnly
)
104 matches
= il
.regExp
.exactMatch(fileName
);
106 matches
= il
.regExp
.exactMatch(path
);
107 //qDebug() << "trying on " << il.regExp.pattern() << "fileOnly:" << il.matchOnFileOnly << "inverted:" << il.inverted << (matches?" *** Match!":"");
108 if (matches
!= il
.inverted
)