add a merge-and-push command

By defult if will:
* pull rebase master branch on origin
* rebase current feature branch with respect to master
* merge feature branch to master
* propose to delete copy of feature branch on origin
* push master to origin
* delete local feature branch
This commit is contained in:
Benjamin Dauvergne 2019-03-01 21:41:03 +01:00
parent 7279e690b8
commit 85a851f119
1 changed files with 108 additions and 2 deletions

View File

@ -308,6 +308,112 @@ def new(ctx):
ctx.invoke(take, issue_number=issue.id)
class MyProgressPrinter(git.RemoteProgress):
def update(self, op_code, cur_count, max_count=None, message=''):
print(op_code, cur_count, max_count, cur_count / (max_count or 100.0), message or "NO MESSAGE")
@redmine.command(name='merge-and-push')
@click.argument('target_branch', default='master')
def merge_and_pus(target_branch):
repo = get_repo()
origin = repo.remote()
if repo.head.is_detached:
raise click.UsageError('Your cannot merge from a detached HEAD.')
if repo.is_dirty():
raise click.UsageError('Your cannot merge, your repo is dirty.')
current_head = repo.head.ref.name
if current_head == target_branch:
raise click.UsageError('Your cannot merge on %s as your are already on it.')
try:
repo.branches[target_branch]
except IndexError:
raise click.UsageError('%r is not a local branch.' % target_branch)
try:
click.echo(u'Checking-out branch « %s » ... ' % target_branch, nl=False)
repo.branches[target_branch].checkout()
click.echo(click.style('Done.', fg='green'))
click.echo(u'Pull-rebasing from remote « %s » onto branch « %s » ... ' % (origin.name, target_branch), nl=False)
failure = False
for pi in origin.pull(rebase=True):
if pi.flags & pi.ERROR:
failure = True
click.echo(click.style(u'Pull-rebase from « %s » failed: %s.' % (
pi.ref.name, pi.note), fg='red'))
click.echo(click.style('Done.', fg='green'))
if failure:
raise click.ClickException('Pull rebase failed.')
finally:
click.echo(u'Checking-out branch « %s »... ' % current_head, nl=False)
repo.branches[current_head].checkout()
click.echo(click.style('Done.', fg='green'))
try:
click.echo(u'Rebasing branch « %s » onto branch « %s » ... ' % (current_head, target_branch), nl=False)
repo.git.rebase(target_branch)
except git.GitCommandError as e:
click.echo(click.style('command %r failed, aborting.' % e.command, fg='red'))
try:
repo.git.rebase(abort=True)
except git.GitCommandError as e:
click.echo(click.style('rebase abort failed, %s\n%s.' % (e.stdout, e.stderr), fg='red'))
raise click.Abort()
click.echo(click.style('Done.', fg='green'))
try:
click.echo('Checking-out to %s... ' % target_branch, nl=False)
repo.branches[target_branch].checkout()
click.echo(click.style('Done.', fg='green'))
click.echo(u'Merging branch « %s » into « %s » ... ' % (current_head, target_branch), nl=False)
try:
repo.git.merge(current_head, ff=True)
except git.GitCommandError as e:
click.echo(click.style('command %r failed, aborting.' % e.command, fg='red'))
try:
repo.git.merge(abort=True)
except git.GitCommandError as e:
click.echo(click.style('merge abort failed, %s\n%s.' % (e.stdout, e.stderr), fg='red'))
raise click.Abort()
click.echo(click.style('Done.', fg='green'))
try:
origin.refs[current_head]
except IndexError:
pass
else:
if click.confirm(u'Do you want to delete feature branch « %s » on remote « %s » ?' % (
current_head, origin.name)):
for pi in origin.push(refspec=':%s' % current_head):
if pi.flags & pi.ERROR:
click.echo(click.style(u'Push from « %s » to « %s » failed.' % (
pi.local_ref.name, pi.remote_ref.name, pi.summary), fg='red'))
if click.confirm(u'Do you want to push « %s » on remote « %s » ?' % (target_branch, repo.remote().name)):
for pi in origin.push():
if pi.flags & pi.ERROR:
click.echo(click.style(u'Push from « %s » to « %s » failed: %s.' % (
pi.local_ref.name, pi.remote_ref.name, pi.summary), fg='red'))
if click.confirm(u'Do you want to delete feature branch « %s » ?' % current_head):
repo.delete_head(repo.branches[current_head])
else:
repo.branches[current_head].checkout()
except Exception:
click.echo(click.style(u'\nFailure going back to branch « %s ».' % current_head, fg='red'))
repo.branches[current_head].checkout()
raise
@issue.command(name='open')
@click.option('--issue', default=None, type=int)
def _open(issue):
issue = get_issue(issue)
subprocess.call(['xdg-open', issue.url])
@project.command()
@click.argument('project_id')
def set(project_id):
@ -315,9 +421,9 @@ def set(project_id):
api = get_redmine_api()
try:
api.project.get(project_id)
except:
except Exception:
raise click.UsageError('Project %s is unknown' % project_id)
repo = git.Repo()
repo = get_repo()
config_writer = repo.config_writer()
if not config_writer.has_section('redmine'):
config_writer.add_section('redmine')