Example #1
0
def create_repository():
    start_path = os.path.abspath(os.getcwd())
    repo_name = 'git3_test_repository'
    print('Init repo')
    init(repo_name)
    os.chdir(repo_name)
    yield start_path, repo_name
Example #2
0
    def run_before_and_after_tests(self):
        start_path = os.path.abspath(os.getcwd())

        init(self.repo_name)
        os.chdir(self.repo_name)

        # create dirs and write files
        os.mkdir(self.dir_name)

        for file_info in self.file_names_and_content:
            with open(file_info[0], 'w') as f:
                f.write(file_info[1])
        # execute tests
        yield

        os.chdir(start_path)
        try:
            shutil.rmtree(self.repo_name)
        except OSError as e:
            print("Error: %s : %s" % (self.repo_name, e.strerror))
Example #3
0
    def test_create_repo(self):
        result = init(self.repo_name)
        assert result is True
        assert os.path.isdir(os.path.join(self.repo_name, '.git'))

        directories = ['objects', 'refs', 'refs/heads']

        for dir in directories:
            assert os.path.isdir(os.path.join(self.repo_name, '.git', dir))

        # since the repo has been just created, there shouldn't be any files in the heads dir
        assert len(
            glob.glob(
                os.path.join(self.repo_name, '.git', 'refs', 'heads',
                             '*'))) == 0

        # check that the head points to the main branch
        with open(os.path.join(self.repo_name, '.git', 'HEAD'), 'r') as f:
            assert f.read() == 'ref: refs/heads/main'
Example #4
0
 def test_create_repo_in_existing_repo(self):
     result = init()
     assert result is False
Example #5
0
 def test_create_repo_in_dir(self):
     os.mkdir(self.indir_repo_name)
     os.chdir(self.indir_repo_name)
     result = init()
     assert result is True
Example #6
0
 def test_create_another_repo(self):
     result = init(self.repo_name)
     assert result is False
Example #7
0
def main():
    parser = argparse.ArgumentParser()
    sub_parsers = parser.add_subparsers(dest='command', metavar='command')
    sub_parsers.required = True

    # Add
    sub_parser = sub_parsers.add_parser('add', help='add file(s) to index')
    sub_parser.add_argument('paths',
                            nargs='+',
                            metavar='path',
                            help='path(s) of files to add')

    # Branch
    sub_parser = sub_parsers.add_parser('branch',
                                        help='List and Create branches')
    sub_parser.add_argument('-r',
                            '--remotes',
                            action='store_true',
                            help='act on remote-tracking branches')
    sub_parser = sub_parser.add_argument(
        'branchname',
        metavar='<branchname>',
        nargs='?',
        help='Create a new branch named <branchname>')

    # Cat-file
    sub_parser = sub_parsers.add_parser('cat-file',
                                        help='display contents of object')
    valid_modes = ['commit', 'tree', 'blob', 'size', 'type', 'pretty']
    sub_parser.add_argument(
        'mode',
        choices=valid_modes,
        help='object type (commit, tree, blob) or display mode (size, '
        'type, pretty)')
    sub_parser.add_argument(
        'hash_prefix', help='SHA-1 hash (or hash prefix) of object to display')

    # Checkout
    sub_parser = sub_parsers.add_parser('checkout', help='Switch branches')
    sub_parser.add_argument('-b',
                            action='store_true',
                            help='Create a new branch with name new_branch')
    sub_parser.add_argument('branch',
                            metavar='<branch>',
                            help='Checkout to <branch>')

    # Commit
    sub_parser = sub_parsers.add_parser(
        'commit',
        help='commit current state of index to current active branch')
    sub_parser.add_argument(
        '-a',
        '--author',
        help='commit author in format "A U Thor <*****@*****.**>" '
        '(uses GIT_AUTHOR_NAME and GIT_AUTHOR_EMAIL environment '
        'variables by default)')
    sub_parser.add_argument('-m',
                            '--message',
                            required=True,
                            help='text of commit message')

    # Create
    sub_parser = sub_parsers.add_parser('create',
                                        help='create your remote repository')
    valid_networks = ['godwoken', 'mumbai']
    sub_parser.add_argument(
        '-n',
        '--network',
        required=True,
        choices=valid_networks,
        help='Choose which network to interact with. Godwoken Testnet and'
        ' Mumbai are currently supported.')

    # Clone
    sub_parser = sub_parsers.add_parser('clone',
                                        help='create your remote repository')
    sub_parser.add_argument('name', help='name of repository to clone')

    # Diff
    sub_parser = sub_parsers.add_parser(
        'diff',
        help='show diff of files changed (between index and working '
        'copy)')
    sub_parser.add_argument(
        '--staged',
        action='store_true',
        help='This form is to view the changes you staged for the '
        'next commit relative to the HEAD commmit.')

    # Hash-object
    sub_parser = sub_parsers.add_parser(
        'hash-object',
        help='hash contents of given path (and optionally write to '
        'object store)')
    sub_parser.add_argument('path', help='path of file to hash')
    sub_parser.add_argument('-t',
                            choices=['commit', 'tree', 'blob'],
                            default='blob',
                            dest='type',
                            help='type of object (default %(default)r)')
    sub_parser.add_argument(
        '-w',
        action='store_true',
        dest='write',
        help='write object to object store (as well as printing hash)')

    # init
    sub_parser = sub_parsers.add_parser('init', help='initialize a new repo')
    sub_parser.add_argument('repo',
                            nargs='?',
                            default='.',
                            help='directory name for new repo')

    #sub_parser = sub_parsers.add_parser('ls-files',
    #help='list files in index')
    #sub_parser.add_argument('-s', '--stage', action='store_true',
    #help='show object details (mode, hash, and stage number) in '
    #'addition to path')

    # Fetch
    sub_parser = sub_parsers.add_parser(
        'fetch', help='Download object and refs from another repository')
    sub_parser.add_argument('branch', nargs='?', help='branch data to fetch')

    # Get-Address
    sub_parser = sub_parsers.add_parser('get-address',
                                        help='Get Matic wallet address')

    # Merge
    sub_parser = sub_parsers.add_parser(
        'merge', help='Join two or more development histories together')
    sub_parser.add_argument('sourceBranch',
                            nargs='?',
                            help='branch to be merged into the current branch')

    # Push
    sub_parser = sub_parsers.add_parser(
        'push', help='push current active branch to given git server URL')
    #sub_parser.add_argument('git_url',
    #        help='URL of git repo, eg: https://github.com/benhoyt/pygit.git')
    #sub_parser.add_argument('-p', '--password',
    #help='password to use for authentication (uses GIT_PASSWORD '
    #'environment variable by default)')
    #sub_parser.add_argument('-u', '--username',
    #help='username to use for authentication (uses GIT_USERNAME '
    #'environment variable by default)')

    # Pull
    sub_parser = sub_parsers.add_parser('pull', help='pulls remote commits')

    # Status
    sub_parser = sub_parsers.add_parser('status',
                                        help='show status of working copy')

    args = parser.parse_args()
    if args.command == 'add':
        add(args.paths)
    elif args.command == 'branch':
        if args.branchname:
            createBranch(args.command, args.branchname)
        else:
            listBranches(args.remotes)
    elif args.command == 'checkout':
        if args.b is False:
            checkout(args.branch)
        else:
            createBranch('checkout', args.branch)
    elif args.command == 'cat-file':
        try:
            cat_file(args.mode, args.hash_prefix)
        except ValueError as error:
            print(error, file=sys.stderr)
            sys.exit(1)
    elif args.command == 'commit':
        commit(args.message, author=args.author)
    elif args.command == 'create':
        create(args.network)
    elif args.command == 'clone':
        clone(args.name)
    elif args.command == 'diff':
        diff(args.staged)
    elif args.command == 'fetch':
        fetch(args.branch)
    elif args.command == 'get-address':
        address = getAddress()
        print('Your address is: {}'.format(address))
    elif args.command == 'hash-object':
        hashObject(read_file(args.path), args.type, write=args.write)
    elif args.command == 'init':
        init(args.repo)
    elif args.command == 'ls-files':
        ls_files(details=args.stage)
    elif args.command == 'merge':
        merge(args.sourceBranch)
    elif args.command == 'push':
        push()
    elif args.command == 'pull':
        pull()
    elif args.command == 'status':
        status()
    else:
        assert False, 'unexpected command {!r}'.format(args.command)
Example #8
0
def clone(repo_name):
    """
    Cloning a remote repository on the local machine.

    repo_name: Repository to be cloned
    """

    user_address, repo_name = repo_name.split('/')
    network, user_address = user_address.split(':')

    if network != 'mumbai' and network != 'godwoken':
        print(f"Network {network} not supported")
        return

    git_factory = get_factory_contract(network)
    user_key = git_factory.functions.getUserRepoNameHash(
        user_address, repo_name).call()
    user_key = '0x{}'.format(binascii.hexlify(user_key).decode())

    repository = git_factory.functions.getRepository(user_key).call()

    if not repository[0] or repository[1] != repo_name:
        print('No such repository')
        return
    git_repo_address = repository[2]

    branch_contract = get_facet_contract("GitBranch", git_repo_address,
                                         network)

    branches = branch_contract.functions.getBranchNames().call()

    # string, which is going to be written into the .git/packed-refs file
    packed_refs_content = ""
    head_cids = set()

    main_cid = None

    default_branch_name = 'main' if 'main' in branches else branches[0]

    for branch_name in branches:
        branch = branch_contract.functions.getBranch(branch_name).call()
        head_cids.add(branch[1])
        packed_refs_content += '{} refs/remotes/origin/{}\n'.format(
            branch[1], branch_name)
        if branch_name == default_branch_name:
            main_cid = branch[1]

    print('Cloning {:s}'.format(repo_name))
    # initialize repository
    if not init(repo_name):
        return

    # get all remote commits
    for head_cid in head_cids:
        commits = get_all_remote_commits(head_cid)

        # replacing cid with sha1
        packed_refs_content = packed_refs_content.replace(
            head_cid, commits[0]['sha1'])

        # we are going to unpack only the files for the main branch. Commits and all
        # other git objects should be still downloaded
        if head_cid == main_cid:
            # write to refs
            main_ref_path = os.path.join(repo_name, '.git', 'refs', 'heads',
                                         default_branch_name)
            write_file(main_ref_path, (commits[0]['sha1'] + '\n').encode())
            head_ref_path = os.path.join(repo_name, '.git', 'HEAD')
            write_file(
                head_ref_path,
                ('ref: refs/heads/{}\n'.format(default_branch_name)).encode())
            first = True
        else:
            first = False

        for commit in commits:
            unpack_files_of_commit(repo_name, commit, first)
            first = False

    #chaning into repo, also for add function, in order to find the index file
    os.chdir(repo_name)

    # write packed-refs
    write_file('.git/packed-refs', packed_refs_content, binary='')

    write_file('.git/name', str.encode(f"location: {network}:{user_key}"))
    # collecting all files from the repo in order to create the index file
    files_to_add = []
    for path, subdirs, files in os.walk('.'):
        for name in files:
            # we don't want to add the files under .git to the index
            if not path.startswith('./.git'):
                files_to_add.append(os.path.join(path, name)[2:])
    add(files_to_add)
    print('{:s} cloned'.format(repo_name))