Beispiel #1
0
def in_git_repo():
    try:
        git.status()
    except ErrorReturnCode_128:
        return False
    else:
        return True
Beispiel #2
0
def update():
    """Update all submodules to Github versions"""
    if _is_dirty():
        sys.exit("Repo must be in clean state before updating. Please commit changes.")
    git.submodule.update(remote=True, rebase=True)
    if _is_dirty():
        print "Updated repositories:"
        print git.status(porcelain=True).strip()
        git.add(all=True)
        git.commit(m="Update submodules to origin")
    else:
        sys.exit('Nothing to update.')
Beispiel #3
0
def update():
    """Update all submodules to Github versions"""
    if _is_dirty():
        sys.exit(
            "Repo must be in clean state before updating. Please commit changes."
        )
    git.submodule.update(remote=True, rebase=True)
    if _is_dirty():
        print "Updated repositories:"
        print git.status(porcelain=True).strip()
        git.add(all=True)
        git.commit(m="Update submodules to origin")
    else:
        sys.exit('Nothing to update.')
Beispiel #4
0
        def assert_status_performance():
            # The test fails if `gl status` takes more than 100 times
            # the time `git status` took.
            MAX_TOLERANCE = 100

            t = time.time()
            gl.status()
            gl_t = time.time() - t

            t = time.time()
            git.status()
            git_t = time.time() - t

            self.assertTrue(gl_t < git_t * MAX_TOLERANCE,
                            msg='gl_t {0}, git_t {1}'.format(gl_t, git_t))
Beispiel #5
0
    def assert_status_performance():
      # The test fails if `gl status` takes more than 100 times
      # the time `git status` took.
      MAX_TOLERANCE = 100

      t = time.time()
      gl.status()
      gl_t = time.time() - t

      t = time.time()
      git.status()
      git_t = time.time() - t

      self.assertTrue(
          gl_t < git_t*MAX_TOLERANCE,
          msg='gl_t {0}, git_t {1}'.format(gl_t, git_t))
Beispiel #6
0
    def status(self):
        if self.git and self.link is None:
            # git repo, check it exists & isn't dirty
            if not os.path.exists(self.path):
                LOG.info("ERROR book {0} from {1} doesn't exist.".format(
                    self.path,
                    self.git))
            else:
                # chdir to the book & run `git status`
                cwd = os.getcwd()
                os.chdir(self.path)
                if self._check_branch():
                    git_status = git.status()
                    if "nothing to commit, working directory clean" in git_status:
                        LOG.info("# book {0} OK".format(self.path))
                    else:
                        LOG.info("# book {0}".format(self.path))
                        LOG.info(git_status)
                os.chdir(cwd)

        elif self.link and self.git is None:
            # check the link points to the correct location
            if self._check_link():
                LOG.info('# book {0} correctly points to {1}'.format(self.path, self.link))
            else:
                link_target = os.readlink(self.path)
                LOG.error('ERROR: {0} should point to {1}, it points to {2}'.format(self.path, self.link, link_target))

        else:
            LOG.error('Unknown book type: {0}'.format(self.path))
Beispiel #7
0
    def status(self):
        """Get status on the repo.
        :return:
        :rtype:
        """

        rd = self.repo_dir

        logger.debug("pkg path %s", rd)
        if not rd:
            print(
                "unable to find pkg '%s'. %s" % (self.name, did_u_mean(self.name))
            )

        cwd = os.getcwd()
        os.chdir(self.repo_dir)
        logger.debug("cwd: %s, getting status %s ", cwd, self.repo_dir)
        try:
            p = git.status(_out=self._sh_stdout('blue'),
                           _err=self._sh_stderr('red'))
            p.wait()
        except Exception:
            pass
            # logger.warn(e)
        os.chdir(cwd)
Beispiel #8
0
 def add(self, paths, msg="Intializating"):
     """
         Initializes Directory as repository if not already git repo.
         and adds uncommited 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"):
                 try:
                     Log.debug(self, "EEGit: git init at {0}".format(path))
                     git.init(path)
                 except ErrorReturnCode as e:
                     Log.debug(self, "{0}".format(e))
                     Log.error(self,
                               "Unable to git init at {0}".format(path))
             status = git.status("-s")
             if len(status.splitlines()) > 0:
                 try:
                     Log.debug(self,
                               "EEGit: git commit at {0}".format(path))
                     git.add("--all")
                     git.commit("-am {0}".format(msg))
                 except ErrorReturnCode as e:
                     Log.debug(self, "{0}".format(e))
                     Log.error(self,
                               "Unable to git commit at {0} ".format(path))
         else:
             Log.debug(self, "EEGit: Path {0} not present".format(path))
Beispiel #9
0
    def test_concurrent_edition_with_conflict(self):
        self.page.raw = "- item1"
        Git().commit(self.page, message="original")
        response1 = self.client.get(self.edit_url)
        response2 = self.client.get(self.edit_url)

        data1 = response1.context[0]['form'].initial
        data1["raw"] = '- item2'
        data1["message"] = "add item2"

        data2 = response2.context[0]['form'].initial
        data2["raw"] = '- item0'
        data1["message"] = "add item0"
        r = self.client.post(self.edit_url, data1)
        self.assertRedirects(r, reverse('waliki_detail', args=(self.page.slug,)))
        r = self.client.post(self.edit_url, data2)
        self.assertRedirects(r, self.edit_url)

        self.assertEqual('', git.status('--porcelain', self.page.path).stdout.decode('utf8'))
        self.assertIn('Merged with conflict', git.log("--no-color", "--pretty=format:%s", "-n 1", self.page.path).stdout.decode('utf8'))
        self.assertRegexpMatches(self.page.raw,'<<<<<<< HEAD\n- item2\n=======\n- item0\n>>>>>>> [0-9a-f]{7}\n')

        # can edit in conflict
        response = self.client.get(self.edit_url)
        data1 = response.context[0]['form'].initial
        data1["raw"] = '- item0\n- item2'
        data1["message"] = "fixing :)"
        response = self.client.post(self.edit_url, data1)
        self.assertRedirects(response, reverse('waliki_detail', args=(self.page.slug,)))
        self.assertEqual(self.page.raw, '- item0\n- item2')
Beispiel #10
0
    def status(self):
        if self.git and self.link is None:
            # git repo, check it exists & isn't dirty
            if not os.path.exists(self.path):
                LOG.info("ERROR book {0} from {1} doesn't exist.".format(
                    self.path,
                    self.git))
            else:
                # chdir to the book & run `git status`
                cwd = os.getcwd()
                os.chdir(self.path)
                if self._check_branch():
                    git_status = git.status()
                    if "nothing to commit, working directory clean" in git_status:
                        LOG.info("# book {0} OK".format(self.path))
                    else:
                        LOG.info("# book {0}".format(self.path))
                        LOG.info(git_status)
                os.chdir(cwd)

        elif self.link and self.git is None:
            # check the link points to the correct location
            if self._check_link():
                LOG.info('# book {0} correctly points to {1}'.format(self.path, self.link))
            else:
                link_target = os.readlink(self.path)
                LOG.error('ERROR: {0} should point to {1}, it points to {2}'.format(self.path, self.link, link_target))

        else:
            LOG.error('Unknown book type: {0}'.format(self.path))
Beispiel #11
0
    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
Beispiel #12
0
 def add(self, paths, msg="Intializating"):
     """
         Initializes Directory as repository if not already git repo.
         and adds uncommited 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"):
                 try:
                     Log.debug(self, "EEGit: git init at {0}"
                               .format(path))
                     git.init(path)
                 except ErrorReturnCode as e:
                     Log.debug(self, "{0}".format(e))
                     Log.error(self, "Unable to git init at {0}"
                               .format(path))
             status = git.status("-s")
             if len(status.splitlines()) > 0:
                 try:
                     Log.debug(self, "EEGit: git commit at {0}"
                               .format(path))
                     git.add("--all")
                     git.commit("-am {0}".format(msg))
                 except ErrorReturnCode as e:
                     Log.debug(self, "{0}".format(e))
                     Log.error(self, "Unable to git commit at {0} "
                               .format(path))
         else:
             Log.debug(self, "EEGit: Path {0} not present".format(path))
Beispiel #13
0
    def add_to_blacklist(self, items_to_blacklist, username, code_permissions):
        # Check if we're on master
        if git("rev-parse", "--abbrev-ref", "HEAD").strip() != "master":
            return (False, "Not currently on master.")

        # Check that we're up-to-date with origin (GitHub)
        git.remote.update()
        if git("rev-parse", "refs/remotes/origin/master").strip() != git("rev-parse", "master").strip():
            return (False, "HEAD isn't at tip of origin's master branch")

        # Check that blacklisted_websites.txt isn't modified locally. That could get ugly fast
        if "blacklisted_websites.txt" in git.status():  # Also ugly
            return (False, "blacklisted_websites.txt modified locally. This is probably bad.")

        # Store current commit hash
        current_commit = git("rev-parse", "HEAD").strip()

        # Add items to file
        with open("blacklisted_websites.txt", "a+") as blacklisted_websites:
            last_character = blacklisted_websites.read()[-1:]
            if last_character != "\n":
                blacklisted_websites.write("\n")
            blacklisted_websites.write("\n".join(items_to_blacklist) + "\n")

        # Checkout a new branch (mostly unnecessary, but may help if we create PRs in the future
        branch = "auto-blacklist-{0}".format(str(time.time()))
        git.checkout("-b", branch)

        # Clear HEAD just in case
        git.reset("HEAD")

        git.add("blacklisted_websites.txt")
        git.commit("-m", "Auto blacklist of {0} by {1} --autopull".format(", ".join(items_to_blacklist), username))

        if code_permissions:
            git.checkout("master")
            git.merge(branch)
            git.push()
        else:
            git.push("origin", branch)
            git.checkout("master")

            if GlobalVars.github_username is None or GlobalVars.github_password is None:
                return (False, "tell someone to set a GH password")

            payload = {"title": "{0}: Blacklist {1}".format(username, ", ".join(items_to_blacklist)),
                       "body": "{0} requests blacklist of domains: \n\n - {1}".format(username, "\n - ".join(items_to_blacklist)),
                       "head": branch,
                       "base": "master"}
            response = requests.post("https://api.github.com/repos/Charcoal-SE/SmokeDetector/pulls", auth=HTTPBasicAuth(GlobalVars.github_username, GlobalVars.github_password), data=json.dumps(payload))
            print(response.json())
            return (True, "You don't have code privileges, but I've [created a pull request for you]({0}).".format(response.json()["html_url"]))

        git.checkout(current_commit)  # Return to old commit to await CI. This will make Smokey think it's in reverted mode if it restarts

        if not code_permissions:
            return (False, "Unable to perform action due to lack of code-level permissions. [Branch pushed](https://github.com/Charcoal-SE/SmokeDetector/tree/{0}), PR at your leisure.".format(branch))

        return (True, "Blacklisted {0} - the entry will be applied via autopull if CI succeeds.".format(", ".join(items_to_blacklist)))
Beispiel #14
0
 def mv(self, sender, page, old_path, author, message, commit=True):
     status = git.status('--porcelain', old_path).stdout.decode('utf8')[1:2]
     extra_path = ''
     if status in ('D', 'M'):
         git.rm(old_path)
         extra_path = old_path
     if commit:
         self.commit(page, author=author, message=message, extra_path=extra_path)
Beispiel #15
0
 def mv(self, sender, page, old_path, author, message, commit=True):
     status = git.status("--porcelain", old_path).stdout.decode("utf8")[1:2]
     extra_path = ""
     if status in ("D", "M"):
         git.rm(old_path)
         extra_path = old_path
     if commit:
         self.commit(page, author=author, message=message, extra_path=extra_path)
Beispiel #16
0
def pull(url, path, remote=None):
    here = str(pwd()).strip()
    try:
        cd(path)
    except OSError:
        print "path does not exist? {}".format(path)
        cd(here)
        return
    try:
        git.status()
    except ErrorReturnCode_128:
        print "{} is not a git repository!".format(path)
        cd(here)
        return
    git.pull(remote or url, 'master')
    git.checkout('-f')
    cd(here)
Beispiel #17
0
 def mv(self, sender, page, old_path, author, message, commit=True):
     status = git.status('--porcelain', old_path).stdout.decode('utf8')[1:2]
     extra_path = ''
     if status in ('D', 'M'):
         git.rm(old_path)
         extra_path = old_path
     if commit:
         self.commit(page, author=author, message=message, extra_path=extra_path)
Beispiel #18
0
def script_write(script, dirname, uid, backup_dir=None):

    dirname = Path(dirname)

    if backup_dir is None:
        backup_dir = dirname / 'backup'
    else:
        backup_dir = Path(backup_dir)

    if uid:
        cmd_file = dirname / ('kea2.%s.sh' % uid)
    else:
        cmd_file = dirname / 'kea2.sh'

    if not dirname.exists():
        os.makedirs(dirname)

    try:
        output = git('rev-parse')
        ingit = True
        lg.debug("In a git repository - add & commit the script")
    except ErrorReturnCode as e:
        lg.info("not git - backing up the cmd file")
        ingit = False

    if cmd_file.exists():
        #check if in git:
        if ingit:
            for line in git.status('-s', cmd_file):
                _status, _filename = line.strip().split(None, 1)
                lg.warning('git status prewrite: %s %s', _status, _filename)
                if _filename != cmd_file:
                    lg.warning("this is not the file we want: %s", _filename)
                    continue
                if _status == '??':
                    git.add(cmd_file)
                if _status in ['??', 'A', 'M']:
                    lg.warning("git commit old version of %s", cmd_file)
                    git.commit(
                        cmd_file,
                        m='autocommit by kea2 - prepare for new version')
        else:
            #not in a git repository - copy file to a temp file
            ocf_stat = cmd_file.stat()
            timestamp = time.strftime("%Y-%m-%d_%H:%M:%S",
                                      time.localtime(ocf_stat.st_ctime))
            if not backup_dir.exists():
                os.makedirs(backup_dir)
            new_file_name = backup_dir / ('_kea2.%s.%s.sh' % (uid, timestamp))
            lg.info("rename old %s to %s", cmd_file, new_file_name)
            cmd_file.move(new_file_name)

    script = script.rstrip()
    with open(cmd_file, 'w') as F:
        F.write(script)
        F.write('\n')
    cmd_file.chmod('a+x')
    return cmd_file
Beispiel #19
0
def script_write(script, dirname, uid, backup_dir=None):

    dirname = Path(dirname)
    
    if backup_dir is None:
        backup_dir = dirname /  'backup'
    else:
        backup_dir = Path(backup_dir)

    if uid:
        cmd_file = dirname / ('kea2.%s.sh' % uid)
    else:
        cmd_file = dirname / 'kea2.sh'

    if not dirname.exists():
        os.makedirs(dirname)

    try:
        output = git('rev-parse')
        ingit = True
        lg.debug("In a git repository - add & commit the script")
    except ErrorReturnCode as e:
        lg.info("not git - backing up the cmd file")
        ingit = False

    if cmd_file.exists():
        #check if in git:
        if ingit:
            for line in git.status('-s', cmd_file):
                _status, _filename = line.strip().split(None, 1)
                lg.warning('git status prewrite: %s %s', _status, _filename)
                if _filename != cmd_file:
                    lg.warning("this is not the file we want: %s", _filename)
                    continue
                if _status == '??':
                    git.add(cmd_file)
                if _status in ['??', 'A', 'M']:
                    lg.warning("git commit old version of %s", cmd_file)
                    git.commit(cmd_file, m='autocommit by kea2 - prepare for new version')
        else:
            #not in a git repository - copy file to a temp file
            ocf_stat = cmd_file.stat()
            timestamp = time.strftime("%Y-%m-%d_%H:%M:%S",
                                      time.localtime(ocf_stat.st_ctime))
            if not backup_dir.exists():
                os.makedirs(backup_dir)
            new_file_name = backup_dir / ('_kea2.%s.%s.sh' % (uid, timestamp))
            lg.info("rename old %s to %s", cmd_file, new_file_name)
            cmd_file.move(new_file_name)

    script = script.rstrip()
    with open(cmd_file, 'w') as F:
        F.write(script)
        F.write('\n')
    cmd_file.chmod('a+x')
    return cmd_file
Beispiel #20
0
 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')
Beispiel #21
0
def _git_info(path):
    from sh import git
    git = git.bake('--no-pager')
    rev_parse = getattr(git, 'rev-parse')
    R = {'branch':    rev_parse('--abbrev-ref', 'HEAD', _cwd=path).strip(),
         'revision':  rev_parse('HEAD', _cwd=path).strip(),
         'untracked': getattr(git, 'ls-files')('--others', '--exclude-standard', '--directory', _cwd=path).strip(),
         'status':    git.status('-s', _cwd=path).strip(),
         'diff':      git.diff(_cwd=path).strip()}
    R['clean'] = len(R['diff']) == 0
    return R
Beispiel #22
0
 def git_commit(self, message='maintenance', push=False):
     sucess = False
     if (cd and git) is not False:
         # switch to project folder
         cd(self.paths['root'])
         # add changes
         git.add('.')
         git.add('-A')
         # commit changes
         try:
             print git.commit("-m '%s'" % message)
             sucess = True
         # get status
         except:
             print git.status()
     else:
         print 'sh and/or git not available.\n'
     # push to remote server
     if sucess and push:
         self.git_push()
Beispiel #23
0
    def _repo_dirty(self):
        """Return True if the repository is dirty."""

        UNCHANGED_STATUSES = (' ', '?', '!')

        for status_line in git.status(porcelain=True):
            if not(status_line[0] in UNCHANGED_STATUSES and
                   status_line[1] in UNCHANGED_STATUSES):
                return True

        return False
Beispiel #24
0
def _git_info(path):
    from sh import git
    git = git.bake('--no-pager')
    rev_parse = getattr(git, 'rev-parse')
    R = {'branch':    rev_parse('--abbrev-ref', 'HEAD', _cwd=path).strip(),
         'revision':  rev_parse('HEAD', _cwd=path).strip(),
         'untracked': getattr(git, 'ls-files')('--others', '--exclude-standard', '--directory', _cwd=path).strip(),
         'status':    git.status('-s', _cwd=path).strip(),
         'diff':      git.diff(_cwd=path).strip()}
    R['clean'] = len(R['diff']) == 0
    return R
Beispiel #25
0
    def _repo_dirty(self):
        """Return True if the repository is dirty."""

        UNCHANGED_STATUSES = (' ', '?', '!')

        for status_line in git.status(porcelain=True):
            if not (status_line[0] in UNCHANGED_STATUSES
                    and status_line[1] in UNCHANGED_STATUSES):
                return True

        return False
Beispiel #26
0
 def checkfilestatus(self, repo, filepath):
     """
         Checks status of file, If its tracked or untracked.
     """
     global git
     git = git.bake("--git-dir={0}/.git".format(repo), "--work-tree={0}".format(repo))
     status = git.status("-s", "{0}".format(filepath))
     if len(status.splitlines()) > 0:
         return True
     else:
         return False
Beispiel #27
0
    def test_concurrent_edition_no_existent_page(self):
        assert not Page.objects.filter(slug='test2').exists()
        url = reverse('waliki_edit', args=('test2', ))
        response1 = self.client.post(url)
        response2 = self.client.post(url)
        page = Page.objects.get(slug='test2')

        data1 = response1.context[0]['form'].initial
        data1["raw"] = '- item2\n'
        data1["message"] = "add item2"
        data1["title"] = "a title"

        data2 = response2.context[0]['form'].initial
        data2["raw"] = '- item0\n'
        data2["message"] = "add item0"
        data2["title"] = "another title"

        self.client.post(url, data1)
        with patch('waliki.views.messages') as messages:
            response = self.client.post(url, data2)
        # there is a warning
        self.assertTrue(messages.warning.called)
        self.assertIsInstance(messages.warning.call_args[0][1],
                              Page.EditionConflict)

        # redirect
        self.assertRedirects(response, url)

        # file committed with conflict
        self.assertEqual(
            '',
            git.status('--porcelain', page.path).stdout.decode('utf8'))
        self.assertIn(
            'Merged with conflict',
            git.log("--pretty=format:%s", "-n 1",
                    page.path).stdout.decode('utf8'))

        self.assertRegexpMatches(
            page.raw, r"""<<<<<<< HEAD\n- item2
=======\n- item0\n>>>>>>> [0-9a-f]{7}\n""")
        page = Page.objects.get(slug='test2')  # refresh
        self.assertEqual(page.title, "another title")

        # can edit in conflict
        response = self.client.get(url)

        data1 = response.context[0]['form'].initial
        data1["raw"] = '- item0\n- item2\n'
        data1["message"] = "fixing :)"
        response = self.client.post(url, data1)
        self.assertRedirects(response,
                             reverse('waliki_detail', args=(page.slug, )))
        self.assertEqual(page.raw, '- item0\n- item2\n')
Beispiel #28
0
 def checkfilestatus(self, repo, filepath):
     """
         Checks status of file, If its tracked or untracked.
     """
     global git
     git = git.bake("--git-dir={0}/.git".format(repo),
                    "--work-tree={0}".format(repo))
     status = git.status("-s", "{0}".format(filepath))
     if len(status.splitlines()) > 0:
         return True
     else:
         return False
Beispiel #29
0
 def needs_commit(self):
     import os
     
     try:
         for line in git.status(porcelain=True):
             if line.strip():
                 return True
   
         return False
     except ErrorReturnCode_128:
         logger.error("Needs_commit failed in {}".format(os.getcwd()))
         return False
Beispiel #30
0
    def needs_commit(self):
        import os

        try:
            for line in git.status(porcelain=True):
                if line.strip():
                    return True

            return False
        except ErrorReturnCode_128:
            global_logger.error("Needs_commit failed in {}".format(
                os.getcwd()))
            return False
Beispiel #31
0
    def test_concurrent_edition_no_existent_page(self):
        assert not Page.objects.filter(slug="test2").exists()
        url = reverse("waliki_edit", args=("test2",))
        response1 = self.client.post(url)
        response2 = self.client.post(url)
        page = Page.objects.get(slug="test2")

        data1 = response1.context[0]["form"].initial
        data1["raw"] = "- item2\n"
        data1["message"] = "add item2"
        data1["title"] = "a title"

        data2 = response2.context[0]["form"].initial
        data2["raw"] = "- item0\n"
        data2["message"] = "add item0"
        data2["title"] = "another title"

        self.client.post(url, data1)
        with patch("waliki.views.messages") as messages:
            response = self.client.post(url, data2)
        # there is a warning
        self.assertTrue(messages.warning.called)
        self.assertIsInstance(messages.warning.call_args[0][1], Page.EditionConflict)

        # redirect
        self.assertRedirects(response, url)

        # file committed with conflict
        self.assertEqual("", git.status("--porcelain", page.path).stdout.decode("utf8"))
        self.assertIn("Merged with conflict", git.log("--pretty=format:%s", "-n 1", page.path).stdout.decode("utf8"))

        self.assertRegexpMatches(
            page.raw,
            r"""<<<<<<< HEAD\n- item2
=======\n- item0\n>>>>>>> [0-9a-f]{7}\n""",
        )
        page = Page.objects.get(slug="test2")  # refresh
        self.assertEqual(page.title, "another title")

        # can edit in conflict
        response = self.client.get(url)

        data1 = response.context[0]["form"].initial
        data1["raw"] = "- item0\n- item2\n"
        data1["message"] = "fixing :)"
        response = self.client.post(url, data1)
        self.assertRedirects(response, reverse("waliki_detail", args=(page.slug,)))
        self.assertEqual(page.raw, "- item0\n- item2\n")
Beispiel #32
0
    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
Beispiel #33
0
    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
Beispiel #34
0
    def test_concurrent_edition_no_existent_page(self):
        assert not Page.objects.filter(slug='test2').exists()
        url = reverse('waliki_edit', args=('test2',))
        response1 = self.client.get(url)
        response2 = self.client.get(url)
        page = Page.objects.get(slug='test2')

        data1 = response1.context[0]['form'].initial
        data1["raw"] = '- item2\n'
        data1["message"] = "add item2"
        data1["title"] = "a title"

        data2 = response2.context[0]['form'].initial
        data2["raw"] = '- item0\n'
        data2["message"] = "add item0"
        data2["title"] = "another title"

        self.client.post(url, data1)
        with patch('waliki.views.messages') as messages:
            response = self.client.post(url, data2)
        # there is a warning
        self.assertTrue(messages.warning.called)
        self.assertIsInstance(messages.warning.call_args[0][1], Page.EditionConflict)

        # redirect
        self.assertRedirects(response, url)

        # file in conflict
        self.assertEqual('UU', git.status('--porcelain', page.path).stdout.decode('utf8')[:2])
        self.assertRegexpMatches(page.raw, r"""<<<<<<< HEAD\n- item2
=======\n- item0\n>>>>>>> [0-9a-f]{7}\n""")
        page = Page.objects.get(slug='test2')       # refresh
        self.assertEqual(page.title, "another title")

        # can edit in conflict
        response = self.client.get(url)

        data1 = response1.context[0]['form'].initial
        data1["raw"] = '- item0\n- item2\n'
        data1["message"] = "fixing :)"
        response = self.client.post(url, data1)
        self.assertRedirects(response, reverse('waliki_detail', args=(page.slug,)))
        self.assertEqual(page.raw, '- item0\n- item2\n')
Beispiel #35
0
def switch(target_branch):
    mark_message = '***mark***'
    try:
        res = git.status()
    except ErrorReturnCode:
        print(get_stderr(res))
        print('失败!该文件夹没有初始化')
        exit(-1)
    is_clean = re.match(".*nothing to commit, working tree clean.*", get_stdout(res), re.S)
    if not is_clean:
        print('工作区不干净,mark提交...')
        git.add('--all')
        git.commit('-a', '-m', mark_message)
    git.switch(target_branch)

    code, output = subprocess.getstatusoutput('git log -1 --pretty=format:"%s" ' + target_branch)
    if code == 0:
        if output == mark_message:
            git.reset('HEAD~')
    else:
        print("查看commit message出错!")
        exit(-1)
    print('切换到%s' % target_branch)
    def merge(self, branch, base_branch="master"):
        """
        Merge the the given WIP branch to master (or base_branch, if specified)

        If the merge fails, the merge will be aborted
        and then a MergeException will be thrown. The
        message of the MergeException will be the
        "git status" output, so details about merge
        conflicts can be determined.

        """

        os.chdir(self.repo)

        current_branch = self.current_branch()
        if current_branch != base_branch:
            git.checkout(base_branch)

        # Always create a merge commit, even if we could fast forward, so we know
        # when merges occured
        try:
            merge_output = git.merge("--no-ff", branch)
        except sh.ErrorReturnCode:
            # attempt to reset things so other operations can
            # continue
            output = git.status()
            git.merge("--abort")

            # re-raise the exception so other code can decide
            # what to do with it
            raise MergeException(output)

        # the merge succeeded, so remove the local WIP branch
        git.branch("-d", branch)

        new_sha      = git("rev-parse","HEAD")
        return new_sha.strip()
Beispiel #37
0
    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
Beispiel #38
0
    def merge(self, branch, base_branch="master"):
        """
        Merge the the given WIP branch to master (or base_branch, if specified)

        If the merge fails, the merge will be aborted
        and then a MergeException will be thrown. The
        message of the MergeException will be the
        "git status" output, so details about merge
        conflicts can be determined.

        """

        os.chdir(self.repo)

        current_branch = self.current_branch()
        if current_branch != base_branch:
            git.checkout(base_branch)

        # Always create a merge commit, even if we could fast forward, so we know
        # when merges occured
        try:
            merge_output = git.merge("--no-ff", branch)
        except sh.ErrorReturnCode:
            # attempt to reset things so other operations can
            # continue
            output = git.status()
            git.merge("--abort")

            # re-raise the exception so other code can decide
            # what to do with it
            raise MergeException(output)

        # the merge succeeded, so remove the local WIP branch
        git.branch("-d", branch)

        new_sha = git("rev-parse", "HEAD")
        return new_sha.strip()
Beispiel #39
0
    def status(self):
        """Get status on the repo.
        :return:
        :rtype:
        """

        rd = self.repo_dir

        logger.debug("pkg path %s", rd)
        if not rd:
            print("unable to find pkg '%s'. %s" %
                  (self.name, did_u_mean(self.name)))

        cwd = os.getcwd()
        os.chdir(self.repo_dir)
        logger.debug("cwd: %s, getting status %s ", cwd, self.repo_dir)
        try:
            p = git.status(_out=self._sh_stdout('blue'),
                           _err=self._sh_stderr('red'))
            p.wait()
        except Exception:
            pass
            # logger.warn(e)
        os.chdir(cwd)
 def current_git_status():
     return git.status()
Beispiel #41
0
    def add_to_blacklist(self, **kwargs):
        blacklist = kwargs.get("blacklist", "website")
        items_to_blacklist = kwargs.get("items_to_blacklist", [])
        username = kwargs.get("username", "")
        chat_profile_link = kwargs.get("chat_profile_link",
                                       "http://chat.stackexchange.com/users")
        code_permissions = kwargs.get("code_permissions", False)

        if blacklist == "website":
            blacklist_file_name = "blacklisted_websites.txt"
        elif blacklist == "keyword":
            blacklist_file_name = "bad_keywords.txt"
        elif blacklist == "username":
            blacklist_file_name = "blacklisted_usernames.txt"

        # Check if we're on master
        if git("rev-parse", "--abbrev-ref", "HEAD").strip() != "master":
            return (False, "Not currently on master.")

        # Check that we're up-to-date with origin (GitHub)
        git.remote.update()
        if git("rev-parse", "refs/remotes/origin/master").strip() != git(
                "rev-parse", "master").strip():
            return (False, "HEAD isn't at tip of origin's master branch")

        # Check that blacklisted_websites.txt isn't modified locally. That could get ugly fast
        if blacklist_file_name in git.status():  # Also ugly
            return (False,
                    "{0} modified locally. This is probably bad.".format(
                        blacklist_file_name))

        # Store current commit hash
        current_commit = git("rev-parse", "HEAD").strip()

        # Add items to file
        with open(blacklist_file_name, "a+") as blacklist_file:
            last_character = blacklist_file.read()[-1:]
            if last_character != "\n":
                blacklist_file.write("\n")
            blacklist_file.write("\n".join(items_to_blacklist) + "\n")

        # Checkout a new branch (for PRs for non-code-privileged people)
        branch = "auto-blacklist-{0}".format(str(time.time()))
        git.checkout("-b", branch)

        # Clear HEAD just in case
        git.reset("HEAD")

        git.add(blacklist_file_name)
        git.commit(
            "-m", u"Auto blacklist of {0} by {1} --autopull".format(
                ", ".join(items_to_blacklist), username))

        if code_permissions:
            git.checkout("master")
            git.merge(branch)
            git.push()
        else:
            git.push("origin", branch)
            git.checkout("master")

            if GlobalVars.github_username is None or GlobalVars.github_password is None:
                return (False, "Tell someone to set a GH password")

            list_of_domains = ""

            for domain in range(len(items_to_blacklist)):
                list_of_domains += "\n - {0} - [MS search](https://metasmoke.erwaysoftware.com/search?utf8=%E2%9C%93&body_is_regex=1&body={0})".format(
                    items_to_blacklist[domain])

            payload = {
                "title":
                "{0}: Blacklist {1}".format(username,
                                            ", ".join(items_to_blacklist)),
                "body":
                "[{0}]({1}) requests the blacklist of the following {2}(s): \n{3}\n<!-- METASMOKE-BLACKLIST {4} -->"
                .format(username, chat_profile_link, blacklist,
                        list_of_domains, "|".join(items_to_blacklist)),
                "head":
                branch,
                "base":
                "master"
            }
            response = requests.post(
                "https://api.github.com/repos/Charcoal-SE/SmokeDetector/pulls",
                auth=HTTPBasicAuth(GlobalVars.github_username,
                                   GlobalVars.github_password),
                data=json.dumps(payload))
            print(response.json())
            return (
                True,
                "You don't have code privileges, but I've [created a pull request for you]({0})."
                .format(response.json()["html_url"]))

        git.checkout(
            current_commit
        )  # Return to old commit to await CI. This will make Smokey think it's in reverted mode if it restarts

        return (
            True,
            "Blacklisted {0} - the entry will be applied via autopull if CI succeeds."
            .format(", ".join(items_to_blacklist)))
Beispiel #42
0
    def add_to_blacklist(**kwargs):
        blacklist = kwargs.get("blacklist", "")
        item_to_blacklist = kwargs.get("item_to_blacklist", "")
        username = kwargs.get("username", "")
        chat_profile_link = kwargs.get("chat_profile_link", "http://chat.stackexchange.com/users")
        code_permissions = kwargs.get("code_permissions", False)

        # Make sure git credentials are set up
        if git.config("--global", "--get", "user.name") == "":
            return (False, "Tell someone to run `git config --global user.name \"SmokeDetector\"`")

        if git.config("--global", "--get", "user.name") == "":
            return (False, "Tell someone to run `git config --global user.email \"[email protected]\"`")

        if blacklist == "":
            # If we broke the code, and this isn't assigned, error out before doing anything, but do
            # so gracefully with a nice error message.
            return (False, "Programming Error - Critical information missing for GitManager: blacklist")

        if item_to_blacklist == "":
            # If we broke the code, and this isn't assigned, error out before doing anything, but do
            # so gracefully with a nice error message.
            return (False, "Programming Error - Critical information missing for GitManager: item_to_blacklist")

        item_to_blacklist = item_to_blacklist.replace("\s", " ")

        if blacklist == "website":
            blacklist_file_name = "blacklisted_websites.txt"
            ms_search_option = "&body_is_regex=1&body="
        elif blacklist == "keyword":
            blacklist_file_name = "bad_keywords.txt"
            ms_search_option = "&body_is_regex=1&body="
        elif blacklist == "username":
            blacklist_file_name = "blacklisted_usernames.txt"
            ms_search_option = "&username_is_regex=1&username="******"Invalid blacklist type specified, something has broken badly!")

        git.checkout("master")
        try:
            git.pull()
        except:
            pass

        # Check that we're up-to-date with origin (GitHub)
        git.remote.update()
        if git("rev-parse", "refs/remotes/origin/master").strip() != git("rev-parse", "master").strip():
            return (False, "HEAD isn't at tip of origin's master branch")

        # Check that blacklisted_websites.txt isn't modified locally. That could get ugly fast
        if blacklist_file_name in git.status():  # Also ugly
            return (False, "{0} is modified locally. This is probably bad.".format(blacklist_file_name))

        # Add item to file
        with open(blacklist_file_name, "a+") as blacklist_file:
            last_character = blacklist_file.read()[-1:]
            if last_character != "\n":
                blacklist_file.write("\n")
            blacklist_file.write(item_to_blacklist + "\n")

        # Checkout a new branch (for PRs for non-code-privileged people)
        branch = "auto-blacklist-{0}".format(str(time.time()))
        git.checkout("-b", branch)

        # Clear HEAD just in case
        git.reset("HEAD")

        git.add(blacklist_file_name)
        git.commit("-m", u"Auto blacklist of {0} by {1} --autopull".format(item_to_blacklist, username))

        if code_permissions:
            git.checkout("master")
            git.merge(branch)
            git.push()
        else:
            git.push("origin", branch)
            git.checkout("master")

            if GlobalVars.github_username is None or GlobalVars.github_password is None:
                return (False, "Tell someone to set a GH password")

            payload = {"title": u"{0}: Blacklist {1}".format(username, item_to_blacklist),
                       "body": u"[{0}]({1}) requests the blacklist of the {2} {3}. See the Metasmoke search [here]"
                               "(https://metasmoke.erwaysoftware.com/search?utf8=%E2%9C%93{4}{5})\n"
                               u"<!-- METASMOKE-BLACKLIST-{6} {3} -->".format(username, chat_profile_link, blacklist,
                                                                              item_to_blacklist, ms_search_option,
                                                                              item_to_blacklist.replace(" ", "+"),
                                                                              blacklist.upper()),
                       "head": branch,
                       "base": "master"}
            response = requests.post("https://api.github.com/repos/Charcoal-SE/SmokeDetector/pulls",
                                     auth=HTTPBasicAuth(GlobalVars.github_username, GlobalVars.github_password),
                                     data=json.dumps(payload))
            print(response.json())
            try:
                git.checkout("deploy")  # Return to deploy, pending the accept of the PR in Master.
                return (True, "You don't have code privileges, but I've [created a pull request for you]({0}).".format(
                    response.json()["html_url"]))
            except KeyError:
                # Error capture/checking for any "invalid" GH reply without an 'html_url' item,
                # which will throw a KeyError.
                if "bad credentials" in str(response.json()['message']).lower():
                    # Capture the case when GH credentials are bad or invalid
                    return (False, "Something is wrong with the GH credentials, tell someone to check them.")
                else:
                    # Capture any other invalid response cases.
                    return (False, "A bad or invalid reply was received from GH, the message was: %s" %
                            response.json()['message'])

        git.checkout("deploy")  # Return to deploy to await CI.

        return (True, "Blacklisted {0}".format(item_to_blacklist))
Beispiel #43
0
def _is_dirty():
    return "" != git.status(porcelain=True).strip()
Beispiel #44
0
 def mv(self, page, old_path, author, message):
     status = git.status('--porcelain', old_path).stdout.decode('utf8')[1:2]
     if status == 'D':
         git.rm(old_path)
     self.commit(page, author=author, message=message)

def clean():
    if path.exists('dist'):
        rmtree('dist')


vers = input('Did you change the version? (y/n) ')
if vers != 'y' and vers != 'n':
    print('Expected "y" or "n", instead found {}. Exiting.'.format(vers))
    exit(1)

if vers == 'n':
    exit(0)

status = git.status()
branch = git.branch()

if 'master' not in branch:
    print('Must be on branch "master". Exiting.')
    exit(1)

if 'Changes not staged for commit' in status or 'Untracked files' in status or 'Changes to be committed' in status:
    # get user input for if they want to commit all current changes
    # and continue with the deploy script
    # exit if no
    commit = input(
        'Changes were detected, would you like to commit all current changes? (y/n) '
    )
    if commit != 'y' and commit != 'n':
        print('Expected "y" or "n", instead found {}. Exiting.'.format(commit))
Beispiel #46
0
def gen_status(file_path):
    '''return generator with result of git status --porcelain'''
    all_status = git.status('--porcelain', file_path, _cwd=dir_path(file_path))
    return all_status
Beispiel #47
0
def _is_dirty():
    return "" != git.status(porcelain=True).strip()
Beispiel #48
0
print("load changes")
git.pull("--all")
git.reset("origin/master", "--hard")
git.pull()

print("Finish download")
for i in l.split("\n")[1:]:
    if i and regex.search(i):
        ips.append(regex.search(i).groups()[0])

with open("rawlist.txt", "w") as fp:
    for i in ips:
        fp.write(i + "\n")

with open("list.txt", 'w') as fp:
    # s = "[AutoProxy 0.2.9]\n"
    for i in ips:
        fp.write("||{}\n".format(i))
    # s = base64.b64encode(s.encode('utf8')).decode()
    # for i in range(0, len(s), 64):
    # fp.write(s[i:i+64])
    # fp.write("\n")

if git.status("--short") != "":
    print("updating")
    git.add(".")
    git.commit("-m", "update by robot")
    git.push()
    print("updating finished")
    "zephyr",
    "minimal",
    "esp8266",
    "pic16bit",
    "qemu-arm",
    "bare-arm",
    "rp2",
]
for p in ports_to_delete:
    try:
        git.rm("-rf", "ports/" + p)
    except sh.ErrorReturnCode_128:
        pass

# We inherit stm32 changes into stm because we did a git rename.
git.status("--porcelain=1", "ports/stm", _out=out_buf)
out_buf.seek(0)
line = out_buf.readline()
while line:
    state, path = line.split()
    if state == "UU":
        git.checkout("--ours", path)
        git.add(path)
    elif state == "UA":
        git.rm(path)
    line = out_buf.readline()

# MicroPython added their nrf code in ports/nrf too. So, we always take our version.
out_buf = StringIO()
git.status("--porcelain=1", "ports/nrf", _out=out_buf)
out_buf.seek(0)
Beispiel #50
0
print("load changes")
git.pull("--all")
git.reset("origin/master", "--hard")
git.pull()

print("Finish download")
for i in l.split("\n")[1:]:
    if i and regex.search(i):
        ips.append(regex.search(i).groups()[0])


with open("rawlist.txt", "w") as fp:
    for i in ips:
        fp.write(i+"\n")

with open("list.txt", 'w') as fp:
    # s = "[AutoProxy 0.2.9]\n"
    for i in ips:
        fp.write("||{}\n".format(i))
    # s = base64.b64encode(s.encode('utf8')).decode()
    # for i in range(0, len(s), 64):
        # fp.write(s[i:i+64])
        # fp.write("\n")

if git.status("--short") != "":
    print("updating")
    git.add(".")
    git.commit("-m", "update by robot")
    git.push()
    print("updating finished")
Beispiel #51
0
 def git_status(self):
     """Get current git status."""
     cd(self.paths['root'])
     print git.status()
Beispiel #52
0
def push(remote_name, remote_branch, to_be_pushed_branch, commit_hash_list):
    git.status()
    current_branch = get_stdout(git('symbolic-ref', '--short', '-q',
                                    'HEAD'))[0:-1]
    mark_message = '***mark***'

    # 校验是否tag已存在
    tag_name = f"merging({current_branch}-->{remote_name}/{remote_branch})"
    code, output = subprocess.getstatusoutput(f"git tag | grep '^{tag_name}$'")
    if code == 0:
        print(f"错误,tag:{tag_name} 已存在")
        exit(-1)

    # 校验远程分支是否存在
    code, output = subprocess.getstatusoutput('git fetch')
    if code != 0:
        print(output)
        print("fetch 失败")
        exit(-1)

    code, output = subprocess.getstatusoutput(
        f"git branch -r | cat | grep '^ *{remote_name}/{remote_branch}'")
    if code != 0:
        print("错误,远程分支%s不存在" % remote_branch)
        exit(-1)

    # 如果工作区不干净,mark提交
    res = git.status()
    is_clean = re.match(".*nothing to commit, working tree clean.*",
                        get_stdout(res), re.S)
    if not is_clean:
        print('工作区不干净,mark提交...')
        git.add('--all')
        git.commit('-a', '-m', mark_message)

    # 检出到远程临时分支
    tmp_branch = f'tmp/local_{remote_name}_{remote_branch}'
    print(f'检出到远程临时分支"{tmp_branch}"...')
    git.checkout('-b', tmp_branch, f'{remote_name}/{remote_branch}')

    # cherry-pick
    try:
        print('开始cherry-pick...')
        res = git('cherry-pick', commit_hash_list)
    except sh.ErrorReturnCode_1:
        print(get_stderr(res))
        print("请解决冲突,然后选择后续操作...")
        while True:
            operation = input('请输入处理方式')
            if operation == 0:
                print('execute: git cherry-pick --continue...')
                code, output = subprocess.getstatusoutput(
                    'git cherry-pick --continue')
                print(output)
                if code != 0:
                    continue
                else:
                    print('解决冲突成功')
                    break
            elif operation == 1:
                print('退出,停在当前位置')
                git('check-pick', '--abort')
                exit(-1)
            elif operation == 2:
                print('撤销,回到起点...')
                git('check-pick', '--abort')
                # 切换会原来的分支,并去掉mark提交
                git.switch(current_branch)
                git.branch('-D', tmp_branch)
                de_mark_commit(current_branch, mark_message)
                exit(-1)
            else:
                print('输入不合法,请重新输入')
    except ErrorReturnCode:
        print(get_stderr(res))
        exit(-1)

    print('推送中...')
    git.push('-f', remote_name, f'HEAD:{to_be_pushed_branch}')

    # 切换会原来的分支,并去掉mark提交
    print('切换会原来的分支,并去掉mark提交')
    git.switch(current_branch)
    git.branch('-D', tmp_branch)
    de_mark_commit(current_branch, mark_message)

    print(f'添加tag"{tag_name}"...')
    git.tag('-a', tag_name, '-m', "nothing")
    print('完成!')
Beispiel #53
0
 def current_git_status(self):
     return git.status()
Beispiel #54
0
def gen_status(file_path):
    '''return generator with result of git status --porcelain'''
    all_status = git.status('--porcelain', file_path, _cwd=dir_path(file_path))
    return all_status
Beispiel #55
0
    def add_to_blacklist(**kwargs):
        if 'windows' in str(platform.platform()).lower():
            log('warning', "Git support not available in Windows.")
            return (False, "Git support not available in Windows.")

        blacklist = kwargs.get("blacklist", "")
        item_to_blacklist = kwargs.get("item_to_blacklist", "")
        username = kwargs.get("username", "")
        chat_profile_link = kwargs.get("chat_profile_link", "http://chat.stackexchange.com/users")
        code_permissions = kwargs.get("code_permissions", False)

        # Make sure git credentials are set up
        if git.config("--global", "--get", "user.name", _ok_code=[0, 1]) == "":
            return (False, "Tell someone to run `git config --global user.name \"SmokeDetector\"`")

        if git.config("--global", "--get", "user.email", _ok_code=[0, 1]) == "":
            return (False, "Tell someone to run `git config --global user.email \"[email protected]\"`")

        if blacklist == "":
            # If we broke the code, and this isn't assigned, error out before doing anything, but do
            # so gracefully with a nice error message.
            return (False, "Programming Error - Critical information missing for GitManager: blacklist")

        if item_to_blacklist == "":
            # If we broke the code, and this isn't assigned, error out before doing anything, but do
            # so gracefully with a nice error message.
            return (False, "Programming Error - Critical information missing for GitManager: item_to_blacklist")

        item_to_blacklist = item_to_blacklist.replace("\s", " ")

        if blacklist == "website":
            blacklist_file_name = "blacklisted_websites.txt"
            ms_search_option = "&body_is_regex=1&body="
        elif blacklist == "keyword":
            blacklist_file_name = "bad_keywords.txt"
            ms_search_option = "&body_is_regex=1&body="
        elif blacklist == "username":
            blacklist_file_name = "blacklisted_usernames.txt"
            ms_search_option = "&username_is_regex=1&username="******"Invalid blacklist type specified, something has broken badly!")

        git.checkout("master")
        try:
            git.pull()
        except:
            pass

        # Check that we're up-to-date with origin (GitHub)
        git.remote.update()
        if git("rev-parse", "refs/remotes/origin/master").strip() != git("rev-parse", "master").strip():
            return (False, "HEAD isn't at tip of origin's master branch")

        # Check that blacklisted_websites.txt isn't modified locally. That could get ugly fast
        if blacklist_file_name in git.status():  # Also ugly
            return (False, "{0} is modified locally. This is probably bad.".format(blacklist_file_name))

        # Add item to file
        with open(blacklist_file_name, "a+") as blacklist_file:
            last_character = blacklist_file.read()[-1:]
            if last_character != "\n":
                blacklist_file.write("\n")
            blacklist_file.write(item_to_blacklist + "\n")

        # Checkout a new branch (for PRs for non-code-privileged people)
        branch = "auto-blacklist-{0}".format(str(time.time()))
        git.checkout("-b", branch)

        # Clear HEAD just in case
        git.reset("HEAD")

        git.add(blacklist_file_name)
        git.commit("--author='SmokeDetector <*****@*****.**>'",
                   "-m", u"Auto blacklist of {0} by {1} --autopull".format(item_to_blacklist, username))

        if code_permissions:
            git.checkout("master")
            git.merge(branch)
            git.push("origin", "master")
            git.branch('-D', branch)  # Delete the branch in the local git tree since we're done with it.
        else:
            git.push("origin", branch)
            git.checkout("master")

            if GlobalVars.github_username is None or GlobalVars.github_password is None:
                return (False, "Tell someone to set a GH password")

            payload = {"title": u"{0}: Blacklist {1}".format(username, item_to_blacklist),
                       "body": u"[{0}]({1}) requests the blacklist of the {2} {3}. See the Metasmoke search [here]"
                               "(https://metasmoke.erwaysoftware.com/search?utf8=%E2%9C%93{4}{5})\n"
                               u"<!-- METASMOKE-BLACKLIST-{6} {3} -->".format(username, chat_profile_link, blacklist,
                                                                              item_to_blacklist, ms_search_option,
                                                                              item_to_blacklist.replace(" ", "+"),
                                                                              blacklist.upper()),
                       "head": branch,
                       "base": "master"}
            response = requests.post("https://api.github.com/repos/Charcoal-SE/SmokeDetector/pulls",
                                     auth=HTTPBasicAuth(GlobalVars.github_username, GlobalVars.github_password),
                                     data=json.dumps(payload))
            log('debug', response.json())
            try:
                git.checkout("deploy")  # Return to deploy, pending the accept of the PR in Master.
                git.branch('-D', branch)  # Delete the branch in the local git tree since we're done with it.
                return (True, "You don't have code privileges, but I've [created a pull request for you]({0}).".format(
                    response.json()["html_url"]))
            except KeyError:
                git.checkout("deploy")  # Return to deploy

                # Delete the branch in the local git tree, we'll create it again if the
                # command is run again. This way, we keep things a little more clean in
                # the local git tree
                git.branch('-D', branch)

                # Error capture/checking for any "invalid" GH reply without an 'html_url' item,
                # which will throw a KeyError.
                if "bad credentials" in str(response.json()['message']).lower():
                    # Capture the case when GH credentials are bad or invalid
                    return (False, "Something is wrong with the GH credentials, tell someone to check them.")
                else:
                    # Capture any other invalid response cases.
                    return (False, "A bad or invalid reply was received from GH, the message was: %s" %
                            response.json()['message'])

        git.checkout("deploy")  # Return to deploy to await CI.

        return (True, "Blacklisted {0}".format(item_to_blacklist))
Beispiel #56
0
 def mv(self, page, old_path, author, message):
     status = git.status('--porcelain', old_path).stdout.decode('utf8')[1:2]
     if status == 'D':
         git.rm(old_path)
     self.commit(page, author=author, message=message)
Beispiel #57
0
 def current_git_status():
     if 'windows' in str(platform.platform()).lower():
         return "Git support not available in Windows."
     return git.status()