2 * Copyright (C) 2007 Thiago Macieira <thiago@kde.org>
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 #include "repository.h"
19 #include <QTextStream>
22 Repository::Repository(const Rules::Repository
&rule
)
25 foreach (Rules::Repository::Branch branchRule
, rule
.branches
) {
27 branch
.isCreated
= false;
29 branches
.insert(branchRule
.name
, branch
);
32 // create the default branch
33 branches
["master"].isCreated
= true;
35 fastImport
.setWorkingDirectory(name
);
38 Repository::~Repository()
40 if (fastImport
.state() != QProcess::NotRunning
) {
41 fastImport
.closeWriteChannel();
42 fastImport
.waitForFinished();
46 void Repository::reloadBranches()
48 QHash
<QString
, Branch
>::Iterator it
= branches
.begin(),
50 for ( ; it
!= end
; ++it
) {
51 QString branchRef
= it
.key();
52 if (!branchRef
.startsWith("refs/"))
53 branchRef
.prepend("refs/heads/");
56 // does this branch already exist?
58 revParse
.setWorkingDirectory(name
);
59 revParse
.start("git-rev-parse", QStringList() << "--verify" << branchRef
);
60 revParse
.waitForFinished();
62 if (revParse
.exitCode() == 0)
69 fastImport
.write("reset " + branchRef
.toUtf8() +
70 "\nfrom " + branchRef
.toUtf8() + "^0\n\n");
76 void Repository::createBranch(const QString
&branch
, int revnum
,
77 const QString
&branchFrom
, int)
79 if (!branches
.contains(branch
)) {
80 qCritical() << branch
<< "is not a known branch in repository" << name
;
85 QByteArray branchRef
= branch
.toUtf8();
86 if (!branchRef
.startsWith("refs/"))
87 branchRef
.prepend("refs/heads/");
89 Branch
&br
= branches
[branch
];
91 QByteArray backupBranch
= branchRef
+ '_' + QByteArray::number(revnum
);
92 qWarning() << branch
<< "already exists; backing up to" << backupBranch
;
94 fastImport
.write("reset " + backupBranch
+ "\nfrom " + branchRef
+ "\n\n");
97 // now create the branch
99 QByteArray branchFromRef
= branchFrom
.toUtf8();
100 if (!branchFromRef
.startsWith("refs/"))
101 branchFromRef
.prepend("refs/heads/");
103 fastImport
.write("reset " + branchRef
+ "\nfrom " + branchFromRef
+ "\n\n");
106 Repository::Transaction
*Repository::newTransaction(const QString
&branch
, const QString
&svnprefix
,
109 if (!branches
.contains(branch
)) {
110 qCritical() << branch
<< "is not a known branch in repository" << name
;
114 Transaction
*txn
= new Transaction
;
115 txn
->repository
= this;
116 txn
->branch
= branch
.toUtf8();
117 txn
->svnprefix
= svnprefix
.toUtf8();
119 txn
->revnum
= revnum
;
120 txn
->lastmark
= revnum
;
126 void Repository::startFastImport()
128 if (fastImport
.state() == QProcess::NotRunning
) {
131 fastImport
.setProcessChannelMode(QProcess::ForwardedChannels
);
132 fastImport
.start("git-fast-import", QStringList());
134 QString outputFile
= name
;
135 outputFile
.replace('/', '_');
136 fastImport
.setStandardOutputFile(outputFile
, QIODevice::Append
);
137 fastImport
.start("/bin/cat", QStringList());
142 Repository::Transaction::~Transaction()
146 void Repository::Transaction::setAuthor(const QByteArray
&a
)
151 void Repository::Transaction::setDateTime(uint dt
)
156 void Repository::Transaction::setLog(const QByteArray
&l
)
161 void Repository::Transaction::deleteFile(const QString
&path
)
163 deletedFiles
.append(path
);
166 QIODevice
*Repository::Transaction::addFile(const QString
&path
, int mode
, qint64 length
)
170 fp
.mark
= ++lastmark
;
173 repository
->fastImport
.write("blob\nmark :");
174 repository
->fastImport
.write(QByteArray::number(fp
.mark
));
175 repository
->fastImport
.write("\ndata ");
176 repository
->fastImport
.write(QByteArray::number(length
));
177 repository
->fastImport
.write("\n", 1);
178 repository
->fastImport
.waitForBytesWritten(0);
181 modifiedFiles
.insert(path
, fp
);
182 return &repository
->fastImport
;
185 void Repository::Transaction::commit()
187 // create the commit message
188 QByteArray message
= log
;
189 if (!message
.endsWith('\n'))
191 message
+= "\nsvn path=" + svnprefix
+ "; revision=" + QByteArray::number(revnum
) + "\n";
194 QByteArray branchRef
= branch
;
195 if (!branchRef
.startsWith("refs/"))
196 branchRef
.prepend("refs/heads/");
198 QTextStream
s(&repository
->fastImport
);
199 s
<< "commit " << branchRef
<< endl
;
200 s
<< "mark :" << revnum
<< endl
;
201 s
<< "committer " << author
<< ' ' << datetime
<< " -0000" << endl
;
203 Branch
&br
= repository
->branches
[branch
];
208 s
<< "data " << message
.length() << endl
;
211 repository
->fastImport
.write(message
);
213 // write the file deletions
214 if (deletedFiles
.contains(""))
215 repository
->fastImport
.write("deleteall\n");
217 foreach (QString df
, deletedFiles
)
218 repository
->fastImport
.write("D " + df
.toUtf8() + "\n");
220 // write the file modifications
221 QHash
<QString
, FileProperties
>::ConstIterator it
= modifiedFiles
.constBegin();
222 for ( ; it
!= modifiedFiles
.constEnd(); ++it
) {
223 repository
->fastImport
.write("M ", 2);
224 repository
->fastImport
.write(QByteArray::number(it
->mode
, 8));
225 repository
->fastImport
.write(" :", 2);
226 repository
->fastImport
.write(QByteArray::number(it
->mark
));
227 repository
->fastImport
.write(" ", 1);
228 repository
->fastImport
.write(it
.key().toUtf8());
229 repository
->fastImport
.write("\n", 1);
232 repository
->fastImport
.write("\n");
234 while (repository
->fastImport
.bytesToWrite() && repository
->fastImport
.waitForBytesWritten()) {