Don't allow to unrecord past the branch point
[vng.git] / Push.cpp
blobcaa6212ad879bcdf18a2f9f8fc831e81f78e9753
1 /*
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 "Push.h"
20 #include "CommandLineParser.h"
21 #include "Logger.h"
22 #include "GitRunner.h"
23 #include "Vng.h"
25 #include <QProcess>
26 #include <QDebug>
27 #include <QRegExp>
29 static const CommandLineOption options[] = {
30 // TODO :)
31 // {"--matches=PATTERN", "select patches matching PATTERN"},
32 // {"-p REGEXP, --patches=REGEXP", "select patches matching REGEXP"},
33 // {"-t REGEXP, --tags=REGEXP", "select tags matching REGEXP"},
34 // {"-a, --all", "answer yes to all patches"},
35 // {"-i, --interactive", "prompt user interactively"},
36 // {"-s, --summary", "summarize changes"},
37 // {"--no-summary", "don't summarize changes"},
38 {"--set-default", "set default repository [DEFAULT]"},
39 {"--no-set-default", "don't set default repository"},
40 CommandLineLastOption
43 Push::Push()
44 : AbstractCommand("Push")
46 CommandLineParser::addOptionDefinitions(options);
49 AbstractCommand::ReturnCodes Push::run()
51 if (! checkInRepository())
52 return NotInRepo;
53 CommandLineParser *args = CommandLineParser::instance();
55 QProcess git;
56 QStringList arguments;
57 arguments << "config" << "-l";
58 GitRunner runner(git, arguments);
59 AbstractCommand::ReturnCodes rc = runner.start(GitRunner::WaitForStandardOutput);
60 if (rc != Ok) {
61 Logger::error() << "Failed to read configuration\n";
62 return rc;
65 QRegExp re("remote\\.(.*)url=(.*)\n");
66 QHash<QString, QString> repoNames;
67 char buf[1024];
68 while (true) { //read relevant lines into repoNames hash
69 qint64 length = Vng::readLine(&git, buf, sizeof(buf));
70 if (length < 0)
71 break;
72 QString line(buf);
73 if (re.exactMatch(line)) {
74 QString context = re.cap(1);
75 if (context.endsWith("."))
76 context = context.left(context.length()-1);
77 repoNames.insert(context, re.cap(2));
81 QString repo("");
82 if (args->arguments().count() > 1)
83 repo = args->arguments()[1];
85 QString url = repo;
86 if (repo.isEmpty())
87 repo = "default"; // the name we store the default as.
88 if (repoNames.contains(repo))
89 url = repoNames[repo];
90 if (url.isEmpty()) { // print help
91 Logger::standardOut() << "failed: Missing argument [REPOSITORY]\n";
92 Logger::standardOut().flush();
93 args->usage(name(), argumentDescription());
94 Logger::standardOut() << endl << commandDescription();
95 return Ok;
98 Logger::info() << "Pushing to `" << url << "'\n";
99 Logger::info().flush(); // make sure its printed before git asks for an ssh pwd.
100 if (dryRun())
101 return Ok;
103 // TODO when not using --all ask the remote for all the refs it has and detect which ones we still have to push
104 // TODO use interview to ask which refs to push instead of all below
105 arguments.clear();
106 arguments << "push" << "--all" << repo;
107 runner.setArguments(arguments);
108 rc = runner.start(GitRunner::WaitForStandardOutput);
109 if (rc != Ok) {
110 Logger::error() << "Git push failed\n";
111 return rc;
114 /* TODO for some reason qprocess doesn't give me any output if the child process already finished :(
115 while (true) {
116 qint64 length = Vng::readLine(&git, buf, sizeof(buf));
117 if (length < 0)
118 break;
119 Logger::info() << QString(buf);
122 git.waitForFinished(-1);
124 if ( !(args->contains("no-set-default")
125 || m_config.contains("no-set-default") && ! args->contains("set-default"))
126 && repo == url) { // lets set as default
127 arguments.clear();
128 arguments << "config" << "--add" << "remote.default.url" << repo;
129 runner.setArguments(arguments);
130 rc = runner.start(GitRunner::WaitUntilFinished);
131 if (rc != Ok) {
132 Logger::error() << "Warning; Failed to store the default value\n";
133 return rc;
137 return Ok;
140 QString Push::argumentDescription() const
142 return "[REPOSITORY]";
145 QString Push::commandDescription() const
147 return "Push is the opposite of pull. Push allows you to copy changes from the\n"
148 "current repository into another repository.\n";