Пример #1
0
 def checkout(self, ref: str, track: bool = False) -> None:
     if self.is_dirty:
         CONSOLE.stdout(
             ' - Dirty repo. Please stash, commit, or discard your changes')
         self.status(verbose=True)
         return
     GitOffline.checkout(self.path, ref=ref, track=track)
Пример #2
0
 def reset(self, ref: Union[Ref, str] = HEAD, hard: bool = False) -> None:
     if isinstance(ref, TrackingBranch):
         ref = ref.upstream_branch.short_ref
     elif isinstance(ref, Ref):
         ref = ref.short_ref
     CONSOLE.stdout(f' - Reset repo to {Format.Git.ref(ref)}')
     GitOffline.reset(self.path, ref=ref, hard=hard)
Пример #3
0
 def get_submodules(cls, path: Path) -> List[Submodule]:
     submodules_info = GitOffline.get_submodules_info(path)
     submodules = []
     for key in submodules_info.keys():
         submodule_info = submodules_info[key]
         # TODO: Save url from config and gitmodules
         url = submodule_info['url']
         submodule_path = Path(key)
         branch = submodule_info[
             'branch'] if 'branch' in submodule_info else None
         active = submodule_info[
             'active'] if 'active' in submodule_info else None
         active = True if active == 'true' else False
         submodule_commit = GitOffline.get_submodule_commit(
             path, submodule_path)
         submodule = Submodule(path,
                               submodule_path,
                               url=url,
                               commit=submodule_commit,
                               branch=branch,
                               active=active)
         submodules.append(submodule)
         recursive_submodules = GitFactory.get_submodules(submodule.path)
         if recursive_submodules:
             submodules += recursive_submodules
     return sorted(submodules)
Пример #4
0
 def checkout(self, check: bool = True, track: bool = False) -> None:
     current_commit = GitOffline.current_head_commit_sha(self.path)
     # TODO: Should this always check out detached HEAD?
     if current_commit == self.sha and GitOffline.is_detached(self.path):
         CONSOLE.stdout(' - On correct commit')
         return
     CONSOLE.stdout(f' - Checkout commit {Format.Git.ref(self.short_ref)}')
     super().checkout(check=check, track=track)
Пример #5
0
 def reset_timestamp(self,
                     timestamp: str,
                     ref: Ref,
                     author: Optional[str] = None) -> None:
     CONSOLE.stdout(' - Reset timestamp')
     GitOffline.reset_timestamp(self.path,
                                timestamp=timestamp,
                                ref=ref.short_ref,
                                author=author)
Пример #6
0
 def checkout(self, check: bool = True, track: bool = False) -> None:
     try:
         GitOffline.checkout(self.path, ref=self.short_ref, track=track)
     except Exception:  # noqa
         message = f'Failed to checkout'
         if check:
             GIT_LOG.error(message)
             raise
         CONSOLE.stdout(f' - {message}')
Пример #7
0
    def update_git_config(self, config: GitConfig) -> None:
        """Update custom git config

        :param GitConfig config: Custom git config
        """

        CONSOLE.stdout(" - Update local git config")
        for key, value in config.items():
            GitOffline.git_config_unset_all_local(self.path, key)
            GitOffline.git_config_add_local(self.path, key, value)
Пример #8
0
 def set_upstream(self) -> None:
     CONSOLE.stdout(
         f' - Set tracking branch {Format.Git.ref(self.name)} -> '
         f'{Format.Git.remote(self.upstream_branch.remote.name)} '
         f'{Format.Git.ref(self.upstream_branch.name)}')
     GitOffline.set_upstream_branch(
         self.path,
         local_branch=self.name,
         upstream_branch=self.upstream_branch.name,
         remote=self.upstream_branch.remote.name)
Пример #9
0
    def add(self, files: Union[Path, str, List[str], List[Path]]) -> None:
        if isinstance(files, str):
            files = [files]
        elif isinstance(files, Path):
            files = [str(files)]
        elif isinstance(files, list):
            files = [str(f) for f in files]
        else:
            raise Exception('Wrong type for files parameter')

        CONSOLE.stdout(' - Add files to git index')
        GitOffline.add(self.path, files=files)
Пример #10
0
 def default_branch(self, url: str) -> Optional[RemoteBranch]:
     if GitOffline.is_repo_cloned(self.path):
         default_branch = GitOffline.get_default_branch(self.path, self.name)
         if default_branch is not None:
             return RemoteBranch(self.path, default_branch, self.name)
     default_branch = GitOnline.get_default_branch(url)
     if default_branch is None:
         return None
     git_dir = GitOffline.git_dir(self.path)
     if git_dir is not None and git_dir.is_dir():
         GitOffline.save_default_branch(git_dir, self.name, default_branch)
     return RemoteBranch(self.path, default_branch, self.name)
Пример #11
0
 def submodule_add(self,
                   url: str,
                   branch: Optional[str] = None,
                   force: bool = False,
                   name: Optional[str] = None,
                   reference: Optional[str] = None,
                   depth: Optional[int] = None,
                   submodule_path: Optional[Path] = None) -> None:
     GitOffline.submodule_add(self.path,
                              url,
                              branch=branch,
                              force=force,
                              name=name,
                              reference=reference,
                              depth=depth,
                              submodule_path=submodule_path)
Пример #12
0
 def checkout(self, check: bool = True, track: bool = False) -> None:
     current_commit = GitOffline.current_head_commit_sha(self.path)
     if current_commit == self.sha:
         CONSOLE.stdout(' - On correct commit for tag')
         return
     CONSOLE.stdout(f' - Checkout tag {self.name}')
     super().checkout(check=check, track=track)
Пример #13
0
    def check_ref_format(ref: str) -> bool:
        """Check if git ref is correctly formatted

        :param str ref: Git ref
        :return: True, if git ref is a valid format
        """

        return GitOffline.check_ref_format(ref)
Пример #14
0
    def wrapper(*args, **kwargs):
        """Wrapper"""

        instance = args[0]
        if GitOffline.is_detached(instance.path):
            CONSOLE.stdout(' - HEAD is detached')
            raise Exception('Detached HEAD')
        return func(*args, **kwargs)
Пример #15
0
 def create(self, branch: Optional[str] = None, remote: Optional[str] = None, track: bool = True) -> None:
     if self.exists:
         CONSOLE.stdout(f' - Local branch {Format.Git.ref(self.short_ref)} already exists')
         return
     CONSOLE.stdout(f' - Create local branch {Format.Git.ref(self.short_ref)}')
     if branch is not None:
         if remote is not None:
             from pygoodle.git.model.branch.remote_branch import RemoteBranch
             remote_branch = RemoteBranch(self.path, branch, remote)
             if not remote_branch.exists:
                 branch = None
                 remote = None
         else:
             local_branch = LocalBranch(self.path, branch)
             if not local_branch.exists:
                 branch = None
     GitOffline.create_local_branch(self.path, self.name, branch=branch, remote=remote, track=track)
Пример #16
0
 def get_remote_branches_offline(cls, path: Path,
                                 remote: str) -> List[RemoteBranch]:
     branches, default_branch = GitOffline.get_remote_branches_info(
         path, remote)
     branches = [RemoteBranch(path, branch, remote) for branch in branches]
     if default_branch is not None:
         branches.append(
             RemoteBranch(path, default_branch, remote, is_default=True))
     return sorted(branches)
Пример #17
0
 def checkout(self, check: bool = True, track: bool = False) -> None:
     current_branch = GitOffline.current_branch(self.path)
     if current_branch == self.name:
         CONSOLE.stdout(
             f' - Branch {Format.Git.ref(self.short_ref)} already checked out'
         )
         return
     CONSOLE.stdout(f' - Checkout branch {Format.Git.ref(self.short_ref)}')
     super().checkout(check=check, track=track)
Пример #18
0
    def clean(self,
              untracked_directories: bool = False,
              force: bool = False,
              ignored: bool = False,
              untracked_files: bool = False) -> None:
        """Discard changes for repo

        :param bool untracked_directories: ``d`` Remove untracked directories in addition to untracked files
        :param bool force: ``f`` Delete directories with .git sub directory or file
        :param bool ignored: ``X`` Remove only files ignored by git
        :param bool untracked_files: ``x`` Remove all untracked files
        """

        CONSOLE.stdout(' - Clean repo')
        GitOffline.clean(self.path,
                         untracked_directories=untracked_directories,
                         force=force,
                         ignored=ignored,
                         untracked_files=untracked_files)
Пример #19
0
 def create(self,
            branch: Optional[str] = None,
            remote: Optional[str] = None) -> None:
     from pygoodle.git.model.factory import GitFactory
     if GitFactory.has_remote_branch_online(self.path, self.name,
                                            self.remote.name):
         CONSOLE.stdout(
             f' - Remote branch {Format.Git.ref(self.name)} already exists')
         return
     CONSOLE.stdout(f' - Create remote branch {Format.Git.ref(self.name)}')
     branch = self.name if branch is None else branch
     from pygoodle.git.model.branch.local_branch import LocalBranch
     local_branch = LocalBranch(self.path, branch)
     GitOnline.fetch(self.path, prune=True)
     has_existing_branch = local_branch.exists
     if not has_existing_branch:
         local_branch.create(branch=branch, remote=remote)
     local_branch.push(remote=self.remote.name, branch=self.name)
     if not has_existing_branch:
         GitOffline.delete_local_branch(self.path, branch)
     GitOnline.fetch(self.path, prune=True)
Пример #20
0
 def get_tracking_branches(cls, path: Path) -> List[TrackingBranch]:
     branches = GitOffline.get_tracking_branches_info(path)
     tracking_branches = []
     for local_branch, info in branches.items():
         tracking_branch = TrackingBranch(
             path,
             local_branch=local_branch,
             upstream_branch=info['upstream_branch'],
             upstream_remote=info['upstream_remote'],
             push_branch=info['push_branch'],
             push_remote=info['push_remote'])
         tracking_branches.append(tracking_branch)
     return sorted(tracking_branches)
Пример #21
0
    def formatted_ref(self) -> str:
        """Formatted project repo ref"""

        if self.is_detached:
            return Format.Git.ref(Format.escape(f'[HEAD @ {self.sha()}]'))

        current_branch_output = Format.Git.ref(
            Format.escape(f'[{self.current_branch}]'))

        local_commits_count = GitOffline.new_commits_count(self.path)
        no_local_commits = local_commits_count == 0
        # TODO: Specify correct remote
        upstream_commits_count = GitOffline.new_commits_count(self.path,
                                                              upstream=True)
        no_upstream_commits = upstream_commits_count == 0

        if no_local_commits and no_upstream_commits:
            return current_branch_output

        local_commits_output = Format.yellow(f'+{local_commits_count}')
        upstream_commits_output = Format.red(f'-{upstream_commits_count}')
        return f'{current_branch_output}({local_commits_output}/{upstream_commits_output})'
Пример #22
0
 def get_diff(cls, path: Path) -> Diff:
     diff_info = GitOffline.get_diff_index_info(path)
     changes = []
     for change_type, changes_list in diff_info.items():
         for change_info in changes_list:
             change = Change(path,
                             file_path=Path(change_info['file_path']),
                             change_type=change_type,
                             old_permissions=change_info['old_permissions'],
                             new_permissions=change_info['new_permissions'],
                             old_sha=change_info['old_sha'],
                             new_sha=change_info['new_sha'])
             changes.append(change)
     return Diff(path, changes=changes)
Пример #23
0
    def create(self) -> None:
        if GitOffline.has_tracking_branch(self.path, self.local_branch.name):
            CONSOLE.stdout(' - Tracking branch already exists')
            return
        # TODO: Add Format util to format tracking branch output: local_branch -> remote remote_branch
        CONSOLE.stdout(
            f' - Create tracking branch {Format.Git.ref(self.name)}')
        GitOnline.fetch(self.path, prune=True)
        # local and remote branches exist
        if self.local_branch.exists and self.upstream_branch.exists:
            self.set_upstream()
            return

        # only local branch exists
        if self.local_branch.exists:
            # GitOnline.push(self.path,
            #                local_branch=self.name,
            #                remote_branch=self.upstream_branch.name,
            #                remote=self.upstream_branch.remote.name,
            #                set_upstream=True)
            self.upstream_branch.create(branch=self.local_branch.name)
            self.set_upstream()
            GitOnline.fetch(self.path, prune=True)
            return

        # only remote branch exists
        if self.upstream_branch.exists:
            self.local_branch.create(branch=self.upstream_branch.name,
                                     remote=self.upstream_branch.remote.name)
            # GitOffline.create_local_branch(self.path, self.name,
            #                                branch=self.upstream_branch.name,
            #                                remote=self.upstream_branch.remote)
            return

        # local and remote branches DO NOT exist
        self.upstream_branch.create()
        GitOnline.fetch(self.path, prune=True)
        self.local_branch.create(branch=self.upstream_branch.name,
                                 remote=self.upstream_branch.remote.name)
Пример #24
0
 def is_checked_out(self) -> bool:
     current_sha = GitOffline.current_head_commit_sha(self.path)
     tag_sha = GitOnline.get_remote_tag_sha(self.path, self.name)
     return current_sha == tag_sha
Пример #25
0
 def delete(self) -> None:
     if not self.exists:
         CONSOLE.stdout(f" - Local tag {Format.Git.ref(self.short_ref)} doesn't exist")
         return
     CONSOLE.stdout(f' - Delete local tag {Format.Git.ref(self.short_ref)}')
     GitOffline.delete_local_tag(self.path, name=self.name)
Пример #26
0
 def sha(self) -> str:
     """Commit sha"""
     return GitOffline.get_tag_commit_sha(self.path, self.name)
Пример #27
0
 def rename(self, name: str) -> None:
     CONSOLE.stdout(f' - Rename remote {Format.Git.remote(self.name)} to {Format.Git.remote(name)}')
     GitOffline.rename_remote(self.path, old_name=self.name, new_name=name)
     self.name = name
Пример #28
0
 def create(self, url: str, fetch: bool = False, tags: bool = False) -> None:
     if self.exists:
         CONSOLE.stdout(f' - Remote {Format.Git.remote(self.name)} already exists')
         return
     CONSOLE.stdout(f' - Create remote {Format.Git.remote(self.name)}')
     GitOffline.create_remote(self.path, name=self.name, url=url, fetch=fetch, tags=tags)
Пример #29
0
 def push_url(self) -> str:
     return GitOffline.get_remote_push_url(self.path, self.name)
Пример #30
0
 def fetch_url(self) -> str:
     return GitOffline.get_remote_fetch_url(self.path, self.name)