2 Author: Marco Costalba (C) 2005-2007
4 Copyright: See COPYING file that comes with this distribution
10 #include <QAbstractItemModel>
11 #include "exceptionmanager.h"
14 template <class, class> struct QPair
;
25 class FileHistory
: public QAbstractItemModel
{
28 FileHistory(QObject
* parent
, Git
* git
);
30 void clear(bool complete
= true);
31 const QString
sha(int row
) const;
32 int row(SCRef sha
) const;
33 const QStringList
fileNames() const { return fNames
; }
34 void resetFileNames(SCRef fn
);
35 void setEarlyOutputState(bool b
= true) { earlyOutputCnt
= (b
? earlyOutputCntBase
: -1); }
36 void setAnnIdValid(bool b
= true) { annIdValid
= b
; }
38 virtual QVariant
data(const QModelIndex
&index
, int role
) const;
39 virtual Qt::ItemFlags
flags(const QModelIndex
& index
) const;
40 virtual QVariant
headerData(int s
, Qt::Orientation o
, int role
= Qt::DisplayRole
) const;
41 virtual QModelIndex
index(int r
, int c
, const QModelIndex
& par
= QModelIndex()) const;
42 virtual QModelIndex
parent(const QModelIndex
& index
) const;
43 virtual int rowCount(const QModelIndex
& par
= QModelIndex()) const;
44 virtual bool hasChildren(const QModelIndex
& par
= QModelIndex()) const;
45 virtual int columnCount(const QModelIndex
&) const { return 5; }
48 void on_changeFont(const QFont
&);
51 void on_newRevsAdded(const FileHistory
*, const QVector
<ShaString
>&);
52 void on_loadCompleted(const FileHistory
*, const QString
&);
55 friend class Annotate
;
56 friend class DataLoader
;
60 const QString
timeDiff(unsigned long secs
) const;
67 QList
<QByteArray
*> rowData
;
68 QList
<QVariant
> headerInfo
;
74 int earlyOutputCntBase
;
76 QStringList curFNames
;
77 QStringList renamedRevs
;
78 QHash
<QString
, QString
> renamedPatches
;
81 struct Reference
{ // stores tag information associated to a revision
82 Reference() : type(0) {}
85 QStringList remoteBranches
;
86 QString currentBranch
;
89 QString tagObj
; // TODO support more then one obj
93 typedef QHash
<ShaString
, Reference
> RefMap
;
96 class Git
: public QObject
{
99 explicit Git(QObject
* parent
);
101 // used as self-documenting boolean parameters
102 static const bool optFalse
= false;
103 static const bool optSaveCache
= true;
104 static const bool optGoDown
= true;
105 static const bool optOnlyLoaded
= true;
106 static const bool optDragDrop
= true;
107 static const bool optFold
= true;
108 static const bool optAmend
= true;
109 static const bool optOnlyInIndex
= true;
110 static const bool optCreate
= true;
124 TreeEntry(SCRef n
, SCRef s
, SCRef t
) : name(n
), sha(s
), type(t
) {}
125 bool operator<(const TreeEntry
&) const;
130 typedef QList
<TreeEntry
> TreeInfo
;
132 void setDefaultModel(FileHistory
* fh
) { revData
= fh
; }
133 void checkEnvironment();
134 void userInfo(SList info
);
135 const QString
getBaseDir(bool* c
, SCRef wd
, bool* ok
= NULL
, QString
* gd
= NULL
);
136 bool init(SCRef wd
, bool range
, const QStringList
* args
, bool overwrite
, bool* quit
);
137 void stop(bool saveCache
);
138 void setThrowOnStop(bool b
);
139 bool isThrowOnStopRaised(int excpId
, SCRef curContext
);
140 void setLane(SCRef sha
, FileHistory
* fh
);
141 Annotate
* startAnnotate(FileHistory
* fh
, QObject
* guiObj
);
142 const FileAnnotation
* lookupAnnotation(Annotate
* ann
, SCRef sha
);
143 void cancelAnnotate(Annotate
* ann
);
144 bool startFileHistory(SCRef sha
, SCRef startingFileName
, FileHistory
* fh
);
145 void cancelDataLoading(const FileHistory
* fh
);
146 void cancelProcess(MyProcess
* p
);
147 bool isCommittingMerge() const { return isMergeHead
; }
148 bool isStGITStack() const { return isStGIT
; }
149 bool isPatchName(SCRef nm
);
150 bool isSameFiles(SCRef tree1Sha
, SCRef tree2Sha
);
151 static bool isImageFile(SCRef file
);
152 static bool isBinaryFile(SCRef file
);
153 bool isNothingToCommit();
154 bool isUnknownFiles() const { return (workingDirInfo
.otherFiles
.count() > 0); }
155 bool isTextHighlighter() const { return isTextHighlighterFound
; }
156 bool isMainHistory(const FileHistory
* fh
) { return (fh
== revData
); }
157 MyProcess
* getDiff(SCRef sha
, QObject
* receiver
, SCRef diffToSha
, bool combined
);
158 const QString
getWorkDirDiff(SCRef fileName
= "");
159 MyProcess
* getFile(SCRef fileSha
, QObject
* receiver
, QByteArray
* result
, SCRef fileName
);
160 MyProcess
* getHighlightedFile(SCRef fileSha
, QObject
* receiver
, QString
* result
, SCRef fileName
);
161 const QString
getFileSha(SCRef file
, SCRef revSha
);
162 bool saveFile(SCRef fileSha
, SCRef fileName
, SCRef path
);
163 void getFileFilter(SCRef path
, ShaSet
& shaSet
);
164 bool getPatchFilter(SCRef exp
, bool isRegExp
, ShaSet
& shaSet
);
165 const RevFile
* getFiles(SCRef sha
, SCRef sha2
= "", bool all
= false, SCRef path
= "");
166 bool getTree(SCRef ts
, TreeInfo
& ti
, bool wd
, SCRef treePath
);
167 static const QString
getLocalDate(SCRef gitDate
);
168 const QString
getDesc(SCRef sha
, QRegExp
& slogRE
, QRegExp
& lLogRE
, bool showH
, FileHistory
* fh
);
169 const QString
getLastCommitMsg();
170 const QString
getNewCommitMsg();
171 const QString
getLaneParent(SCRef fromSHA
, int laneNum
);
172 const QStringList
getChilds(SCRef parent
);
173 const QStringList
getNearTags(bool goDown
, SCRef sha
);
174 const QStringList
getDescendantBranches(SCRef sha
, bool shaOnly
= false);
175 const QString
getShortLog(SCRef sha
);
176 const QString
getTagMsg(SCRef sha
);
177 const Rev
* revLookup(const ShaString
& sha
, const FileHistory
* fh
= NULL
) const;
178 const Rev
* revLookup(SCRef sha
, const FileHistory
* fh
= NULL
) const;
179 uint
checkRef(const ShaString
& sha
, uint mask
= ANY_REF
) const;
180 uint
checkRef(SCRef sha
, uint mask
= ANY_REF
) const;
181 const QString
getRevInfo(SCRef sha
);
182 const QString
getRefSha(SCRef refName
, RefType type
= ANY_REF
, bool askGit
= true);
183 const QStringList
getRefName(SCRef sha
, RefType type
, QString
* curBranch
= NULL
) const;
184 const QStringList
getAllRefNames(uint mask
, bool onlyLoaded
);
185 const QStringList
getAllRefSha(uint mask
);
186 void getWorkDirFiles(SList files
, SList dirs
, RevFile::StatusFlag status
);
187 QTextCodec
* getTextCodec(bool* isGitArchive
);
188 bool formatPatch(SCList shaList
, SCRef dirPath
, SCRef remoteDir
= "");
189 bool updateIndex(SCList selFiles
);
190 bool commitFiles(SCList files
, SCRef msg
, bool amend
);
191 bool makeTag(SCRef sha
, SCRef tag
, SCRef msg
);
192 bool deleteTag(SCRef sha
);
193 bool applyPatchFile(SCRef patchPath
, bool fold
, bool sign
);
194 bool resetCommits(int parentDepth
);
195 bool stgCommit(SCList selFiles
, SCRef msg
, SCRef patchName
, bool fold
);
196 bool stgPush(SCRef sha
);
197 bool stgPop(SCRef sha
);
198 void setTextCodec(QTextCodec
* tc
);
199 void addExtraFileInfo(QString
* rowName
, SCRef sha
, SCRef diffToSha
, bool allMergeFiles
);
200 void removeExtraFileInfo(QString
* rowName
);
201 void formatPatchFileHeader(QString
* rowName
, SCRef sha
, SCRef dts
, bool cmb
, bool all
);
202 int findFileIndex(const RevFile
& rf
, SCRef name
);
203 const QString
filePath(const RevFile
& rf
, uint i
) const {
205 return dirNamesVec
[rf
.dirAt(i
)] + fileNamesVec
[rf
.nameAt(i
)];
207 void setCurContext(Domain
* d
) { curDomain
= d
; }
208 Domain
* curContext() const { return curDomain
; }
211 void newRevsAdded(const FileHistory
*, const QVector
<ShaString
>&);
212 void loadCompleted(const FileHistory
*, const QString
&);
213 void cancelLoading(const FileHistory
*);
214 void cancelAllProcesses();
215 void annotateReady(Annotate
*, bool, const QString
&);
216 void fileNamesLoad(int, int);
217 void changeFont(const QFont
&);
220 void procReadyRead(const QByteArray
&);
224 void loadFileCache();
225 void loadFileNames();
226 void on_runAsScript_eof();
227 void on_getHighlightedFile_eof();
228 void on_newDataReady(const FileHistory
*);
229 void on_loaded(FileHistory
*, ulong
,int,bool,const QString
&,const QString
&);
232 friend class MainImpl
;
233 friend class DataLoader
;
234 friend class ConsoleImpl
;
235 friend class RevsView
;
237 struct WorkingDirInfo
{
238 void clear() { diffIndex
= diffIndexCached
= ""; otherFiles
.clear(); }
240 QString diffIndexCached
;
241 QStringList otherFiles
;
243 WorkingDirInfo workingDirInfo
;
245 struct LoadArguments
{ // used to pass arguments to init2()
247 bool filteredLoading
;
248 QStringList filterList
;
250 LoadArguments loadArguments
;
252 struct FileNamesLoader
{
253 FileNamesLoader() : rf(NULL
) {}
257 QVector
<int> rfNames
;
259 FileNamesLoader fileLoader
;
262 bool run(SCRef cmd
, QString
* out
= NULL
, QObject
* rcv
= NULL
, SCRef buf
= "");
263 bool run(QByteArray
* runOutput
, SCRef cmd
, QObject
* rcv
= NULL
, SCRef buf
= "");
264 MyProcess
* runAsync(SCRef cmd
, QObject
* rcv
, SCRef buf
= "");
265 MyProcess
* runAsScript(SCRef cmd
, QObject
* rcv
= NULL
, SCRef buf
= "");
266 const QStringList
getArgs(bool* quit
, bool repoChanged
);
268 void parseStGitPatches(SCList patchNames
, SCList patchShas
);
270 void clearFileNames();
271 bool startRevList(SCList args
, FileHistory
* fh
);
272 bool startUnappliedList();
273 bool startParseProc(SCList initCmd
, FileHistory
* fh
, SCRef buf
);
274 bool tryFollowRenames(FileHistory
* fh
);
275 bool populateRenamedPatches(SCRef sha
, SCList nn
, FileHistory
* fh
, QStringList
* on
, bool bt
);
276 bool filterEarlyOutputRev(FileHistory
* fh
, Rev
* rev
);
277 int addChunk(FileHistory
* fh
, const QByteArray
& ba
, int ofs
);
278 void parseDiffFormat(RevFile
& rf
, SCRef buf
, FileNamesLoader
& fl
);
279 void parseDiffFormatLine(RevFile
& rf
, SCRef line
, int parNum
, FileNamesLoader
& fl
);
281 Rev
* fakeRevData(SCRef sha
, SCList parents
, SCRef author
, SCRef date
, SCRef log
,
282 SCRef longLog
, SCRef patch
, int idx
, FileHistory
* fh
);
283 const Rev
* fakeWorkDirRev(SCRef parent
, SCRef log
, SCRef longLog
, int idx
, FileHistory
* fh
);
284 const RevFile
* fakeWorkDirRevFile(const WorkingDirInfo
& wd
);
285 bool copyDiffIndex(FileHistory
* fh
, SCRef parent
);
286 const RevFile
* insertNewFiles(SCRef sha
, SCRef data
);
287 const RevFile
* getAllMergeFiles(const Rev
* r
);
288 bool runDiffTreeWithRenameDetection(SCRef runCmd
, QString
* runOutput
);
289 bool isParentOf(SCRef par
, SCRef child
);
290 bool isTreeModified(SCRef sha
);
292 void updateDescMap(const Rev
* r
, uint i
, QHash
<QPair
<uint
, uint
>,bool>& dm
,
293 QHash
<uint
, QVector
<int> >& dv
);
294 void mergeNearTags(bool down
, Rev
* p
, const Rev
* r
, const QHash
<QPair
<uint
, uint
>, bool>&dm
);
295 void mergeBranches(Rev
* p
, const Rev
* r
);
296 void updateLanes(Rev
& c
, Lanes
& lns
, SCRef sha
);
297 bool mkPatchFromWorkDir(SCRef msg
, SCRef patchFile
, SCList files
);
298 const QStringList
getOthersFiles();
299 const QStringList
getOtherFiles(SCList selFiles
, bool onlyInIndex
);
300 const QString
getNewestFileName(SCList args
, SCRef fileName
);
301 static const QString
colorMatch(SCRef txt
, QRegExp
& regExp
);
302 void appendFileName(RevFile
& rf
, SCRef name
, FileNamesLoader
& fl
);
303 void flushFileNames(FileNamesLoader
& fl
);
304 void populateFileNamesMap();
305 const QString
formatList(SCList sl
, SCRef name
, bool inOneLine
= true);
306 static const QString
quote(SCRef nm
);
307 static const QString
quote(SCList sl
);
308 static const QStringList
noSpaceSepHack(SCRef cmd
);
309 void removeDeleted(SCList selFiles
);
310 void setStatus(RevFile
& rf
, SCRef rowSt
);
311 void setExtStatus(RevFile
& rf
, SCRef rowSt
, int parNum
, FileNamesLoader
& fl
);
312 void appendNamesWithId(QStringList
& names
, SCRef sha
, SCList data
, bool onlyLoaded
);
313 Reference
* lookupReference(const ShaString
& sha
, bool create
= false);
315 EM_DECLARE(exGitStopped
);
318 QString workDir
; // workDir is always without trailing '/'
320 QString filesLoadingPending
;
321 QString filesLoadingCurSha
;
322 int filesLoadingStartOfs
;
323 bool cacheNeedsUpdate
;
324 bool errorReportingEnabled
;
328 bool isTextHighlighterFound
;
329 bool loadingUnAppliedPatches
;
330 bool fileCacheAccessed
;
331 int patchesStillToFind
;
332 QString firstNonStGitPatch
;
333 RevFileMap revsFiles
;
334 QVector
<QByteArray
> revsFilesShaBackupBuf
;
336 QVector
<QByteArray
> shaBackupBuf
;
337 StrVect fileNamesVec
;
339 QHash
<QString
, int> fileNamesMap
; // quick lookup file name
340 QHash
<QString
, int> dirNamesMap
; // quick lookup directory name
341 FileHistory
* revData
;