def status(): branch = git.current_branch() print "# On branch %s, tracking database %s" % (branch, database) tracked = [db[len(database):] for db in list_databases() if db.startswith(database)] tracked[tracked.index("")] = branch print "# Currently tracking local branches: %s" % tracked print "# Patches applied:" print "# %s" % list_applied_patches(branch, database) print "# Patches not applied:" print "# %s" % [patch for patch in list_file_patches(branch, database) if patch not in list_applied_patches(branch, database) and patch not in list_ignored_patches(branch, database)] print "# Patches ignored:" print "# %s" % list_ignored_patches(branch, database) print "# Patches stashed:" print "# %s" % list_stashed_patches(branch, database) last_commit = git.last_commit_time() if fast_check_sqlchanges(database, last_commit): with amalgamated_sql(branch, database) as amalgamated_sql_file: sql_difference = calculate_difference(amalgamated_sql_file, database, [filters.filter_auto_increment, lambda input: filters.filter_renames(input, database, git.last_commit_time())]) if sql_difference: print "# Untracked SQL code since last commit at '%s'." % (last_commit) else: print "# SQL database clean." else: print "# SQL database clean."
def checking_and_committing(args=sys.argv[1:]): from helpers import promise print "Checking if promise was kept..." if not promise.promise_exists(): kept_promise(args) return True promises = promise.read_promise() promise_kept = True error_message = None current_branch = git.current_branch() for promise in promises: if promise_kept: if promise[u'child'] == current_branch: promise_kept, error_message = check_promise(promise, False) elif promise[u'parent'] == current_branch: promise_kept, error_message = check_promise(promise, True) promise_kept = not promise_kept else: broken_promise(error_message) if promise_kept: kept_promise(args) return True else: broken_promise(error_message) return False
def fast_check_sqlchanges(database, start_datetime): # XXX: We need to implement branching support here # Could be tricky - basically whenever we switch branches (post-checkout hook), we will need to record # if there were pending changes (using this, maybe called with an argument) # Find the last significant event since start_datetime that would cause us to ignore # anything. For example, if a rollback occurred, there is no difference in data, yet # there have been binlog entries. events = list_events(database, start_datetime) for time_, event in events: if ( event == "rollback" or event == "branch-change" or event == "retrieve" or event == "merge" or event == "created" or event == "ignored sql, %s" % git.current_branch() ): # Small delay to account for SQL processing delays. start_datetime = datetime.datetime.fromtimestamp(time_ + 10) binlog = read_binlog(database, start_datetime) for line in binlog: if ( re.search(".*?alter ", line, flags=re.IGNORECASE) or re.search(".*?create ", line, flags=re.IGNORECASE) or re.search(".*?rename ", line, flags=re.IGNORECASE) or re.search(".*?drop ", line, flags=re.IGNORECASE) ): return True return False
def diff(): if fast_check_sqlchanges(database, git.last_commit_time()): with amalgamated_sql(git.current_branch(), database) as amalgamated_sql_file: sql_difference = calculate_difference(amalgamated_sql_file, database, [filters.filter_auto_increment, lambda input: filters.filter_renames(input, database, git.last_commit_time())]) if sql_difference: print sql_difference else: print "# SQL database clean." else: print "# SQL database clean."
def create_promise(args): hash_str = git.current_hash() parent = git.current_branch() if parent == "": raise Exception("Creating promise failed. Current branch has no name." " If repo is just initialized, create an initial commit.") # TODO: check if promise is allowed if in a promise branch (promise in a promsie) promise = {"hash": hash_str, "parent": parent, "child": args.newBranchName, "files": args.files} return promise
def unignore_patches(): branch = git.current_branch() if list_ignored_patches(branch, database): patches = dict([(i, patch) for i, patch in enumerate(list_ignored_patches(branch, database))]) pprint(patches) try: input = raw_input("Please enter a space separated list of patch #s to unignore: ") if input != "": to_unignore = [int(i) for i in input.split(" ")] for unignored in to_unignore: remove_ignored_from_db(git.current_branch(), database, patches[unignored]) except: print "Invalid input." return else: print "No patches to be unignored." add_event_to_db(database, "unignored patches, %s: ", time.time())
def ignore_patches(): # Mark certain patches as to be ignored / unignored. branch = git.current_branch() patches = dict([(i, patch) for i, patch in enumerate(list_file_patches(branch, database)) if patch not in list_applied_patches(branch, database) and patch not in list_ignored_patches(branch, database)]) if not patches: print "No patches to be ignored." return pprint(patches) try: input = raw_input("Please enter a space separated list of patch #s to ignore: ") if input != "": to_ignore = [int(i) for i in input.split(" ")] for ignored in to_ignore: add_ignored_to_db(git.current_branch(), database, patches[ignored]) except: print "Invalid input." return add_event_to_db(database, "ignored patches, %s: ", time.time())
def stash(): branch = git.current_branch() if args.unstash or args.delete: if list_stashed_patches(branch, database): patches = dict([(i, patch) for i, patch in enumerate(list_stashed_patches(branch, database))]) pprint(patches) try: input = raw_input("Please enter a space separated list of patch #s to unstash: " if args.unstash else "Please enter a space separated list of patch #s to delete: ") if input != "": to_unstash = [patches[int(i)] for i in input.split(" ")] for unstashed in to_unstash: if args.unstash: try: apply_patch(database, unstashed, True) remove_stashed_from_db(branch, database, unstashed) except MySqlException: print "Error applying stashed patch %s, not continuing" elif args.delete: # Delete the patch here. os.remove(unstashed) remove_stashed_from_db(branch, database, unstashed) except: print "Invalid input." return else: print "No stashed patches available for unstashing." if args.unstash else "No stashed patches available for deleting." if args.unstash: add_event_to_db(database, "unstashed patches, %s: ", time.time()) else: if fast_check_sqlchanges(database, git.last_commit_time()): print "Stashing all schema changes made on branch %s to database %s" % (branch, database) with amalgamated_sql(branch, database) as amalgamated_sql_file: base_dir = os.path.join(".git", "gitdb", "stashed", branch, database) patch_name = os.path.join(base_dir, free_patch_name()) makedirs(base_dir) sql_changes = calculate_difference(amalgamated_sql_file, database, [filters.filter_auto_increment, lambda input: filters.filter_renames(input, database, git.last_commit_time())]) if not sql_changes: print "No schema changes to stash." return else: print "Your SQL schema changes will be stashed in the file %s. You can use the git db stash command to manipulate them." % patch_name with open(patch_name, "w") as sql_patch: sql_patch.write(sql_changes) # Rollback the database to the last commit. temp_file = NamedTemporaryFile() sql_difference = calculate_difference(database, amalgamated_sql_file, [filters.filter_auto_increment, lambda input: filters.filter_renames(input, database, git.last_commit_time())]) temp_file.write(sql_difference) temp_file.flush() apply_patch(database, temp_file.name, True) temp_file.close() add_stashed_to_db(branch, database, patch_name) add_event_to_db(database, "stash", time.time()) else: print "No schema changes to stash."
def merge(): # Merge in unmerged development patches. from gitdb import handle_pull handle_pull(git.current_branch(), database) add_event_to_db(database, "merge", time.time())