]> andersk Git - svn-all-fast-export.git/blob - src/repository.cpp
20ea04918eac28c88add19d0a826a91616aa296c
[svn-all-fast-export.git] / src / repository.cpp
1 /*
2  *  Copyright (C) 2007  Thiago Macieira <thiago@kde.org>
3  *
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.
8  *
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.
13  *
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/>.
16  */
17
18 #include "repository.h"
19 #include <QTextStream>
20 #include <QDebug>
21
22 Repository::Repository(const Rules::Repository &rule)
23     : name(rule.name)
24 {
25     foreach (Rules::Repository::Branch branchRule, rule.branches) {
26         Branch branch;
27         branch.branchFrom = branchRule.branchFrom;
28         if (!branch.branchFrom.startsWith("refs/"))
29             branch.branchFrom.prepend("refs/heads/");
30         branch.isCreated = false;
31
32         branches.insert(branchRule.name, branch);
33     }
34
35     // create the default branch
36     branches["master"].isCreated = true;
37
38     fastImport.setWorkingDirectory(name);
39     fastImport.setProcessChannelMode(QProcess::ForwardedChannels);
40 }
41
42 Repository::~Repository()
43 {
44     if (fastImport.state() != QProcess::NotRunning) {
45         fastImport.closeWriteChannel();
46         fastImport.waitForFinished();
47     }
48 }
49
50 void Repository::reloadBranches()
51 {
52     QHash<QString, Branch>::Iterator it = branches.begin(),
53                                     end = branches.end();
54     for ( ; it != end; ++it) {
55         QString branchRef = it.key();
56         if (!branchRef.startsWith("refs/"))
57             branchRef.prepend("refs/heads/");
58
59         bool branchExists;
60         // does this branch already exist?
61         QProcess revParse;
62         revParse.setWorkingDirectory(name);
63         revParse.start("git-rev-parse", QStringList() << "--verify" << branchRef);
64         revParse.waitForFinished();
65
66         if (revParse.exitCode() == 0)
67             branchExists = true;
68         else
69             branchExists = false;
70
71         if (branchExists) {
72             startFastImport();
73             fastImport.write("reset " + branchRef.toUtf8() +
74                              "\nfrom " + branchRef.toUtf8() + "^0\n\n");
75             it->isCreated = true;
76         }
77     }
78 }
79
80 Repository::Transaction *Repository::newTransaction(const QString &branch, const QString &svnprefix,
81                                                     int revnum)
82 {
83     if (!branches.contains(branch)) {
84         qCritical() << branch << "is not a known branch in repository" << name;
85         return 0;
86     }
87
88     Transaction *txn = new Transaction;
89     txn->repository = this;
90     txn->branch = branch.toUtf8();
91     txn->svnprefix = svnprefix.toUtf8();
92     txn->datetime = 0;
93     txn->revnum = revnum;
94     txn->lastmark = revnum;
95
96     startFastImport();
97     return txn;
98 }
99
100 void Repository::startFastImport()
101 {
102     if (fastImport.state() == QProcess::NotRunning) {
103         // start the process
104 #ifndef DRY_RUN
105         fastImport.start("git-fast-import", QStringList());
106 #else
107         fastImport.start("/bin/cat", QStringList());
108 #endif
109     }
110 }
111
112 Repository::Transaction::~Transaction()
113 {
114 }
115
116 void Repository::Transaction::setAuthor(const QByteArray &a)
117 {
118     author = a;
119 }
120
121 void Repository::Transaction::setDateTime(uint dt)
122 {
123     datetime = dt;
124 }
125
126 void Repository::Transaction::setLog(const QByteArray &l)
127 {
128     log = l;
129 }
130
131 void Repository::Transaction::deleteFile(const QString &path)
132 {
133     deletedFiles.append(path);
134 }
135
136 QIODevice *Repository::Transaction::addFile(const QString &path, int mode, qint64 length)
137 {
138     FileProperties fp;
139     fp.mode = mode;
140     fp.mark = ++lastmark;
141
142 #ifndef DRY_RUN
143     repository->fastImport.write("blob\nmark :");
144     repository->fastImport.write(QByteArray::number(fp.mark));
145     repository->fastImport.write("\ndata ");
146     repository->fastImport.write(QByteArray::number(length));
147     repository->fastImport.write("\n", 1);
148     repository->fastImport.waitForBytesWritten(0);
149 #endif
150
151     modifiedFiles.insert(path, fp);
152     return &repository->fastImport;
153 }
154
155 void Repository::Transaction::commit()
156 {
157     // create the commit message
158     QByteArray message = log;
159     if (!message.endsWith('\n'))
160         message += '\n';
161     message += "\nsvn path=" + svnprefix + "; revision=" + QByteArray::number(revnum) + "\n";
162
163     {
164         QByteArray branchRef = branch;
165         if (!branchRef.startsWith("refs/"))
166             branchRef.prepend("refs/heads/");
167
168         QTextStream s(&repository->fastImport);
169         s << "commit " << branchRef << endl;
170         s << "mark :" << revnum << endl;
171         s << "committer " << author << ' ' << datetime << " -0000" << endl;
172
173         Branch &br = repository->branches[branch];
174         if (!br.isCreated) {
175             br.isCreated = true;
176             s << "from " << br.branchFrom << endl;
177         }
178
179         s << "data " << message.length() << endl;
180     }
181
182     repository->fastImport.write(message);
183
184     // write the file deletions
185     foreach (QString df, deletedFiles)
186         repository->fastImport.write("D " + df.toUtf8() + "\n");
187
188     // write the file modifications
189     QHash<QString, FileProperties>::ConstIterator it = modifiedFiles.constBegin();
190     for ( ; it != modifiedFiles.constEnd(); ++it) {
191         repository->fastImport.write("M ", 2);
192         repository->fastImport.write(QByteArray::number(it->mode, 8));
193         repository->fastImport.write(" :", 2);
194         repository->fastImport.write(QByteArray::number(it->mark));
195         repository->fastImport.write(" ", 1);
196         repository->fastImport.write(it.key().toUtf8());
197         repository->fastImport.write("\n", 1);
198     }
199
200     repository->fastImport.write("\n");
201
202     while (repository->fastImport.bytesToWrite() && repository->fastImport.waitForBytesWritten()) {
203         // nothing
204     }
205 }
This page took 0.061853 seconds and 3 git commands to generate.