def clean(self, *args, **kwargs): super(CodeRepository, self).clean(*args, **kwargs) if not os.path.isdir(self.location): raise ValidationError('Location is not a valid directory') #svn=0 git=1 bzr=2 hg=3 if self.repository_type == 0: try: import pysvn except ImportError: ValidationError('You must install pysvn to use svn repos') elif self.repository_type == 1: try: from dulwich.repo import Repo, NotGitRepository except ImportError: ValidationError('You must install dulwich to use git repos') try: Repo(self.location) except NotGitRepository: raise ValidationError('Location is not a valid git repository') elif self.repository_type == 2: try: from bzrlib import branch, diff, errors except ImportError: raise ValidationError( 'You must install bzrlib to use bazaar repos') try: branch.Branch.open(self.location.rstrip(os.path.sep)) except errors.NotBranchError: raise ValidationError( 'Location is not a valid bazaar repository') elif self.repository_type == 3: try: from mercurial import ui from mercurial.localrepo import localrepository as hg_repo from mercurial.error import RepoError except ImportError: ValidationError('You must install mercurial to use hg repos') try: hg_repo(ui.ui(), path=self.location) except RepoError: raise ValidationError( 'Location is not a valid mercurial repository')
def generate_smoke_entry(inputpath: str, outputpath: str, force: bool = False) -> int: """ Generate repositories with different style in separate branches and its violations. :param inputpath: Path to the tar.gz archive containing initial repositories. :param outputpath: Path to the directory where the generated dataset should be stored. :param force: Override outputpath directory if exists. :return: Success status. 0 if Succeeded, 1 otherwise. """ log = logging.getLogger("styles-gen") if not inputpath.endswith(".tar.xz"): raise ValueError("Input file should be .tar.xz archive.") inputpath = Path(inputpath) outputpath = Path(outputpath) if force and outputpath.exists(): shutil.rmtree(str(outputpath)) try: outputpath.mkdir() except FileExistsError: log.error("Directory %s exists. If you want to override it run with --force flag.", outputpath) return 1 with tarfile.open(str(inputpath)) as tar: tar.extractall(str(outputpath)) repopaths = [x for x in outputpath.iterdir() if x.is_dir()] log.info("Repos found: %s", ", ".join(r.stem for r in repopaths)) with open(str(outputpath / index_filename), "w") as index_file: writer = csv.DictWriter(index_file, fieldnames=["repo", "style", "from", "to"]) writer.writeheader() for style_name, (pattern, repl) in js_format_rules.items(): pattern = re.compile(pattern) for repopath in repopaths: repo = Repo(str(repopath)) repo.hooks.clear() # Speed up dulwich by ~25% for filepath in repopath.glob("**/*.js"): code = filepath.read_text() new_code = re.sub(pattern, repl, code) filepath.write_text(new_code) from_commit, to_commit = commit_style(repo, style_name) writer.writerow({ "repo": repopath.name, "style": style_name, "from": from_commit, "to": to_commit, }) return 0
def log(self, **keywords): branch = keywords["branch"] repo = Repo(self.package.path()) set_head(repo, branch) #commits = repo.revision_history(repo.head()) commits = repo.revision_history(repo.ref("refs/heads/" + branch)) content = "" for commit in commits: content = content + format_commit(commit) self.content = content self.branch = branch self.sha = "" return self.respond()
def send_pack(self, path, determine_wants, generate_pack_contents, progress=None, write_pack=write_pack_objects): """Upload a pack to a remote repository. :param path: Repository path (as bytestring) :param generate_pack_contents: Function that can return a sequence of the shas of the objects to upload. :param progress: Optional progress function :param write_pack: Function called with (file, iterable of objects) to write the objects returned by generate_pack_contents to the server. :raises SendPackError: if server rejects the pack data :raises UpdateRefsError: if the server supports report-status and rejects ref updates :return: new_refs dictionary containing the changes that were made {refname: new_ref}, including deleted refs. """ if not progress: progress = lambda x: None from dulwich.repo import Repo with closing(Repo(path)) as target: old_refs = target.get_refs() new_refs = determine_wants(dict(old_refs)) have = [sha1 for sha1 in old_refs.values() if sha1 != ZERO_SHA] want = [] for refname, new_sha1 in new_refs.items(): if new_sha1 not in have and not new_sha1 in want and new_sha1 != ZERO_SHA: want.append(new_sha1) if not want and set(new_refs.items()).issubset(set(old_refs.items())): return new_refs target.object_store.add_objects(generate_pack_contents(have, want)) for refname, new_sha1 in new_refs.items(): old_sha1 = old_refs.get(refname, ZERO_SHA) if new_sha1 != ZERO_SHA: if not target.refs.set_if_equals(refname, old_sha1, new_sha1): progress('unable to set %s to %s' % (refname, new_sha1)) else: if not target.refs.remove_if_equals(refname, old_sha1): progress('unable to remove %s' % refname) return new_refs
def import_repo(self, name): """Import a repo from a fast-export file in a temporary directory. :param name: The name of the repository export file, relative to dulwich/tests/data/repos. :returns: An initialized Repo object that lives in a temporary directory. """ path = import_repo_to_dir(name) repo = Repo(path) def cleanup(): repo.close() rmtree_ro(os.path.dirname(path.rstrip(os.sep))) self.addCleanup(cleanup) return repo
def __init__( # pylint:disable=W0231 self, root_dir=os.curdir, search_parent_directories=True): from dulwich.errors import NotGitRepository from dulwich.repo import Repo try: if search_parent_directories: self.repo = Repo.discover(start=root_dir) else: self.repo = Repo(root_dir) except NotGitRepository as exc: raise SCMError(f"{root_dir} is not a git repository") from exc self._submodules: Dict[str, "PathInfo"] = self._find_submodules() self._stashes: dict = {}
def test_with_remote_name(self): remote_name = b'origin' outstream = BytesIO() errstream = BytesIO() # create a file for initial commit handle, fullpath = tempfile.mkstemp(dir=self.repo.path) os.close(handle) porcelain.add(repo=self.repo.path, paths=fullpath) porcelain.commit(repo=self.repo.path, message=b'test', author=b'test <email>', committer=b'test <email>') # Setup target repo target_path = tempfile.mkdtemp() self.addCleanup(shutil.rmtree, target_path) target_repo = porcelain.clone(self.repo.path, target=target_path, errstream=errstream) # Capture current refs target_refs = target_repo.get_refs() # create a second file to be pushed handle, fullpath = tempfile.mkstemp(dir=self.repo.path) os.close(handle) porcelain.add(repo=self.repo.path, paths=fullpath) porcelain.commit(repo=self.repo.path, message=b'test2', author=b'test2 <email>', committer=b'test2 <email>') self.assertFalse(self.repo[b'HEAD'].id in target_repo) target_repo.close() # Fetch changes into the cloned repo porcelain.fetch(target_path, self.repo.path, remote_name=remote_name, outstream=outstream, errstream=errstream) # Assert that fetch updated the local image of the remote self.assert_correct_remote_refs( target_repo.get_refs(), self.repo.get_refs()) # Check the target repo for pushed changes, as well as updates # for the refs with Repo(target_path) as r: self.assertTrue(self.repo[b'HEAD'].id in r) self.assertNotEqual(self.repo.get_refs(), target_refs)
def test_clone_no_head(self): temp_dir = self.mkdtemp() self.addCleanup(shutil.rmtree, temp_dir) repo_dir = os.path.join(os.path.dirname(__file__), "data", "repos") dest_dir = os.path.join(temp_dir, "a.git") shutil.copytree(os.path.join(repo_dir, "a.git"), dest_dir, symlinks=True) r = Repo(dest_dir) del r.refs[b"refs/heads/master"] del r.refs[b"HEAD"] t = r.clone(os.path.join(temp_dir, "b.git"), mkdir=True) self.assertEqual( { b"refs/tags/mytag": b"28237f4dc30d0d462658d6b937b08a0f0b6ef55a", b"refs/tags/mytag-packed": b"b0931cadc54336e78a1d980420e3268903b57a50", }, t.refs.as_dict(), )
def test_simple(self): outstream = BytesIO() errstream = BytesIO() # create a file for initial commit handle, fullpath = tempfile.mkstemp(dir=self.repo.path) os.close(handle) filename = os.path.basename(fullpath) porcelain.add(repo=self.repo.path, paths=filename) porcelain.commit(repo=self.repo.path, message=b'test', author=b'test', committer=b'test') # Setup target repo target_path = tempfile.mkdtemp() self.addCleanup(shutil.rmtree, target_path) target_repo = porcelain.clone(self.repo.path, target=target_path, errstream=errstream) target_repo.close() # create a second file to be pushed handle, fullpath = tempfile.mkstemp(dir=self.repo.path) os.close(handle) filename = os.path.basename(fullpath) porcelain.add(repo=self.repo.path, paths=filename) porcelain.commit(repo=self.repo.path, message=b'test2', author=b'test2', committer=b'test2') self.assertTrue(b'refs/heads/master' in self.repo.refs) self.assertTrue(b'refs/heads/master' in target_repo.refs) # Pull changes into the cloned repo porcelain.pull(target_path, self.repo.path, b'refs/heads/master', outstream=outstream, errstream=errstream) # Check the target repo for pushed changes with closing(Repo(target_path)) as r: self.assertEqual(r[b'HEAD'].id, self.repo[b'HEAD'].id)
def run(item: Any, **_kwargs: Any) -> Any: git = find_git(item.path) if git: repo = Repo(git) relpath = Path(str(item.path)[len(git) + 1 if git != "." else 0:]) file_date, author = get_commit(repo, relpath) dir_date, _ = get_commit(repo, relpath.parent) item = evolve( item, author=author, file_date=file_date, dir_date=dir_date, ) return evolve( item, file_mtime=item.path.stat().st_mtime, dir_mtime=item.path.parent.stat().st_mtime, )
def open_repo(name, temp_dir=None): """Open a copy of a repo in a temporary directory. Use this function for accessing repos in dulwich/tests/data/repos to avoid accidentally or intentionally modifying those repos in place. Use tear_down_repo to delete any temp files created. :param name: The name of the repository, relative to dulwich/tests/data/repos :param temp_dir: temporary directory to initialize to. If not provided, a temporary directory will be created. :returns: An initialized Repo object that lives in a temporary directory. """ temp_dir = tempfile.mkdtemp() repo_dir = os.path.join(os.path.dirname(__file__), 'data', 'repos', name) temp_repo_dir = os.path.join(temp_dir, name) shutil.copytree(repo_dir, temp_repo_dir, symlinks=True) return Repo(temp_repo_dir)
def get_version() -> str: """ Return the next version. This is today’s date in the format ``YYYY.MM.DD.MICRO``. ``MICRO`` refers to the number of releases created on this date, starting from ``0``. """ utc_now = datetime.datetime.utcnow() date_format = '%Y.%m.%d' date_str = utc_now.strftime(date_format) local_repository = Repo('.') tag_labels = tag_list(repo=local_repository) tag_labels = [item.decode() for item in tag_labels] today_tag_labels = [ item for item in tag_labels if item.startswith(date_str) ] micro = int(len(today_tag_labels)) return '{date}.{micro}'.format(date=date_str, micro=micro)
def get_commit_details(): """ If there's a '.git' directory besides 'dreampielib', return the current commit (HEAD) id and commit time. Otherwise, return None, None. """ git_dir = join(dirname(dirname(dirname(abspath(__file__)))), '.git') if not isdir(git_dir): return None, None try: from dulwich.repo import Repo except ImportError: return None, None repo = Repo(git_dir) commit_id = repo.refs['HEAD'] commit = repo.commit(commit_id) return commit_id, commit.commit_time
def test_normal_from_repo(self): # Create repo folder = Path.cwd() try: rp = Repo(str(folder)) except NotGitRepository: rp = Repo.init(str(folder)) try: version = rp.head().decode() self.original_revision = version except KeyError: FILE_NAME_TEST = 'file_test.txt' test_file = folder / FILE_NAME_TEST test_file.touch() rp.stage(FILE_NAME_TEST.encode()) version = rp.do_commit(b'Test commit').decode() v = get_source_revision() assert v == version[:10]
def fetch_pack(self, path, determine_wants, graph_walker, pack_data, progress=None): """Retrieve a pack from a git smart server. :param determine_wants: Callback that returns list of commits to fetch :param graph_walker: Object with next() and ack(). :param pack_data: Callback called for each bit of data in the pack :param progress: Callback for progress reports (strings) """ from dulwich.repo import Repo with closing(Repo(path)) as r: objects_iter = r.fetch_objects(determine_wants, graph_walker, progress) # Did the process short-circuit (e.g. in a stateless RPC call)? Note # that the client still expects a 0-object pack in most cases. if objects_iter is None: return write_pack_objects(ProtocolFile(None, pack_data), objects_iter)
def save(self): primer_dir = pathlib.Path(self.confdir) primer_project_dir = primer_dir / 'projects' project_dir = pathlib.Path(self.name) project = self.name if self.base: project_dir = self.base / project_dir if project_dir.exists(): raise exceptions.ProjectFolderExistsError(self.name) if not primer_project_dir.exists(): primer_project_dir.mkdir(parents=True, exist_ok=True) repo = porcelain.init(str(primer_dir)) else: repo = Repo(str(primer_dir)) projects_yml = primer_dir / 'projects.yml' if projects_yml.exists(): with projects_yml.open('r') as yml_file: projects_def = yaml.load(yml_file, Loader=Loader) projects = projects_def['primer']['projects'] if project in projects: raise exceptions.ProjectExistsError(self.name) projects.append(project) else: projects_def = OrderedDict() projects_def['version'] = 1 projects_def['primer'] = {'projects': [self.name]} with projects_yml.open('w') as yml_file: yaml.dump(projects_def, yml_file, default_flow_style=False, Dumper=Dumper) project_dir.mkdir(parents=True, exist_ok=True) header = OrderedDict() header['version'] = 1 header['primer'] = {'repositories': {}, 'directory': str(project_dir)} primer_yml = primer_project_dir / '{}.yml'.format(self.name) with primer_yml.open('w') as yml_file: yaml.dump(header, yml_file, default_flow_style=False, Dumper=Dumper) porcelain.add(repo, primer_yml) porcelain.commit(repo, message="added {}".format(self.name))
def test_simple(self): """ Basic test of porcelain push where self.repo is the remote. First clone the remote, commit a file to the clone, then push the changes back to the remote. """ outstream = BytesIO() errstream = BytesIO() porcelain.commit(repo=self.repo.path, message=b'init', author=b'', committer=b'') # Setup target repo cloned from temp test repo clone_path = tempfile.mkdtemp() self.addCleanup(shutil.rmtree, clone_path) target_repo = porcelain.clone(self.repo.path, target=clone_path, errstream=errstream) target_repo.close() # create a second file to be pushed back to origin handle, fullpath = tempfile.mkstemp(dir=clone_path) os.close(handle) porcelain.add(repo=clone_path, paths=[os.path.basename(fullpath)]) porcelain.commit(repo=clone_path, message=b'push', author=b'', committer=b'') # Setup a non-checked out branch in the remote refs_path = b"refs/heads/foo" self.repo.refs[refs_path] = self.repo[b'HEAD'].id # Push to the remote porcelain.push(clone_path, self.repo.path, b"HEAD:" + refs_path, outstream=outstream, errstream=errstream) # Check that the target and source with closing(Repo(clone_path)) as r_clone: self.assertEqual(r_clone[b'HEAD'].id, self.repo[refs_path].id) # Get the change in the target repo corresponding to the add # this will be in the foo branch. change = list(tree_changes(self.repo, self.repo[b'HEAD'].tree, self.repo[b'refs/heads/foo'].tree))[0] self.assertEqual(os.path.basename(fullpath), change.new.path.decode('ascii'))
def test_bare_local_with_checkout(self): f1_1 = make_object(Blob, data=b'f1') commit_spec = [[1], [2, 1], [3, 1, 2]] trees = {1: [(b'f1', f1_1), (b'f2', f1_1)], 2: [(b'f1', f1_1), (b'f2', f1_1)], 3: [(b'f1', f1_1), (b'f2', f1_1)], } c1, c2, c3 = build_commit_graph(self.repo.object_store, commit_spec, trees) self.repo.refs[b"refs/heads/master"] = c3.id target_path = tempfile.mkdtemp() errstream = BytesIO() self.addCleanup(shutil.rmtree, target_path) r = porcelain.clone(self.repo.path, target_path, bare=True, errstream=errstream) self.assertEqual(r.path, target_path) self.assertEqual(Repo(target_path).head(), c3.id) self.assertFalse(b'f1' in os.listdir(target_path)) self.assertFalse(b'f2' in os.listdir(target_path))
def test_clone_no_head(self): temp_dir = tempfile.mkdtemp() self.addCleanup(shutil.rmtree, temp_dir) repo_dir = os.path.join(os.path.dirname(__file__), 'data', 'repos') dest_dir = os.path.join(temp_dir, 'a.git') shutil.copytree(os.path.join(repo_dir, 'a.git'), dest_dir, symlinks=True) r = Repo(dest_dir) del r.refs["refs/heads/master"] del r.refs["HEAD"] t = r.clone(os.path.join(temp_dir, 'b.git'), mkdir=True) self.assertEqual( { 'refs/tags/mytag': '28237f4dc30d0d462658d6b937b08a0f0b6ef55a', 'refs/tags/mytag-packed': 'b0931cadc54336e78a1d980420e3268903b57a50', }, t.refs.as_dict())
def send_pack(self, path, determine_wants, generate_pack_contents, progress=None, write_pack=write_pack_objects): """Upload a pack to a remote repository. :param path: Repository path (as bytestring) :param generate_pack_contents: Function that can return a sequence of the shas of the objects to upload. :param progress: Optional progress function :param write_pack: Function called with (file, iterable of objects) to write the objects returned by generate_pack_contents to the server. :raises SendPackError: if server rejects the pack data :raises UpdateRefsError: if the server supports report-status and rejects ref updates """ from dulwich.repo import Repo with closing(Repo(path)) as target: old_refs = target.get_refs() new_refs = determine_wants(dict(old_refs)) have = [sha1 for sha1 in old_refs.values() if sha1 != ZERO_SHA] want = [] all_refs = set(new_refs.keys()).union(set(old_refs.keys())) for refname in all_refs: old_sha1 = old_refs.get(refname, ZERO_SHA) new_sha1 = new_refs.get(refname, ZERO_SHA) if new_sha1 not in have and new_sha1 != ZERO_SHA: want.append(new_sha1) if not want and old_refs == new_refs: return new_refs target.object_store.add_objects(generate_pack_contents(have, want)) for name, sha in new_refs.items(): target.refs[name] = sha return new_refs
def test_new_shallow_clone_from_dulwich(self): require_git_version(self.min_single_branch_version) self._source_repo = self.import_repo('server_new.export') self._stub_repo = _StubRepo('shallow') self.addCleanup(tear_down_repo, self._stub_repo) port = self._start_server(self._source_repo) # Fetch at depth 1 run_git_or_fail([ 'clone', '--mirror', '--depth=1', '--no-single-branch', self.url(port), self._stub_repo.path ]) clone = self._stub_repo = Repo(self._stub_repo.path) expected_shallow = [ b'94de09a530df27ac3bb613aaecdd539e0a0655e1', b'da5cd81e1883c62a25bb37c4d1f8ad965b29bf8d' ] self.assertEqual(expected_shallow, _get_shallow(clone)) self.assertReposNotEqual(clone, self._source_repo)
def test_new_shallow_clone_from_dulwich(self): require_git_version(self.min_single_branch_version) self._source_repo = self.import_repo('server_new.export') self._stub_repo = _StubRepo('shallow') self.addCleanup(tear_down_repo, self._stub_repo) port = self._start_server(self._source_repo) # Fetch at depth 1 run_git_or_fail([ 'clone', '--mirror', '--depth=1', '--no-single-branch', self.url(port), self._stub_repo.path ]) clone = self._stub_repo = Repo(self._stub_repo.path) expected_shallow = [ b'35e0b59e187dd72a0af294aedffc213eaa4d03ff', b'514dc6d3fbfe77361bcaef320c4d21b72bc10be9' ] self.assertEqual(expected_shallow, _get_shallow(clone)) self.assertReposNotEqual(clone, self._source_repo)
def test_simple_local(self): f1_1 = make_object(Blob, data='f1') commit_spec = [[1], [2, 1], [3, 1, 2]] trees = {1: [('f1', f1_1), ('f2', f1_1)], 2: [('f1', f1_1), ('f2', f1_1)], 3: [('f1', f1_1), ('f2', f1_1)], } c1, c2, c3 = build_commit_graph(self.repo.object_store, commit_spec, trees) self.repo.refs["refs/heads/master"] = c3.id target_path = tempfile.mkdtemp() outstream = StringIO() self.addCleanup(shutil.rmtree, target_path) r = porcelain.clone(self.repo.path, target_path, checkout=False, outstream=outstream) self.assertEquals(r.path, target_path) self.assertEquals(Repo(target_path).head(), c3.id) self.assertTrue('f1' not in os.listdir(target_path)) self.assertTrue('f2' not in os.listdir(target_path))
def main(argv=sys.argv): """Entry point for starting an HTTP git server.""" if len(argv) > 1: gitdir = argv[1] else: gitdir = os.getcwd() # TODO: allow serving on other addresses/ports via command-line flag listen_addr='' port = 8000 log_utils.default_logging_config() backend = DictBackend({'/': Repo(gitdir)}) app = make_wsgi_chain(backend) server = make_server(listen_addr, port, app, handler_class=HTTPGitRequestHandler) logger.info('Listening for HTTP connections on %s:%d', listen_addr, port) server.serve_forever()
def dbBlock(args, api=False, toggle=True): # Retrieve user record db = TinyDB(args.userdb, **db_format) User = Query() if api: table = db.table('api_users') else: table = db if toggle: verb = ('Block', 'Blocking', 'blocked') else: verb = ('Unblock', 'Unblocking', 'unblocked') user_list = table.search(User.userid == args.userid) status = len(user_list) if status < 1: print('User {} not found. Exiting.'.format(args.userid)) sys.exit(1) elif status > 1: print('ID not unique. Is there a problem in the database?') sys.exit(2) print('{} user {}...'.format(verb[1], args.userid)) user = user_list[0] # Update user record table.update({'blocked': toggle}, doc_ids=[user.doc_id]) # Add file to Git index try: repo = Repo(os.path.dirname(args.userdb)) except NotGitRepository: repo = Repo.init(os.path.dirname(args.userdb)) git.add(repo=repo, paths=[args.userdb]) # Prepare commit information committer = 'MSCWG <{}>'.format(mscwg_email).encode('utf8') author = committer message = ('{} user {}\n\nChanged by dbctl.py'.format( verb[0], args.userid).encode('utf8')) # Execute commit git.commit(repo, message=message, author=author, committer=committer) print('\nUser successfully {}'.format(verb[2]))
def log(self, *virtual_path, **keywords): branch = "master" if "branch" in keywords: branch = keywords["branch"] sha = None if "sha" in keywords: sha = keywords["sha"] path_to_lookup = self.filename content = "" repo = Repo(self.package.path()) #get a list of all commits all_commits = get_all_commits(repo, branch, commits_to_avoid=set([]), start=None) relevant_commits = list() last_blob_id = None for commit in all_commits: #get the actual commit commit = repo.get_object(commit) #get the tree tree_id = commit.tree #tree = repo.get_object(tree) #check the blob #note it may not be in the tree try: blob_id = dulwich.object_store.tree_lookup_path(repo.get_object, tree_id, path_to_lookup)[1] if not (blob_id == last_blob_id): last_blob_id = blob_id relevant_commits.append((commit, blob_id)) except KeyError: pass #the file wasn't in the tree at that time #now you have a list of relevant commits #make up some output for commit in relevant_commits: actual_commit = commit[0] content = content + "<hr><br /><br />view this version: <a href=\"/package/" + self.package.name + ":" + branch + "/" + path_to_lookup + "/" + commit[1] + "\">" + commit[1] + "</a><br />" + format_commit(actual_commit.as_pretty_string()) self.branch = branch self.sha = sha self.content = content return self.respond()
def GitUpload(file, Name, Email, Password, Repository, Message="Some uploads"): origin_uris = Repository if not origin_uris.startswith(Name): origin_uris = Name + "/" + origin_uris if not origin_uris.startswith("https://github.com/"): origin_uris = "https://github.com/" + origin_uris if not origin_uris.endswith(".git"): origin_uris = origin_uris + ".git" path = os.getcwd() # Gittle.clone() 会将当前目录下的文件下载到本地,并初始化git工作路径,上传文件正常 # repo = Gittle.clone("https://github.com/fengfeng0918/gittle.git", path) # Gittle.init() 初始化git工作路径,并没有将远程仓库信息拉到本地,上传(push)文件时会将远程库清空 # repo = Gittle.init(path,origin_uri="https://github.com/fengfeng0918/gittle.git") # git init 以下流程正常!!! if not os.path.exists(".git"): local_repo = Gittle.init(path) # local_repo = Gittle.clone(origin_uris,path) bares = False #不会删除远端,重写本地 else: local_repo = Repo(path) bares = True # 不会删除远端,不重写本地 repo = Gittle(local_repo, origin_uris) repo.fetch(bare=bares) # Stage file if not isinstance(file, list): file = [file] repo.stage(file) # Commiting repo.commit(name=Name, email=Email, message=Message, files=file) # add remote repo.add_remote('origin', origin_uris) # Push repo.auth(username=Name, password=Password) # Auth for pushing repo.push()
def view_file(self, *virtual_path, **keywords): branch = "master" desired_view = "default" sha = None if "sha" in keywords: sha = keywords["sha"] elif hasattr(self, "sha"): sha = self.sha if "branch" in keywords: branch = keywords["branch"] if "desired_view" in keywords: desired_view = keywords["desired_view"] if self.package is None: raise cherrypy.NotFound() if not (desired_view in self.acceptable_views): raise cherrypy.NotFound() #create the dulwich.repo.Repo object repo = Repo(self.package.path()) #switch to the right refspec set_head(repo, branch) #reconstruct the filename filename = self.filename #get the sha if it wasn't passed to us try: if not sha: sha = dulwich.object_store.tree_lookup_path(repo.get_object, repo.get_object(repo.ref("refs/heads/" + branch)).tree, filename)[1] obj = repo.get_object(sha) except IndexError: raise cherrypy.NotFound() except KeyError: raise cherrypy.NotFound() output = str(obj.as_pretty_string()) #determine the MIME type mime_type = "text/plain" #try: # if filename.count(".") > 0: # extension = filename.split(".")[-1] # mime_type = mimetypes.types_map["." + extension] #except KeyError: # mime_type = "text/plain" #set the MIME type #cherrypy.response.headers["Content-Type"] = mime_type self.content = "<pre>" + output + "</pre>" self.branch = branch return self.respond()
def checkout(path, url, bare=True): """ Either clones a new git repo from URL into path (if it didn't already exist), or else fetches new content from URL into repo at path (if it did already exist). In either case returns a Dulwich Repo object on path. """ abspath = Path(path).resolve() cfgpath = abspath / ("config" if bare else ".git/config") abspath = str(abspath) if cfgpath.exists(): print("Fetching {}".format(url)) # QQQ Dulwich fetch() is broken # dulwich.porcelain.fetch(abspath, url) check_call(['git', 'fetch', '--all'], cwd=path) else: print("Cloning {}".format(url)) dulwich.porcelain.clone(url, target=abspath, bare=bare) return Repo(abspath)
def branches(self, **keywords): sha, branch, filename = keywords["sha"], keywords["branch"], keywords["filename"] repo = Repo(self.package.path()) data = repo.get_refs() valid_keys = [] for key in data.keys(): if key[0:11] == "refs/heads/": valid_keys.append((key[11:], data[key])) content = "" for key in valid_keys: content = content + "<a href=\"/package/" + self.package.name + ":" + key[0] + "/\">" + key[0] + "</a><br />" self.content = content self.branch = branch self.sha = sha return self.respond()