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
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))
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'
def test_create_repo_in_existing_repo(self): result = init() assert result is False
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
def test_create_another_repo(self): result = init(self.repo_name) assert result is False
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)
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))