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