Make detection of empty repo also work after a git gc
[vng.git] / src / commands / Push.cpp
blob72b46d1486bb49d3ad5ce3ee6e70331321de26b7
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 "GenericCursor.h"
24 #include "Interview.h"
25 #include "Vng.h"
27 #include <QProcess>
28 #include <QDebug>
29 #include <QRegExp>
31 static const CommandLineOption options[] = {
32 // TODO :)
33 // {"--matches=PATTERN", "select patches matching PATTERN"},
34 // {"-p REGEXP, --patches=REGEXP", "select patches matching REGEXP"},
35 // {"-t REGEXP, --tags=REGEXP", "select tags matching REGEXP"},
36 // {"-a, --all", "answer yes to all patches"},
37 // {"-i, --interactive", "prompt user interactively"},
38 // {"-s, --summary", "summarize changes"},
39 // {"--no-summary", "don't summarize changes"},
40 {"--set-default", "set default repository [DEFAULT]"},
41 {"--no-set-default", "don't set default repository"},
42 CommandLineLastOption
45 Push::Push()
46 : AbstractCommand("push")
48 CommandLineParser::addOptionDefinitions(options);
49 CommandLineParser::setArgumentDefinition("push [Repository]" );
52 AbstractCommand::ReturnCodes Push::run()
54 if (! checkInRepository())
55 return NotInRepo;
56 CommandLineParser *args = CommandLineParser::instance();
59 // Find out which remote repo to use
60 RemoteRepo remoteRepo;
61 if (args->arguments().count() > 1) {
62 remoteRepo = RemoteRepo(args->arguments().at(1), args->arguments().at(1));
63 } else {
64 foreach (const RemoteRepo &repo, m_config.remotes()) {
65 if (repo.isDefault()) {
66 remoteRepo = repo;
67 break;
71 if (! remoteRepo.isValid()) {
72 if (m_config.remotes().isEmpty()) {
73 Logger::error() << "Vng failed: Please specify the remote repository you want to push to\n";
74 return InvalidOptions;
76 if (m_config.remotes().size() > 1) {
77 GenericCursor cursor;
78 foreach (const RemoteRepo &repo, m_config.remotes()) {
79 if (repo.url() == repo.name())
80 cursor.addDataItem(QLatin1String(" at ") + repo.url());
81 else
82 cursor.addDataItem(QLatin1String(" '") + repo.name()
83 + QLatin1String("` (") + repo.url() + QLatin1Char(')'));
85 Interview interview(cursor, QLatin1String("Shall I use this repository?"));
86 interview.setUsePager(shouldUsePager());
87 if (!interview.start())
88 return Ok;
89 Q_ASSERT(!cursor.selectedItems().isEmpty());
90 remoteRepo = m_config.remotes().at(cursor.selectedItems().first());
91 } else {
92 remoteRepo = m_config.remotes().first();
95 Q_ASSERT(remoteRepo.isValid());
97 Logger::warn() << "Pushing to `" << remoteRepo.url() << "'\n";
98 Logger::warn().flush(); // make sure its printed before git asks for an ssh pwd.
99 if (dryRun())
100 return Ok;
102 // TODO when not using --all ask the remote for all the refs it has and detect which ones we still have to push
103 // TODO use interview to ask which refs to push instead of all below
104 QProcess git;
105 QStringList arguments;
106 arguments << QLatin1String("push") << remoteRepo.url();
107 GitRunner runner(git, arguments);
108 AbstractCommand::ReturnCodes rc = runner.start(GitRunner::WaitForStandardOutput);
109 if (rc != Ok) {
110 Logger::error() << "Git push failed\n";
111 return rc;
114 char buf[1024];
115 while(true) { // just pipe out data
116 git.waitForReadyRead(-1);
117 qint64 readLength = git.read(buf, sizeof(buf)-1);
118 if (readLength <= 0)
119 break;
120 buf[readLength] = 0;
121 Logger::standardOut() << buf;
123 git.waitForFinished(-1);
125 const bool makeDefault = args->contains(QLatin1String("set-default"))
126 || (m_config.contains(QLatin1String("set-default"))
127 && !args->contains(QLatin1String("no-set-default")));
128 m_config.addRepo(remoteRepo, makeDefault ? Configuration::AddAsDefault
129 : Configuration::AddNotDefault);
130 return Ok;
133 QString Push::argumentDescription() const
135 return QLatin1String("[REPOSITORY]");
138 QString Push::commandDescription() const
140 return QLatin1String("push is the opposite of pull. push allows you to copy changes from the\n"
141 "current repository into another repository.\n");