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:
parent
7279e690b8
commit
85a851f119
110
git_redmine.py
110
git_redmine.py
|
@ -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')
|
||||
|
|
Loading…
Reference in New Issue