def commit(self, page, message='', author=None, parent=None, extra_path=None): path = page.path paths_to_commit = [path] if extra_path: paths_to_commit.append(extra_path) kwargs = {} User = get_user_model() if isinstance(author, User) and author.is_authenticated(): kwargs['author'] = u"%s <%s>" % (author.get_full_name() or author.username, author.email) elif isinstance(author, six.string_types): kwargs['author'] = author try: there_were_changes = parent and parent != self.last_version(page) status = git.status('--porcelain', path).stdout.decode('utf8')[:2] if parent and status != "UU": git.stash() git.checkout('--detach', parent) try: git.stash('pop') except: git.checkout('--theirs', path) if status == 'UU': # See http://stackoverflow.com/a/8062976/811740 kwargs['i'] = True git.add(path) git_commit_cmd = git.commit.bake(allow_empty=True, allow_empty_message=True, m=message, **kwargs) git_commit_cmd('--', *paths_to_commit) last = self.last_version(page) if parent and status != "UU": git.checkout('master') git.merge(last) except ErrorReturnCode as e: # TODO: make this more robust! error = e.stdout.decode('utf8') if 'CONFLICT' in error: # For '-i' attribute see http://stackoverflow.com/q/5827944/811740 git_commit_cmd = git.commit.bake(allow_empty=True, allow_empty_message=True, m=_('Merged with conflict'), i=True, **kwargs) git_commit_cmd('--', *paths_to_commit) raise Page.EditionConflict( _('Automatic merge failed. Please, fix the conflict and save the page.' )) else: raise return there_were_changes
def rollback(self, paths, msg="Rolling-Back"): """ Rollback last commit to restore previous. configuration and commit changes automatically """ for path in paths: global git git = git.bake("--git-dir={0}/.git".format(path), "--work-tree={0}".format(path)) if os.path.isdir(path): if not os.path.isdir(path + "/.git"): Log.error( self, "Unable to find a git repository at {0}".format(path)) try: Log.debug( self, "WOGit: git stash --include-untracked at {0}".format( path)) git.stash("push", "--include-untracked", "-m {0}".format(msg)) except ErrorReturnCode as e: Log.debug(self, "{0}".format(e)) Log.error(self, "Unable to git reset at {0} ".format(path)) else: Log.debug(self, "WOGit: Path {0} not present".format(path))
def prepare(self): modified = re.compile('^[MA]\s+(?P<name>.*)$') self.files = [] mod_files = git.status('--porcelain') for mod_file in mod_files.splitlines(): match = modified.match(mod_file) if match: self.files.append(match.group('name')) print highlight('Stashing all untracked changes...') git.stash('--include-untracked', '--keep-index')
def post_run(self): git.reset('--hard') try: # This hook can be called by a simple git commit --amend # without anything to actually get from the stash. In this # case, this command will break and we can safely ignore it. git.stash('pop', '--quiet', '--index') except Exception: pass sys.exit(self.result)
def update(conf, args): '''Apply updates from the upstream repository.''' print('Checking for updates...') # fetch changes from the canonical repo git.fetch(constants.GIT_REMOTE, no_tags=True, quiet=True) # get a list of the commit messages for the incoming changes updates = git('--no-pager', 'log', '..FETCH_HEAD', oneline=True) updates = [tuple(m.split(None, 1)) for m in updates.splitlines()] # print out a list of the incoming updates if len(updates) > 0: print('Available updates:') max_updates = 10 for commit, msg in updates[:max_updates]: print(color.yellow('*'), msg) # print a special message if too many updates are available if len(updates) > max_updates: print('...and', color.green(len(updates) - max_updates), 'more!') print('Run `git log ..FETCH_HEAD` to see the full list') # bail if we have uncommitted changes (git exits non-0 in this case) if git.diff(exit_code=True, quiet=True, _ok_code=(0, 1)).exit_code != 0: raise ValueError('The repository has uncommitted changes. Handle them, ' 'then try updating again.') print('Applying the update...') # stash _all_ changes to the repo git.stash(include_untracked=True, all=True, quiet=True) # squash all the fetched commits together and merge them into master git.merge('@{u}', squash=True, quiet=True) # add a nice update commit that includes the latest upstream commit hash commit_message = 'Update dotparty to %s' % updates[0][0] git.commit(m=commit_message, quiet=True) # TODO: if squash merge failed, roll back to the pre-update state and # complain with instructions for the user to do their own update. # un-stash all our old changes git.stash('pop', quiet=True) # push our changes back up to the remote git.push(quiet=True) print('Update successful!') else: print('Already up-to-date!')
def write_study(self, study_id, content, branch, author="OpenTree API <*****@*****.**>"): """Write a study Given a study_id, content, branch and optionally an author, write a study on the given branch and attribute the commit to author. If the branch does not yet exist, it will be created. If the study is being created, it's containing directory will be created as well. Returns the SHA of the new commit on branch. """ os.chdir(self.repo) # If there are uncommitted changes to our repo, stash them so this commit can proceed git.stash() if self.branch_exists(branch): git.checkout(branch) else: # Create this new branch off of master, NOT the currently-checked out branch! git.checkout("master") git.checkout("-b", branch) study_dir = "study/%s" % study_id study_filename = "%s/%s.json" % (study_dir, study_id) # create a study directory if this is a new study if not os.path.isdir(study_dir): os.mkdir(study_dir) file = open(study_filename, 'w') file.write(content) file.close() git.add(study_filename) git.commit(author=author, message="Update Study #%s via OpenTree API" % study_id) new_sha = git("rev-parse", "HEAD") return new_sha.strip()
def main(all_files=False): git.stash(u=True, keep_index=True) try: results = nosetests('cardscript/', with_doctest=True) result = True except sh.ErrorReturnCode as exc: # If anything goes wrong, let us know, but abandon the commit. git.reset(hard=True) # Code is wrong, reset it. print("ERROR: Tests FAILED; Commit ABORTED.") print(exc.stderr) result = False finally: git.stash('pop', q=True) # Restore anything in our working directory. return result
def commit(self, page, message="", author=None, parent=None, extra_path=None): path = page.path paths_to_commit = [path] if extra_path: paths_to_commit.append(extra_path) kwargs = {} if isinstance(author, User) and author.is_authenticated(): kwargs["author"] = u"%s <%s>" % (author.get_full_name() or author.username, author.email) elif isinstance(author, six.string_types): kwargs["author"] = author try: there_were_changes = parent and parent != self.last_version(page) status = git.status("--porcelain", path).stdout.decode("utf8")[:2] if parent and status != "UU": git.stash() git.checkout("--detach", parent) try: git.stash("pop") except: git.checkout("--theirs", path) if status == "UU": # See http://stackoverflow.com/a/8062976/811740 kwargs["i"] = True git.add(path) git_commit_cmd = git.commit.bake(allow_empty=True, allow_empty_message=True, m=message, **kwargs) git_commit_cmd("--", *paths_to_commit) last = self.last_version(page) if parent and status != "UU": git.checkout("master") git.merge(last) except ErrorReturnCode as e: # TODO: make this more robust! error = e.stdout.decode("utf8") if "CONFLICT" in error: # For '-i' attribute see http://stackoverflow.com/q/5827944/811740 git_commit_cmd = git.commit.bake( allow_empty=True, allow_empty_message=True, m=_("Merged with conflict"), i=True, **kwargs ) git_commit_cmd("--", *paths_to_commit) raise Page.EditionConflict(_("Automatic merge failed. Please, fix the conflict and save the page.")) else: raise return there_were_changes
def stash(self): o = git.stash() if o.exit_code != 0: raise RepositoryException("Failed to stash in git repo: {}".format( o)) return True
def commit(self, page, message='', author=None, parent=None, extra_path=None): path = page.path paths_to_commit = [path] if extra_path: paths_to_commit.append(extra_path) kwargs = {} User = get_user_model() if isinstance(author, User) and is_authenticated(author): kwargs['author'] = u"%s <%s>" % (author.get_full_name() or author.username, author.email) elif isinstance(author, six.string_types): kwargs['author'] = author try: there_were_changes = parent and parent != self.last_version(page) status = git.status('--porcelain', path).stdout.decode('utf8')[:2] if parent and status != "UU": git.stash() git.checkout('--detach', parent) try: git.stash('pop') except: git.checkout('--theirs', path) if status == 'UU': # See http://stackoverflow.com/a/8062976/811740 kwargs['i'] = True git.add(path) git_commit_cmd = git.commit.bake(allow_empty=True, allow_empty_message=True, m=message, **kwargs) git_commit_cmd('--', *paths_to_commit) last = self.last_version(page) if parent and status != "UU": git.checkout('master') git.merge(last) except ErrorReturnCode as e: # TODO: make this more robust! error = e.stdout.decode('utf8') if 'CONFLICT' in error: # For '-i' attribute see http://stackoverflow.com/q/5827944/811740 git_commit_cmd = git.commit.bake(allow_empty=True, allow_empty_message=True, m=_('Merged with conflict'), i=True, **kwargs) git_commit_cmd('--', *paths_to_commit) raise Page.EditionConflict(_('Automatic merge failed. Please, fix the conflict and save the page.')) else: raise return there_were_changes
def stash(self): o = git.stash() if o.exit_code != 0: raise RepositoryException( "Failed to stash in git repo: {}".format(o)) return True
def write_study(self,study_id, content, branch, author="OpenTree API <*****@*****.**>"): """Write a study Given a study_id, content, branch and optionally an author, write a study on the given branch and attribute the commit to author. If the branch does not yet exist, it will be created. If the study is being created, it's containing directory will be created as well. Returns the SHA of the new commit on branch. """ os.chdir(self.repo) # If there are uncommitted changes to our repo, stash them so this commit can proceed git.stash() if self.branch_exists(branch): git.checkout(branch) else: # Create this new branch off of master, NOT the currently-checked out branch! git.checkout("master") git.checkout("-b",branch) study_dir = "study/%s" % study_id study_filename = "%s/%s.json" % (study_dir, study_id) # create a study directory if this is a new study if not os.path.isdir(study_dir): os.mkdir(study_dir) file = open(study_filename, 'w') file.write(content) file.close() git.add(study_filename) git.commit(author=author, message="Update Study #%s via OpenTree API" % study_id) new_sha = git("rev-parse","HEAD") return new_sha.strip()
def commit(self, page, message='', author=None, parent=None): path = page.path kwargs = {} if isinstance(author, User) and author.is_authenticated(): kwargs['author'] = u"%s <%s>" % (author.get_full_name() or author.username, author.email) elif isinstance(author, six.string_types): kwargs['author'] = author try: there_were_changes = parent and parent != self.last_version(page) status = git.status('--porcelain', path).stdout.decode('utf8')[:2] if parent and status != "UU": git.stash() git.checkout('--detach', parent) try: git.stash('pop') except: git.checkout('--theirs', path) if status == 'UU': # See http://stackoverflow.com/a/8062976/811740 kwargs['i'] = True git.add(path) git.commit(path, allow_empty_message=True, m=message, **kwargs) last = self.last_version(page) if parent and status != "UU": git.checkout('master') git.merge(last) except ErrorReturnCode as e: # TODO: make this more robust! error = e.stdout.decode('utf8') if 'CONFLICT' in error: raise Page.EditionConflict(_('Automatic merge failed. Please, fix the conflict and save the page.')) else: raise return there_were_changes
def release(): """Release/publish the documentation to the webpage. """ # Save the current state. branch = git('rev-parse', '--abbrev-ref', 'HEAD').stdout.rstrip() git.stash('save', "Work in progress while updating gh-pages branch") # Check out the gh-pages branch. try: git.checkout('gh-pages') except ErrorReturnCode_128: # Create the branch if necessary. git.checkout('-b', 'gh-pages') # Remove the existing files in the base folder. extensions = ['*.html', '*.inv'] fnames = util.multiglob('..', extensions) for fname in fnames: os.remove(fname) # Copy the new files to the base folder. fnames = util.multiglob(BUILD_DIR, extensions) for fname in fnames: shutil.copy(fname, '..') # Track the new files. fnames = util.multiglob('..', extensions) git.add(*fnames) # Copy but rename the folders referenced in the HTML files. # Github only recognizes images, stylesheets, and javascripts as folders. folders = [('_images', 'images'), ('_static', 'javascripts'), ] for (src, dst) in folders: dst = os.path.join('..', dst) # Remove the existing folder. shutil.rmtree(dst, ignore_errors=True) # Copy the new folder. shutil.copytree(os.path.join(BUILD_DIR, src), dst) # Track the new folder. git.add(dst) # Update the HTML files to reference the new folder names. html_fnames = glob(os.path.join('..', '*.html')) util.replace(html_fnames, folders) # Copy and rename the examples folder. src = os.path.join(BUILD_DIR, 'examples') dst = '../examples2' # Remove the existing folder. shutil.rmtree(dst, ignore_errors=True) # Copy the new files. os.mkdir(dst) for fname in os.listdir(src): shutil.copy(os.path.join(src, fname), os.path.join(dst, fname)) # Track the new folder. git.add(dst) # Update the HTML files to reference the new folder names. util.replace(html_fnames, [(r'"\./examples/', r'"./examples2/')]) # Update the sitemap. print(python('sitemap_gen.py', config="sitemap_conf.xml")) # Commit the changes. try: git.commit('-a', m="Rebuilt documentation") except ErrorReturnCode_1: pass # No changes to commit # If desired, rebase and push the changes to origin. print("The gh-pages branch has been updated and is currently checked out.") if util.yes("Do you want to rebase it and push the changes to " "origin (y/n)?"): git.rebase('-i', 'origin/gh-pages') git.push.origin('gh-pages') # Return to the original state. git.checkout(branch) try: git.stash.pop() except ErrorReturnCode_1: pass # No stash was necessary in the first place. print("Now back on " + branch)
versions = json.load(open('versions.json')) dir_names = [] try: rmtree('tmp') except: pass os.makedirs('tmp') sphinx_build = Command('sphinx-build') if args.stash: git.stash() for name, options in versions.items(): print 'Generating docs for version ' + name try: git.checkout(options['branch_name']) print 'Checked out "' + options['branch_name'] + '"' # Print latest commit print git('--no-pager', 'log', '-1') os.environ['CHAOS_DOC_VERSION'] = name sphinx_build('-b', 'html', '-a', '-E', 'source', 'tmp/' + options['directory_name']) del os.environ['CHAOS_DOC_VERSION'] dir_names.append(options['directory_name'])
def release(): """Release/publish the documentation to the webpage. """ # Save the current state. branch = git('rev-parse', '--abbrev-ref', 'HEAD').stdout.rstrip() git.stash('save', "Work in progress while updating gh-pages branch") # Check out the gh-pages branch. try: git.checkout('gh-pages') except ErrorReturnCode_128: # Create the branch if necessary. git.checkout('-b', 'gh-pages') # Remove the existing files in the base folder. extensions = ['*.html', '*.inv'] fnames = util.multiglob('..', extensions) for fname in fnames: os.remove(fname) # Copy the new files to the base folder. fnames = util.multiglob(BUILD_DIR, extensions) for fname in fnames: shutil.copy(fname, '..') # Track the new files. fnames = util.multiglob('..', extensions) git.add(*fnames) # Copy but rename the folders referenced in the HTML files. # Github only recognizes images, stylesheets, and javascripts as folders. folders = [ ('_images', 'images'), ('_static', 'javascripts'), ] for (src, dst) in folders: dst = os.path.join('..', dst) # Remove the existing folder. shutil.rmtree(dst, ignore_errors=True) # Copy the new folder. shutil.copytree(os.path.join(BUILD_DIR, src), dst) # Track the new folder. git.add(dst) # Update the HTML files to reference the new folder names. html_fnames = glob(os.path.join('..', '*.html')) util.replace(html_fnames, folders) # Copy and rename the examples folder. src = os.path.join(BUILD_DIR, 'examples') dst = '../examples2' # Remove the existing folder. shutil.rmtree(dst, ignore_errors=True) # Copy the new files. os.mkdir(dst) for fname in os.listdir(src): shutil.copy(os.path.join(src, fname), os.path.join(dst, fname)) # Track the new folder. git.add(dst) # Update the HTML files to reference the new folder names. util.replace(html_fnames, [(r'"\./examples/', r'"./examples2/')]) # Update the sitemap. print((python('sitemap_gen.py', config="sitemap_conf.xml"))) # Commit the changes. try: git.commit('-a', m="Rebuilt documentation") except ErrorReturnCode_1: pass # No changes to commit # If desired, rebase and push the changes to origin. print("The gh-pages branch has been updated and is currently checked out.") if util.yes("Do you want to rebase it and push the changes to " "origin (y/n)?"): git.rebase('-i', 'origin/gh-pages') git.push.origin('gh-pages') # Return to the original state. git.checkout(branch) try: git.stash.pop() except ErrorReturnCode_1: pass # No stash was necessary in the first place. print(("Now back on " + branch))
versions = json.load(open('versions.json')) dir_names = [] try: rmtree('tmp') except: pass os.makedirs('tmp') sphinx_build = Command('sphinx-build') if args.stash: git.stash() for name, options in versions.items(): print 'Generating docs for version ' + name try: git.checkout(options['branch_name']) print 'Checked out "' + options['branch_name'] + '"' # Print latest commit print git('--no-pager', 'log', '-1') os.environ['CHAOS_DOC_VERSION'] = name sphinx_build('-b', 'html', '-a', '-E', 'source', 'tmp/' + options['directory_name']) del os.environ['CHAOS_DOC_VERSION'] dir_names.append(options['directory_name']) except: