2 # -*- coding: utf-8 -*-
7 Copyright (c) 2013 Frédéric Massart - FMCorz.net
9 This program is free software: you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation, either version 3 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program. If not, see <http://www.gnu.org/licenses/>.
22 http://github.com/FMCorz/mdk
26 from ..command
import Command
29 class RebaseCommand(Command
):
31 _description
= 'Rebase branches'
33 def __init__(self
, *args
, **kwargs
):
34 super(RebaseCommand
, self
).__init__(*args
, **kwargs
)
39 'help': 'issues to be rebased',
48 'help': 'the suffix of the branch of those issues',
55 'choices': [str(x
) for x
in range(13, int(self
.C
.get('masterBranch')))] + ['master'],
56 'help': 'versions to rebase the issues on. Ignored if names is set.',
64 'action': 'store_true',
65 'help': 'push the branch after successful rebase'
69 ['-t', '--update-tracker'],
71 'action': 'store_true',
72 'dest': 'updatetracker',
73 'help': 'to use with --push, also add the diff information to the tracker issue'
79 'default': self
.C
.get('myRemote'),
80 'help': 'the remote to push the branch to. Default is %s.' % self
.C
.get('myRemote'),
85 ['-f', '--force-push'],
87 'action': 'store_true',
89 'help': 'Force the push'
96 'help': 'name of the instances to rebase',
107 versions
= args
.versions
109 # If we don't have a version, we need an instance
110 if not names
and not versions
:
111 raise Exception('This is not a Moodle instance')
113 # We don't have any names but some versions are set
117 names
.append(self
.Wp
.generateInstanceName(v
))
120 Mlist
= self
.Wp
.resolveMultiple(names
)
122 # Updating cache remotes
123 logging
.info('Updating cached repositories')
124 self
.Wp
.updateCachedClones(verbose
=False)
126 # Loops over instances to rebase
128 logging
.info('Working on %s' %
(M
.get('identifier')))
129 M
.git().fetch(self
.C
.get('upstreamRemote'))
131 # Test if currently in a detached branch
132 if M
.git().currentBranch() == 'HEAD':
133 result
= M
.git().checkout(M
.get('stablebranch'))
134 # If we can't checkout the stable branch, that is probably because we are in an unmerged situation
136 logging
.warning('Error. The repository seem to be on a detached branch. Skipping.')
140 stash
= M
.git().stash(untracked
=True)
142 logging
.error('Error while trying to stash your changes. Skipping %s.' % M
.get('identifier'))
143 logging
.debug(stash
[2])
145 elif not stash
[1].startswith('No local changes'):
146 logging
.info('Stashed your local changes')
148 # Looping over each issue to rebase
150 branch
= M
.generateBranchName(issue
, suffix
=args
.suffix
)
151 if not M
.git().hasBranch(branch
):
152 logging
.warning('Could not find branch %s' %
(branch
))
156 logging
.info('> Rebasing %s...' %
(branch
))
157 base
= '%s/%s' %
(self
.C
.get('upstreamRemote'), M
.get('stablebranch'))
158 result
= M
.git().rebase(branch
=branch
, base
=base
)
160 logging
.warning('Error while rebasing branch %s on top of %s' %
(branch
, base
))
161 if result
[0] == 1 and result
[2].strip() == '':
162 logging
.debug('There must be conflicts.')
163 logging
.info('Aborting... Please rebase manually.')
164 M
.git().rebase(abort
=True)
166 logging
.debug(result
[2])
172 logging
.info('Pushing %s to %s' %
(branch
, remote
))
173 result
= M
.git().push(remote
=remote
, branch
=branch
, force
=args
.forcepush
)
175 logging
.warning('Error while pushing to remote')
176 logging
.debug(result
[2])
180 if args
.updatetracker
:
181 M
.updateTrackerGitInfo(branch
=branch
)
184 if not stash
[1].startswith('No local changes'):
185 pop
= M
.git().stash(command
='pop')
187 logging
.error('An error ocured while unstashing your changes')
188 logging
.debug(pop
[2])
190 logging
.info('Popped the stash')
194 logging
.info('Done.')