def run_finish(args): gitflow = GitFlow() repo = gitflow.repo git = repo.git f_prefix = gitflow.get_prefix('feature') name = gitflow.nameprefix_or_current('feature', args.nameprefix) full_name = f_prefix + name #+++ PT story stuff sys.stdout.write('Getting data from Pivotal Tracker ... ') story_id = pivotal.get_story_id_from_branch_name('feature', name) story = pivotal.Story(story_id) release = story.get_release() print 'OK' # Decide on the upstream branch. if release: # Merge into the release branch. r_prefix = gitflow.get_prefix('release') short_name = gitflow.nameprefix_or_current('release', release) upstream = r_prefix + short_name else: # Merge into the develop branch. upstream = gitflow.develop_name() # Fail as soon as possible if something is not right so that we don't # get Pivotal Tracker into an inconsistent state. rev_range = [get_feature_ancestor(full_name, upstream), repo.commit(full_name).hexsha] #+++ Git manipulation sys.stdout.write('Finishing feature branch ... upstream %s ... ' \ % upstream) gitflow.finish('feature', name, upstream=upstream, fetch=True, rebase=args.rebase, keep=True, force_delete=args.force_delete, tagging_info=None, push=(not args.no_push)) print 'OK' #+++ Review Request if not args.no_review: sys.stdout.write('Posting review ... upstream %s ... ' % upstream) review = BranchReview.from_identifier('feature', name, rev_range) review.post(story, summary_from_story=(not args.summary_from_commit)) print('OK') sys.stdout.write('Posting code review url into Pivotal Tracker ... ') comment = 'New patch was uploaded into Review Board: ' + review.get_url() story.add_comment(comment) print('OK') #+++ Finish PT story sys.stdout.write('Updating Pivotal Tracker ... ') if story.is_finished(): sys.stdout.write('story already finished, skipping ... ') else: sys.stdout.write('finishing %s ... ' % story.get_id()) story.finish() print 'OK'
def test_finish_in_new_sandbox_without_commit(self): sandbox = create_sandbox(self) gitflow = GitFlow(sandbox).init() gitflow.create('feature', 'wow-feature', base=None, fetch=False) gitflow.finish('feature', 'wow-feature', False, False, False, False, None) self.assertNotIn('feature/wow-feature', gitflow.repo.branches)
def test_finish_unresolved_merge_conflict(self): gitflow = GitFlow(self.repo).init() gitflow.finish('feature', 'recursion', False, False, False, False, None) self.assertRaises(MergeError, gitflow.finish, 'feature', 'even', False, False, False, False, None) # do not resolve, but finish again self.assertRaises(Usage, gitflow.finish, 'feature', 'even', False, False, False, False, None)
def test_finish_in_new_sandbox(self): sandbox = create_sandbox(self) gitflow = GitFlow(sandbox).init() gitflow.create('feature', 'wow-feature', base=None, fetch=False) self.assertEqual(gitflow.repo.active_branch.name, 'feature/wow-feature') fake_commit(gitflow.repo, 'Yet another commit') gitflow.finish('feature', 'wow-feature', False, False, False, False, None) self.assertNotIn('feature/wow-feature', gitflow.repo.branches)
def run_finish(args): gitflow = GitFlow() name = gitflow.nameprefix_or_current('feature', args.nameprefix) gitflow.start_transaction('finishing feature branch %s' % name) gitflow.finish('feature', name, fetch=args.fetch, rebase=args.rebase, keep=args.keep, force_delete=args.force_delete, tagging_info=None)
def _release_version_with_git_flow(version_tag): from os import curdir from gitflow.core import GitFlow from gitpy import LocalRepository gitflow = GitFlow() gitflow.create("release", version_tag, base=None, fetch=False) gitflow.finish("release", version_tag, fetch=False, rebase=False, keep=False, force_delete=True, tagging_info=dict(sign=False, message=version_tag)) repository = LocalRepository(curdir)
def _release_version_with_git_flow(version_tag): from gitflow.core import GitFlow gitflow = GitFlow() gitflow.create("release", version_tag, base=None, fetch=False) gitflow.finish("release", version_tag, fetch=False, rebase=False, keep=False, force_delete=True, tagging_info=dict(sign=False, message=version_tag))
def run_finish(args): gitflow = GitFlow() version = gitflow.name_or_current('hotfix', args.version) gitflow.start_transaction('finishing hotfix branch %s' % version) tagging_info = None if not args.notag: tagging_info = dict( sign=args.sign or args.signingkey, signingkey=args.signingkey, message=args.message) gitflow.finish( 'hotfix', version, fetch=args.fetch, rebase=False, keep=args.keep, force_delete=False, tagging_info=tagging_info)
def run_finish(args): gitflow = GitFlow() version = gitflow.name_or_current('hotfix', args.version) gitflow.start_transaction('finishing hotfix branch %s' % version) tagging_info = None if not args.notag: tagging_info = dict(sign=args.sign or args.signingkey, signingkey=args.signingkey, message=args.message) gitflow.finish('hotfix', version, fetch=args.fetch, rebase=False, keep=args.keep, force_delete=False, tagging_info=tagging_info)
def test_finish_fetch_does_not_change_repo(self): remote = GitFlow(self.remote).init() rc0 = remote.develop().commit gitflow = GitFlow(self.repo).init() c0 = gitflow.develop().commit self.assertEqual(rc0, c0) gitflow.create('feature', 'wow-feature', base=None, fetch=False) c1 = gitflow.develop().commit self.assertEqual(c0, c1) gitflow.finish('feature', 'wow-feature', True, False, False, False, None) c2 = gitflow.develop().commit self.assertEqual(c0, c2) fh = self.__get_fetch_head(self.repo) self.assertEqual(fh, c0)
def test_finish_fetch_fetches_from_remote(self): remote = GitFlow(self.remote).init() rc0 = remote.develop().commit gitflow = GitFlow(self.repo).init() c0 = gitflow.develop().commit self.assertEqual(rc0, c0) gitflow.create('feature', 'wow-feature', base=None, fetch=False) c1 = gitflow.develop().commit self.assertEqual(c0, c1) fake_commit(gitflow.repo, 'Yet another commit') gitflow.finish('feature', 'wow-feature', True, False, False, False, None) c2 = gitflow.develop().commit self.assertNotEqual(c0, c2) fh = self.__get_fetch_head(self.repo) self.assertEqual(fh, c0) self.assertNotEqual(fh, c2)
def run_finish(args): gitflow = GitFlow() repo = gitflow.repo git = repo.git f_prefix = gitflow.get_prefix('feature') name = gitflow.nameprefix_or_current('feature', args.nameprefix) full_name = f_prefix + name #+++ PT story stuff sys.stdout.write('Getting data from Pivotal Tracker ... ') story_id = pivotal.get_story_id_from_branch_name('feature', name) story = pivotal.Story(story_id) release = story.get_release() print 'OK' # Decide on the upstream branch. if release: # Merge into the release branch. r_prefix = gitflow.get_prefix('release') short_name = gitflow.nameprefix_or_current('release', release) upstream = r_prefix + short_name else: # Merge into the develop branch. upstream = gitflow.develop_name() # Fail as soon as possible if something is not right so that we don't # get Pivotal Tracker into an inconsistent state. rev_range = [ get_feature_ancestor(full_name, upstream), repo.commit(full_name).hexsha ] #+++ Git manipulation sys.stdout.write('Finishing feature branch ... upstream %s ... ' \ % upstream) gitflow.finish('feature', name, upstream=upstream, fetch=True, rebase=args.rebase, keep=True, force_delete=args.force_delete, tagging_info=None, push=(not args.no_push)) print 'OK' #+++ Review Request if not args.no_review: sys.stdout.write('Posting review ... upstream %s ... ' % upstream) review = BranchReview.from_identifier('feature', name, rev_range) review.post(story, summary_from_story=(not args.summary_from_commit)) print('OK') sys.stdout.write( 'Posting code review url into Pivotal Tracker ... ') comment = 'New patch was uploaded into Review Board: ' + review.get_url( ) story.add_comment(comment) print('OK') #+++ Finish PT story sys.stdout.write('Updating Pivotal Tracker ... ') if story.is_finished(): sys.stdout.write('story already finished, skipping ... ') else: sys.stdout.write('finishing %s ... ' % story.get_id()) story.finish() print 'OK'
def run_finish(args): gitflow = GitFlow() git = gitflow.git origin = gitflow.origin() version = gitflow.name_or_current('release', args.version) #+++ Check if all stories were QA'd pt_release = pivotal.Release(args.version) print('Checking Pivotal Tracker stories ... ') pt_release.try_finish() print('OK') #+++ Check all relevant review requests in Review Board, to be sure rb_release = review.Release(pt_release) print('Checking Review Board review requests ... ') rb_release.try_finish(args.ignore_missing_reviews) print('OK') #+++ Merge release branch into develop and master sys.stdout.write('Merging release branch %s ... ' % version) tagging_info = None if not args.notag: tagging_info = dict( sign=args.sign or args.signingkey, signingkey=args.signingkey, message=args.message) gitflow.finish('release', version, fetch=(not args.no_fetch), rebase=False, keep=True, force_delete=False, tagging_info=tagging_info, push=False) print('OK') #+++ Close all relevant review requests sys.stdout.write('Submitting all relevant review requests ... ') rb_release.finish() print('OK') #+++ Collect local and remote branches to be deleted sys.stdout.write('Collecting branches to be deleted ... ') local_branches = list() remote_branches = list() #+ Collect features to be deleted. origin_prefix = str(origin) + '/' feature_prefix = gitflow.get_prefix('feature') # refs = [<type>/<id>/...] refs = [str(ref)[len(origin_prefix):] for ref in origin.refs] for story in pt_release: if story.is_rejected(): continue # prefix = <feature-prefix>/<id> prefix = feature_prefix + str(story.get_id()) base_marker = gitflow.managers['feature'].base_marker_name(prefix) try: name = gitflow.nameprefix_or_current('feature', prefix) local_branches.append(feature_prefix + name) if base_marker in gitflow.repo.refs: local_branches.append(base_marker) except NoSuchBranchError: pass for ref in refs: # if <feature-prefix>/... startswith <feature-prefix>/<id> if ref.startswith(prefix) or ref == base_marker: remote_branches.append(ref) #+ Collect releases to be deleted. if not args.keep: release_branch = gitflow.get_prefix('release') + version try: gitflow.name_or_current('release', version) local_branches.append(release_branch) except NoSuchBranchError: pass if release_branch in refs: remote_branches.append(release_branch) print 'OK' #+++ Delete local and remote branches that are a part of this release sys.stdout.write('Checking out %s ... ' % gitflow.develop_name()) git.checkout(gitflow.develop_name()) print 'OK' #+ Delete local branches. print 'Deleting local branches ...' for branch in local_branches: git.branch('-D', branch) print ' ' + branch print ' OK' #+ Delete remote branches. print 'Deleting remote branches and pushing the rest ...' for branch in remote_branches: print ' ' + branch refspecs = [(':' + b) for b in remote_branches] refspecs.append(gitflow.develop_name()) refspecs.append(gitflow.master_name()) git.push(str(origin), '--tags', *refspecs) print ' OK'
def run_finish(args): gitflow = GitFlow() git = gitflow.git origin = gitflow.origin() version = gitflow.name_or_current('release', args.version) #+++ Check if all stories were QA'd pt_release = pivotal.Release(args.version) print('Checking Pivotal Tracker stories ... ') pt_release.try_finish() print('OK') #+++ Check all relevant review requests in Review Board, to be sure rb_release = review.Release(pt_release) print('Checking Review Board review requests ... ') rb_release.try_finish(args.ignore_missing_reviews) print('OK') #+++ Merge release branch into develop and master sys.stdout.write('Merging release branch %s ... ' % version) tagging_info = None if not args.notag: tagging_info = dict(sign=args.sign or args.signingkey, signingkey=args.signingkey, message=args.message) gitflow.finish('release', version, fetch=(not args.no_fetch), rebase=False, keep=True, force_delete=False, tagging_info=tagging_info, push=False) print('OK') #+++ Close all relevant review requests sys.stdout.write('Submitting all relevant review requests ... ') rb_release.finish() print('OK') #+++ Collect local and remote branches to be deleted sys.stdout.write('Collecting branches to be deleted ... ') local_branches = list() remote_branches = list() #+ Collect features to be deleted. origin_prefix = str(origin) + '/' feature_prefix = gitflow.get_prefix('feature') # refs = [<type>/<id>/...] refs = [str(ref)[len(origin_prefix):] for ref in origin.refs] for story in pt_release: if story.is_rejected(): continue # prefix = <feature-prefix>/<id> prefix = feature_prefix + str(story.get_id()) base_marker = gitflow.managers['feature'].base_marker_name(prefix) try: name = gitflow.nameprefix_or_current('feature', prefix) local_branches.append(feature_prefix + name) if base_marker in gitflow.repo.refs: local_branches.append(base_marker) except NoSuchBranchError: pass for ref in refs: # if <feature-prefix>/... startswith <feature-prefix>/<id> if ref.startswith(prefix) or ref == base_marker: remote_branches.append(ref) #+ Collect releases to be deleted. if not args.keep: release_branch = gitflow.get_prefix('release') + version try: gitflow.name_or_current('release', version) local_branches.append(release_branch) except NoSuchBranchError: pass if release_branch in refs: remote_branches.append(release_branch) print 'OK' #+++ Delete local and remote branches that are a part of this release sys.stdout.write('Checking out %s ... ' % gitflow.develop_name()) git.checkout(gitflow.develop_name()) print 'OK' #+ Delete local branches. print 'Deleting local branches ...' for branch in local_branches: git.branch('-D', branch) print ' ' + branch print ' OK' #+ Delete remote branches. print 'Deleting remote branches and pushing the rest ...' for branch in remote_branches: print ' ' + branch refspecs = [(':' + b) for b in remote_branches] refspecs.append(gitflow.develop_name()) refspecs.append(gitflow.master_name()) git.push(str(origin), '--tags', *refspecs) print ' OK'