Dulwich.io dulwich / aa73abc
Port remainder of docstrings to Google style. Jelmer Vernooń≥ 2 months ago
20 changed file(s) with 741 addition(s) and 556 deletion(s). Raw diff Collapse all Expand all
6161 /**
6262 * Get the entries of a tree, prepending the given path.
6363 *
64 * :param path: The path to prepend, without trailing slashes.
65 * :param path_len: The length of path.
66 * :param tree: The Tree object to iterate.
67 * :param n: Set to the length of result.
68 * :return: A (C) array of PyObject pointers to TreeEntry objects for each path
64 * Args:
65 * path: The path to prepend, without trailing slashes.
66 * path_len: The length of path.
67 * tree: The Tree object to iterate.
68 * n: Set to the length of result.
69 * Returns: A (C) array of PyObject pointers to TreeEntry objects for each path
6970 * in tree.
7071 */
7172 static PyObject **tree_entries(char *path, Py_ssize_t path_len, PyObject *tree,
174174 def itersections(self):
175175 """Iterate over the sections.
176176
177 :return: Iterator over section tuples
177 Returns: Iterator over section tuples
178178 """
179179 raise NotImplementedError(self.itersections)
180180
355355 def test_root_exists(self):
356356 """Check that Swift container exist
357357
358 :return: True if exist or None it not
358 Returns: True if exist or None it not
359359 """
360360 ret = self.httpclient.request('HEAD', self.base_path)
361361 if ret.status_code == 404:
368368 def create_root(self):
369369 """Create the Swift container
370370
371 :raise: `SwiftException` if unable to create
371 Raises:
372 SwiftException: if unable to create
372373 """
373374 if not self.test_root_exists():
374375 ret = self.httpclient.request('PUT', self.base_path)
379380 def get_container_objects(self):
380381 """Retrieve objects list in a container
381382
382 :return: A list of dict that describe objects
383 Returns: A list of dict that describe objects
383384 or None if container does not exist
384385 """
385386 qs = '?format=json'
487488 def del_root(self):
488489 """Delete the root container by removing container content
489490
490 :raise: `SwiftException` if unable to delete
491 Raises:
492 SwiftException: if unable to delete
491493 """
492494 for obj in self.get_container_objects():
493495 self.del_object(obj['name'])
565567 def read_checksum(self):
566568 """Read the checksum from the pack
567569
568 :return: the checksum bytestring
570 Returns: the checksum bytestring
569571 """
570572 return self.scon.get_object(self.filename, range="-20")
571573
680682 def iter_shas(self, finder):
681683 """An iterator over pack's ObjectStore.
682684
683 :return: a `ObjectStoreIterator` or `GreenThreadsObjectStoreIterator`
685 Returns: a `ObjectStoreIterator` or `GreenThreadsObjectStoreIterator`
684686 instance if gevent is enabled
685687 """
686688 shas = iter(finder.next, None)
724726 def add_pack(self):
725727 """Add a new pack to this object store.
726728
727 :return: Fileobject to write to and a commit function to
729 Returns: Fileobject to write to and a commit function to
728730 call when the pack is finished.
729731 """
730732 f = BytesIO()
937939 def _determine_file_mode(self):
938940 """Probe the file-system to determine whether permissions can be trusted.
939941
940 :return: True if permissions can be trusted, False otherwise.
942 Returns: True if permissions can be trusted, False otherwise.
941943 """
942944 return False
943945
6868 def GitFile(filename, mode='rb', bufsize=-1):
6969 """Create a file object that obeys the git file locking protocol.
7070
71 :return: a builtin file object or a _GitFile object
71 Returns: a builtin file object or a _GitFile object
7272
73 :note: See _GitFile for a description of the file locking protocol.
73 Note: See _GitFile for a description of the file locking protocol.
7474
7575 Only read-only and write-only (binary) modes are supported; r+, w+, and a
7676 are not. To read and write from the same file, you can take advantage of
105105 directory, and the lockfile will be renamed to overwrite the original file
106106 on close.
107107
108 :note: You *must* call close() or abort() on a _GitFile for the lock to be
108 Note: You *must* call close() or abort() on a _GitFile for the lock to be
109109 released. Typically this will happen in a finally block.
110110 """
111111
156156 def close(self):
157157 """Close this file, saving the lockfile over the original.
158158
159 :note: If this method fails, it will attempt to delete the lockfile.
159 Note: If this method fails, it will attempt to delete the lockfile.
160160 However, it is not guaranteed to do so (e.g. if a filesystem
161161 becomes suddenly read-only), which will prevent future writes to
162162 this file until the lockfile is removed manually.
163 :raises OSError: if the original file could not be overwritten. The
163 Raises:
164 OSError: if the original file could not be overwritten. The
164165 lock file is still closed, so further attempts to write to the same
165166 file object will raise ValueError.
166167 """
212212
213213 For directories, include a trailing slash.
214214
215 :return: status is None if file is not mentioned, True if it is
215 Returns: status is None if file is not mentioned, True if it is
216216 included, False if it is explicitly excluded.
217217 """
218218 status = None
4040 encoding=None):
4141 """Write a individual file patch.
4242
43 :param commit: Commit object
44 :param progress: Tuple with current patch number and total.
45 :return: tuple with filename and contents
43 Args:
44 commit: Commit object
45 progress: Tuple with current patch number and total.
46 Returns:
47 tuple with filename and contents
4648 """
4749 encoding = encoding or getattr(f, "encoding", "ascii")
4850 if isinstance(contents, str):
7981 def get_summary(commit):
8082 """Determine the summary line for use in a filename.
8183
82 :param commit: Commit
83 :return: Summary string
84 Args:
85 commit: Commit
86 Returns: Summary string
8487 """
8588 decoded = commit.message.decode(errors='replace')
8689 return decoded.splitlines()[0].replace(" ", "-")
152155 def is_binary(content):
153156 """See if the first few bytes contain any null characters.
154157
155 :param content: Bytestring to check for binary content
158 Args:
159 content: Bytestring to check for binary content
156160 """
157161 return b'\0' in content[:FIRST_FEW_BYTES]
158162
174178 def write_object_diff(f, store, old_file, new_file, diff_binary=False):
175179 """Write the diff for an object.
176180
177 :param f: File-like object to write to
178 :param store: Store to retrieve objects from, if necessary
179 :param old_file: (path, mode, hexsha) tuple
180 :param new_file: (path, mode, hexsha) tuple
181 :param diff_binary: Whether to diff files even if they
181 Args:
182 f: File-like object to write to
183 store: Store to retrieve objects from, if necessary
184 old_file: (path, mode, hexsha) tuple
185 new_file: (path, mode, hexsha) tuple
186 diff_binary: Whether to diff files even if they
182187 are considered binary files by is_binary().
183188
184 :note: the tuple elements should be None for nonexistant files
189 Note: the tuple elements should be None for nonexistant files
185190 """
186191 (old_path, old_mode, old_id) = old_file
187192 (new_path, new_mode, new_id) = new_file
224229 def gen_diff_header(paths, modes, shas):
225230 """Write a blob diff header.
226231
227 :param paths: Tuple with old and new path
228 :param modes: Tuple with old and new modes
229 :param shas: Tuple with old and new shas
232 Args:
233 paths: Tuple with old and new path
234 modes: Tuple with old and new modes
235 shas: Tuple with old and new shas
230236 """
231237 (old_path, new_path) = paths
232238 (old_mode, new_mode) = modes
256262 def write_blob_diff(f, old_file, new_file):
257263 """Write blob diff.
258264
259 :param f: File-like object to write to
260 :param old_file: (path, mode, hexsha) tuple (None if nonexisting)
261 :param new_file: (path, mode, hexsha) tuple (None if nonexisting)
262
263 :note: The use of write_object_diff is recommended over this function.
265 Args:
266 f: File-like object to write to
267 old_file: (path, mode, hexsha) tuple (None if nonexisting)
268 new_file: (path, mode, hexsha) tuple (None if nonexisting)
269
270 Note: The use of write_object_diff is recommended over this function.
264271 """
265272 (old_path, old_mode, old_blob) = old_file
266273 (new_path, new_mode, new_blob) = new_file
284291 def write_tree_diff(f, store, old_tree, new_tree, diff_binary=False):
285292 """Write tree diff.
286293
287 :param f: File-like object to write to.
288 :param old_tree: Old tree id
289 :param new_tree: New tree id
290 :param diff_binary: Whether to diff files even if they
294 Args:
295 f: File-like object to write to.
296 old_tree: Old tree id
297 new_tree: New tree id
298 diff_binary: Whether to diff files even if they
291299 are considered binary files by is_binary().
292300 """
293301 changes = store.tree_changes(old_tree, new_tree)
299307 def git_am_patch_split(f, encoding=None):
300308 """Parse a git-am-style patch and split it up into bits.
301309
302 :param f: File-like object to parse
303 :param encoding: Encoding to use when creating Git objects
304 :return: Tuple with commit object, diff contents and git version
310 Args:
311 f: File-like object to parse
312 encoding: Encoding to use when creating Git objects
313 Returns: Tuple with commit object, diff contents and git version
305314 """
306315 encoding = encoding or getattr(f, "encoding", "ascii")
307316 encoding = encoding or "ascii"
319328 def parse_patch_message(msg, encoding=None):
320329 """Extract a Commit object and patch from an e-mail message.
321330
322 :param msg: An email message (email.message.Message)
323 :param encoding: Encoding to use to encode Git commits
324 :return: Tuple with commit object, diff contents and git version
331 Args:
332 msg: An email message (email.message.Message)
333 encoding: Encoding to use to encode Git commits
334 Returns: Tuple with commit object, diff contents and git version
325335 """
326336 c = Commit()
327337 c.author = msg["from"].encode(encoding)
198198 """Convert a path to a path usable in an index, e.g. bytes and relative to
199199 the repository root.
200200
201 :param repopath: Repository path, absolute or relative to the cwd
202 :param path: A path, absolute or relative to the cwd
203 :return: A path formatted for use in e.g. an index
201 Args:
202 repopath: Repository path, absolute or relative to the cwd
203 path: A path, absolute or relative to the cwd
204 Returns: A path formatted for use in e.g. an index
204205 """
205206 if not isinstance(path, bytes):
206207 path = path.encode(sys.getfilesystemencoding())
218219 errstream=default_bytes_err_stream):
219220 """Create an archive.
220221
221 :param repo: Path of repository for which to generate an archive.
222 :param committish: Commit SHA1 or ref to use
223 :param outstream: Output stream (defaults to stdout)
224 :param errstream: Error stream (defaults to stderr)
222 Args:
223 repo: Path of repository for which to generate an archive.
224 committish: Commit SHA1 or ref to use
225 outstream: Output stream (defaults to stdout)
226 errstream: Error stream (defaults to stderr)
225227 """
226228
227229 if committish is None:
237239 def update_server_info(repo="."):
238240 """Update server info files for a repository.
239241
240 :param repo: path to the repository
242 Args:
243 repo: path to the repository
241244 """
242245 with open_repo_closing(repo) as r:
243246 server_update_server_info(r)
246249 def symbolic_ref(repo, ref_name, force=False):
247250 """Set git symbolic ref into HEAD.
248251
249 :param repo: path to the repository
250 :param ref_name: short name of the new ref
251 :param force: force settings without checking if it exists in refs/heads
252 Args:
253 repo: path to the repository
254 ref_name: short name of the new ref
255 force: force settings without checking if it exists in refs/heads
252256 """
253257 with open_repo_closing(repo) as repo_obj:
254258 ref_path = _make_branch_ref(ref_name)
260264 def commit(repo=".", message=None, author=None, committer=None, encoding=None):
261265 """Create a new commit.
262266
263 :param repo: Path to repository
264 :param message: Optional commit message
265 :param author: Optional author name and email
266 :param committer: Optional committer name and email
267 :return: SHA1 of the new commit
267 Args:
268 repo: Path to repository
269 message: Optional commit message
270 author: Optional author name and email
271 committer: Optional committer name and email
272 Returns: SHA1 of the new commit
268273 """
269274 # FIXME: Support --all argument
270275 # FIXME: Support --signoff argument
283288 def commit_tree(repo, tree, message=None, author=None, committer=None):
284289 """Create a new commit object.
285290
286 :param repo: Path to repository
287 :param tree: An existing tree object
288 :param author: Optional author name and email
289 :param committer: Optional committer name and email
291 Args:
292 repo: Path to repository
293 tree: An existing tree object
294 author: Optional author name and email
295 committer: Optional committer name and email
290296 """
291297 with open_repo_closing(repo) as r:
292298 return r.do_commit(
296302 def init(path=".", bare=False):
297303 """Create a new git repository.
298304
299 :param path: Path to repository.
300 :param bare: Whether to create a bare repository.
301 :return: A Repo instance
305 Args:
306 path: Path to repository.
307 bare: Whether to create a bare repository.
308 Returns: A Repo instance
302309 """
303310 if not os.path.exists(path):
304311 os.mkdir(path)
314321 origin=b"origin", depth=None, **kwargs):
315322 """Clone a local or remote git repository.
316323
317 :param source: Path or URL for source repository
318 :param target: Path to target repository (optional)
319 :param bare: Whether or not to create a bare repository
320 :param checkout: Whether or not to check-out HEAD after cloning
321 :param errstream: Optional stream to write progress to
322 :param outstream: Optional stream to write progress to (deprecated)
323 :param origin: Name of remote from the repository used to clone
324 :param depth: Depth to fetch at
325 :return: The new repository
324 Args:
325 source: Path or URL for source repository
326 target: Path to target repository (optional)
327 bare: Whether or not to create a bare repository
328 checkout: Whether or not to check-out HEAD after cloning
329 errstream: Optional stream to write progress to
330 outstream: Optional stream to write progress to (deprecated)
331 origin: Name of remote from the repository used to clone
332 depth: Depth to fetch at
333 Returns: The new repository
326334 """
327335 # TODO(jelmer): This code overlaps quite a bit with Repo.clone
328336 if outstream is not None:
382390 def add(repo=".", paths=None):
383391 """Add files to the staging area.
384392
385 :param repo: Repository for the files
386 :param paths: Paths to add. No value passed stages all modified files.
387 :return: Tuple with set of added files and ignored files
393 Args:
394 repo: Repository for the files
395 paths: Paths to add. No value passed stages all modified files.
396 Returns: Tuple with set of added files and ignored files
388397 """
389398 ignored = set()
390399 with open_repo_closing(repo) as r:
425434
426435 Equivalent to running `git clean -fd` in target_dir.
427436
428 :param repo: Repository where the files may be tracked
429 :param target_dir: Directory to clean - current directory if None
437 Args:
438 repo: Repository where the files may be tracked
439 target_dir: Directory to clean - current directory if None
430440 """
431441 if target_dir is None:
432442 target_dir = os.getcwd()
462472 def remove(repo=".", paths=None, cached=False):
463473 """Remove files from the staging area.
464474
465 :param repo: Repository for the files
466 :param paths: Paths to remove
475 Args:
476 repo: Repository for the files
477 paths: Paths to remove
467478 """
468479 with open_repo_closing(repo) as r:
469480 index = r.open_index()
517528 def print_commit(commit, decode, outstream=sys.stdout):
518529 """Write a human-readable commit log entry.
519530
520 :param commit: A `Commit` object
521 :param outstream: A stream file to write to
531 Args:
532 commit: A `Commit` object
533 outstream: A stream file to write to
522534 """
523535 outstream.write("-" * 50 + "\n")
524536 outstream.write("commit: " + commit.id.decode('ascii') + "\n")
542554 def print_tag(tag, decode, outstream=sys.stdout):
543555 """Write a human-readable tag.
544556
545 :param tag: A `Tag` object
546 :param decode: Function for decoding bytes to unicode string
547 :param outstream: A stream to write to
557 Args:
558 tag: A `Tag` object
559 decode: Function for decoding bytes to unicode string
560 outstream: A stream to write to
548561 """
549562 outstream.write("Tagger: " + decode(tag.tagger) + "\n")
550563 time_tuple = time.gmtime(tag.tag_time + tag.tag_timezone)
559572 def show_blob(repo, blob, decode, outstream=sys.stdout):
560573 """Write a blob to a stream.
561574
562 :param repo: A `Repo` object
563 :param blob: A `Blob` object
564 :param decode: Function for decoding bytes to unicode string
565 :param outstream: A stream file to write to
575 Args:
576 repo: A `Repo` object
577 blob: A `Blob` object
578 decode: Function for decoding bytes to unicode string
579 outstream: A stream file to write to
566580 """
567581 outstream.write(decode(blob.data))
568582
570584 def show_commit(repo, commit, decode, outstream=sys.stdout):
571585 """Show a commit to a stream.
572586
573 :param repo: A `Repo` object
574 :param commit: A `Commit` object
575 :param decode: Function for decoding bytes to unicode string
576 :param outstream: Stream to write to
587 Args:
588 repo: A `Repo` object
589 commit: A `Commit` object
590 decode: Function for decoding bytes to unicode string
591 outstream: Stream to write to
577592 """
578593 print_commit(commit, decode=decode, outstream=outstream)
579594 if commit.parents:
594609 def show_tree(repo, tree, decode, outstream=sys.stdout):
595610 """Print a tree to a stream.
596611
597 :param repo: A `Repo` object
598 :param tree: A `Tree` object
599 :param decode: Function for decoding bytes to unicode string
600 :param outstream: Stream to write to
612 Args:
613 repo: A `Repo` object
614 tree: A `Tree` object
615 decode: Function for decoding bytes to unicode string
616 outstream: Stream to write to
601617 """
602618 for n in tree:
603619 outstream.write(decode(n) + "\n")
606622 def show_tag(repo, tag, decode, outstream=sys.stdout):
607623 """Print a tag to a stream.
608624
609 :param repo: A `Repo` object
610 :param tag: A `Tag` object
611 :param decode: Function for decoding bytes to unicode string
612 :param outstream: Stream to write to
625 Args:
626 repo: A `Repo` object
627 tag: A `Tag` object
628 decode: Function for decoding bytes to unicode string
629 outstream: Stream to write to
613630 """
614631 print_tag(tag, decode, outstream)
615632 show_object(repo, repo[tag.object[1]], decode, outstream)
658675 reverse=False, name_status=False):
659676 """Write commit logs.
660677
661 :param repo: Path to repository
662 :param paths: Optional set of specific paths to print entries for
663 :param outstream: Stream to write log output to
664 :param reverse: Reverse order in which entries are printed
665 :param name_status: Print name status
666 :param max_entries: Optional maximum number of entries to display
678 Args:
679 repo: Path to repository
680 paths: Optional set of specific paths to print entries for
681 outstream: Stream to write log output to
682 reverse: Reverse order in which entries are printed
683 name_status: Print name status
684 max_entries: Optional maximum number of entries to display
667685 """
668686 with open_repo_closing(repo) as r:
669687 walker = r.get_walker(
682700 default_encoding=DEFAULT_ENCODING):
683701 """Print the changes in a commit.
684702
685 :param repo: Path to repository
686 :param objects: Objects to show (defaults to [HEAD])
687 :param outstream: Stream to write to
688 :param default_encoding: Default encoding to use if none is set in the
703 Args:
704 repo: Path to repository
705 objects: Objects to show (defaults to [HEAD])
706 outstream: Stream to write to
707 default_encoding: Default encoding to use if none is set in the
689708 commit
690709 """
691710 if objects is None:
707726 def diff_tree(repo, old_tree, new_tree, outstream=sys.stdout):
708727 """Compares the content and mode of blobs found via two tree objects.
709728
710 :param repo: Path to repository
711 :param old_tree: Id of old tree
712 :param new_tree: Id of new tree
713 :param outstream: Stream to write to
729 Args:
730 repo: Path to repository
731 old_tree: Id of old tree
732 new_tree: Id of new tree
733 outstream: Stream to write to
714734 """
715735 with open_repo_closing(repo) as r:
716736 write_tree_diff(outstream, r.object_store, old_tree, new_tree)
719739 def rev_list(repo, commits, outstream=sys.stdout):
720740 """Lists commit objects in reverse chronological order.
721741
722 :param repo: Path to repository
723 :param commits: Commits over which to iterate
724 :param outstream: Stream to write to
742 Args:
743 repo: Path to repository
744 commits: Commits over which to iterate
745 outstream: Stream to write to
725746 """
726747 with open_repo_closing(repo) as r:
727748 for entry in r.get_walker(include=[r[c].id for c in commits]):
741762 sign=False):
742763 """Creates a tag in git via dulwich calls:
743764
744 :param repo: Path to repository
745 :param tag: tag string
746 :param author: tag author (optional, if annotated is set)
747 :param message: tag message (optional)
748 :param annotated: whether to create an annotated tag
749 :param objectish: object the tag should point at, defaults to HEAD
750 :param tag_time: Optional time for annotated tag
751 :param tag_timezone: Optional timezone for annotated tag
752 :param sign: GPG Sign the tag
765 Args:
766 repo: Path to repository
767 tag: tag string
768 author: tag author (optional, if annotated is set)
769 message: tag message (optional)
770 annotated: whether to create an annotated tag
771 objectish: object the tag should point at, defaults to HEAD
772 tag_time: Optional time for annotated tag
773 tag_timezone: Optional timezone for annotated tag
774 sign: GPG Sign the tag
753775 """
754776
755777 with open_repo_closing(repo) as r:
797819 def tag_list(repo, outstream=sys.stdout):
798820 """List all tags.
799821
800 :param repo: Path to repository
801 :param outstream: Stream to write tags to
822 Args:
823 repo: Path to repository
824 outstream: Stream to write tags to
802825 """
803826 with open_repo_closing(repo) as r:
804827 tags = sorted(r.refs.as_dict(b"refs/tags"))
808831 def tag_delete(repo, name):
809832 """Remove a tag.
810833
811 :param repo: Path to repository
812 :param name: Name of tag to remove
834 Args:
835 repo: Path to repository
836 name: Name of tag to remove
813837 """
814838 with open_repo_closing(repo) as r:
815839 if isinstance(name, bytes):
825849 def reset(repo, mode, treeish="HEAD"):
826850 """Reset current HEAD to the specified state.
827851
828 :param repo: Path to repository
829 :param mode: Mode ("hard", "soft", "mixed")
830 :param treeish: Treeish to reset to
852 Args:
853 repo: Path to repository
854 mode: Mode ("hard", "soft", "mixed")
855 treeish: Treeish to reset to
831856 """
832857
833858 if mode != "hard":
843868 errstream=default_bytes_err_stream, **kwargs):
844869 """Remote push with dulwich via dulwich.client
845870
846 :param repo: Path to repository
847 :param remote_location: Location of the remote
848 :param refspecs: Refs to push to remote
849 :param outstream: A stream file to write output
850 :param errstream: A stream file to write errors
871 Args:
872 repo: Path to repository
873 remote_location: Location of the remote
874 refspecs: Refs to push to remote
875 outstream: A stream file to write output
876 errstream: A stream file to write errors
851877 """
852878
853879 # Open the repo
890916 errstream=default_bytes_err_stream, **kwargs):
891917 """Pull from remote via dulwich.client
892918
893 :param repo: Path to repository
894 :param remote_location: Location of the remote
895 :param refspec: refspecs to fetch
896 :param outstream: A stream file to write to output
897 :param errstream: A stream file to write to errors
919 Args:
920 repo: Path to repository
921 remote_location: Location of the remote
922 refspec: refspecs to fetch
923 outstream: A stream file to write to output
924 errstream: A stream file to write to errors
898925 """
899926 # Open the repo
900927 with open_repo_closing(repo) as r:
927954 def status(repo=".", ignored=False):
928955 """Returns staged, unstaged, and untracked changes relative to the HEAD.
929956
930 :param repo: Path to repository or repository object
931 :param ignored: Whether to include ignored files in `untracked`
932 :return: GitStatus tuple,
957 Args:
958 repo: Path to repository or repository object
959 ignored: Whether to include ignored files in `untracked`
960 Returns: GitStatus tuple,
933961 staged - dict with lists of staged paths (diff index/HEAD)
934962 unstaged - list of unstaged paths (diff index/working-tree)
935963 untracked - list of untracked, un-ignored & non-.git paths
958986 def _walk_working_dir_paths(frompath, basepath):
959987 """Get path, is_dir for files in working dir from frompath
960988
961 :param frompath: Path to begin walk
962 :param basepath: Path to compare to
989 Args:
990 frompath: Path to begin walk
991 basepath: Path to compare to
963992 """
964993 for dirpath, dirnames, filenames in os.walk(frompath):
965994 # Skip .git and below.
9831012 def get_untracked_paths(frompath, basepath, index):
9841013 """Get untracked paths.
9851014
1015 Args:
9861016 ;param frompath: Path to walk
987 :param basepath: Path to compare to
988 :param index: Index to check against
1017 basepath: Path to compare to
1018 index: Index to check against
9891019 """
9901020 for ap, is_dir in _walk_working_dir_paths(frompath, basepath):
9911021 if not is_dir:
9971027 def get_tree_changes(repo):
9981028 """Return add/delete/modify changes to tree by comparing index to HEAD.
9991029
1000 :param repo: repo path or object
1001 :return: dict with lists for each type of change
1030 Args:
1031 repo: repo path or object
1032 Returns: dict with lists for each type of change
10021033 """
10031034 with open_repo_closing(repo) as r:
10041035 index = r.open_index()
10311062 def daemon(path=".", address=None, port=None):
10321063 """Run a daemon serving Git requests over TCP/IP.
10331064
1034 :param path: Path to the directory to serve.
1035 :param address: Optional address to listen on (defaults to ::)
1036 :param port: Optional port to listen on (defaults to TCP_GIT_PORT)
1065 Args:
1066 path: Path to the directory to serve.
1067 address: Optional address to listen on (defaults to ::)
1068 port: Optional port to listen on (defaults to TCP_GIT_PORT)
10371069 """
10381070 # TODO(jelmer): Support git-daemon-export-ok and --export-all.
10391071 backend = FileSystemBackend(path)
10441076 def web_daemon(path=".", address=None, port=None):
10451077 """Run a daemon serving Git requests over HTTP.
10461078
1047 :param path: Path to the directory to serve
1048 :param address: Optional address to listen on (defaults to ::)
1049 :param port: Optional port to listen on (defaults to 80)
1079 Args:
1080 path: Path to the directory to serve
1081 address: Optional address to listen on (defaults to ::)
1082 port: Optional port to listen on (defaults to 80)
10501083 """
10511084 from dulwich.web import (
10521085 make_wsgi_chain,
10651098 def upload_pack(path=".", inf=None, outf=None):
10661099 """Upload a pack file after negotiating its contents using smart protocol.
10671100
1068 :param path: Path to the repository
1069 :param inf: Input stream to communicate with client
1070 :param outf: Output stream to communicate with client
1101 Args:
1102 path: Path to the repository
1103 inf: Input stream to communicate with client
1104 outf: Output stream to communicate with client
10711105 """
10721106 if outf is None:
10731107 outf = getattr(sys.stdout, 'buffer', sys.stdout)
10891123 def receive_pack(path=".", inf=None, outf=None):
10901124 """Receive a pack file after negotiating its contents using smart protocol.
10911125
1092 :param path: Path to the repository
1093 :param inf: Input stream to communicate with client
1094 :param outf: Output stream to communicate with client
1126 Args:
1127 path: Path to the repository
1128 inf: Input stream to communicate with client
1129 outf: Output stream to communicate with client
10951130 """
10961131 if outf is None:
10971132 outf = getattr(sys.stdout, 'buffer', sys.stdout)
11251160 def branch_delete(repo, name):
11261161 """Delete a branch.
11271162
1128 :param repo: Path to the repository
1129 :param name: Name of the branch
1163 Args:
1164 repo: Path to the repository
1165 name: Name of the branch
11301166 """
11311167 with open_repo_closing(repo) as r:
11321168 if isinstance(name, list):
11401176 def branch_create(repo, name, objectish=None, force=False):
11411177 """Create a branch.
11421178
1143 :param repo: Path to the repository
1144 :param name: Name of the new branch
1145 :param objectish: Target object to point new branch at (defaults to HEAD)
1146 :param force: Force creation of branch, even if it already exists
1179 Args:
1180 repo: Path to the repository
1181 name: Name of the new branch
1182 objectish: Target object to point new branch at (defaults to HEAD)
1183 force: Force creation of branch, even if it already exists
11471184 """
11481185 with open_repo_closing(repo) as r:
11491186 if objectish is None:
11611198 def branch_list(repo):
11621199 """List all branches.
11631200
1164 :param repo: Path to the repository
1201 Args:
1202 repo: Path to the repository
11651203 """
11661204 with open_repo_closing(repo) as r:
11671205 return r.refs.keys(base=LOCAL_BRANCH_PREFIX)
12471285
12481286 Currently this only packs loose objects.
12491287
1250 :param repo: Path to the repository
1288 Args:
1289 repo: Path to the repository
12511290 """
12521291 with open_repo_closing(repo) as r:
12531292 r.object_store.pack_loose_objects()
12561295 def pack_objects(repo, object_ids, packf, idxf, delta_window_size=None):
12571296 """Pack objects into a file.
12581297
1259 :param repo: Path to the repository
1260 :param object_ids: List of object ids to write
1261 :param packf: File-like object to write to
1262 :param idxf: File-like object to write to (can be None)
1298 Args:
1299 repo: Path to the repository
1300 object_ids: List of object ids to write
1301 packf: File-like object to write to
1302 idxf: File-like object to write to (can be None)
12631303 """
12641304 with open_repo_closing(repo) as r:
12651305 entries, data_sum = write_pack_objects(
12751315 name_only=False):
12761316 """List contents of a tree.
12771317
1278 :param repo: Path to the repository
1279 :param tree_ish: Tree id to list
1280 :param outstream: Output stream (defaults to stdout)
1281 :param recursive: Whether to recursively list files
1282 :param name_only: Only print item name
1318 Args:
1319 repo: Path to the repository
1320 tree_ish: Tree id to list
1321 outstream: Output stream (defaults to stdout)
1322 recursive: Whether to recursively list files
1323 name_only: Only print item name
12831324 """
12841325 def list_tree(store, treeid, base):
12851326 for (name, mode, sha) in store[treeid].iteritems():
12991340 def remote_add(repo, name, url):
13001341 """Add a remote.
13011342
1302 :param repo: Path to the repository
1303 :param name: Remote name
1304 :param url: Remote URL
1343 Args:
1344 repo: Path to the repository
1345 name: Remote name
1346 url: Remote URL
13051347 """
13061348 if not isinstance(name, bytes):
13071349 name = name.encode(DEFAULT_ENCODING)
13191361 def check_ignore(repo, paths, no_index=False):
13201362 """Debug gitignore files.
13211363
1322 :param repo: Path to the repository
1323 :param paths: List of paths to check for
1324 :param no_index: Don't check index
1325 :return: List of ignored files
1364 Args:
1365 repo: Path to the repository
1366 paths: List of paths to check for
1367 no_index: Don't check index
1368 Returns: List of ignored files
13261369 """
13271370 with open_repo_closing(repo) as r:
13281371 index = r.open_index()
13411384
13421385 Note that this does not actually update the working tree.
13431386
1344 :param repo: Path to the repository
1345 :param detach: Create a detached head
1346 :param target: Branch or committish to switch to
1347 :param new_branch: New branch to create
1387 Args:
1388 repo: Path to the repository
1389 detach: Create a detached head
1390 target: Branch or committish to switch to
1391 new_branch: New branch to create
13481392 """
13491393 with open_repo_closing(repo) as r:
13501394 if new_branch is not None:
13661410 def check_mailmap(repo, contact):
13671411 """Check canonical name and email of contact.
13681412
1369 :param repo: Path to the repository
1370 :param contact: Contact name and/or email
1371 :return: Canonical contact data
1413 Args:
1414 repo: Path to the repository
1415 contact: Contact name and/or email
1416 Returns: Canonical contact data
13721417 """
13731418 with open_repo_closing(repo) as r:
13741419 from dulwich.mailmap import Mailmap
13851430 def fsck(repo):
13861431 """Check a repository.
13871432
1388 :param repo: A path to the repository
1389 :return: Iterator over errors/warnings
1433 Args:
1434 repo: A path to the repository
1435 Returns: Iterator over errors/warnings
13901436 """
13911437 with open_repo_closing(repo) as r:
13921438 # TODO(jelmer): check pack files
14331479 def describe(repo):
14341480 """Describe the repository version.
14351481
1436 :param projdir: git repository root
1437 :returns: a string description of the current git revision
1482 Args:
1483 projdir: git repository root
1484 Returns: a string description of the current git revision
14381485
14391486 Examples: "gabcdefh", "v0.1" or "v0.1-5-gabcdefh".
14401487 """
15021549 def get_object_by_path(repo, path, committish=None):
15031550 """Get an object by path.
15041551
1505 :param repo: A path to the repository
1506 :param path: Path to look up
1507 :param committish: Commit to look up path in
1508 :return: A `ShaFile` object
1552 Args:
1553 repo: A path to the repository
1554 path: Path to look up
1555 committish: Commit to look up path in
1556 Returns: A `ShaFile` object
15091557 """
15101558 if committish is None:
15111559 committish = "HEAD"
15241572 def write_tree(repo):
15251573 """Write a tree object from the index.
15261574
1527 :param repo: Repository for which to write tree
1528 :return: tree id for the tree that was written
1575 Args:
1576 repo: Repository for which to write tree
1577 Returns: tree id for the tree that was written
15291578 """
15301579 with open_repo_closing(repo) as r:
15311580 return r.open_index().commit(r.object_store)
143143 def pkt_line(data):
144144 """Wrap data in a pkt-line.
145145
146 :param data: The data to wrap, as a str or None.
147 :return: The data prefixed with its length in pkt-line format; if data was
146 Args:
147 data: The data to wrap, as a str or None.
148 Returns: The data prefixed with its length in pkt-line format; if data was
148149 None, returns the flush-pkt ('0000').
149150 """
150151 if data is None:
186187
187188 This method may read from the readahead buffer; see unread_pkt_line.
188189
189 :return: The next string from the stream, without the length prefix, or
190 Returns: The next string from the stream, without the length prefix, or
190191 None for a flush-pkt ('0000').
191192 """
192193 if self._readahead is None:
222223 Note that this refers to the actual stream EOF and not just a
223224 flush-pkt.
224225
225 :return: True if the stream is at EOF, False otherwise.
226 Returns: True if the stream is at EOF, False otherwise.
226227 """
227228 try:
228229 next_line = self.read_pkt_line()
237238 This method can be used to unread a single pkt-line into a fixed
238239 readahead buffer.
239240
240 :param data: The data to unread, without the length prefix.
241 :raise ValueError: If more than one pkt-line is unread.
241 Args:
242 data: The data to unread, without the length prefix.
243 Raises:
244 ValueError: If more than one pkt-line is unread.
242245 """
243246 if self._readahead is not None:
244247 raise ValueError('Attempted to unread multiple pkt-lines.')
247250 def read_pkt_seq(self):
248251 """Read a sequence of pkt-lines from the remote git process.
249252
250 :return: Yields each line of data up to but not including the next
253 Returns: Yields each line of data up to but not including the next
251254 flush-pkt.
252255 """
253256 pkt = self.read_pkt_line()
258261 def write_pkt_line(self, line):
259262 """Sends a pkt-line to the remote git process.
260263
261 :param line: A string containing the data to send, without the length
264 Args:
265 line: A string containing the data to send, without the length
262266 prefix.
263267 """
264268 try:
293297 def write_sideband(self, channel, blob):
294298 """Write multiplexed data to the sideband.
295299
296 :param channel: An int specifying the channel to write to.
297 :param blob: A blob of data (as a string) to send on this channel.
300 Args:
301 channel: An int specifying the channel to write to.
302 blob: A blob of data (as a string) to send on this channel.
298303 """
299304 # a pktline can be a max of 65520. a sideband line can therefore be
300305 # 65520-5 = 65515
308313
309314 Only used for the TCP git protocol (git://).
310315
311 :param cmd: The remote service to access.
312 :param args: List of arguments to send to remove service.
316 Args:
317 cmd: The remote service to access.
318 args: List of arguments to send to remove service.
313319 """
314320 self.write_pkt_line(cmd + b" " + b"".join([(a + b"\0") for a in args]))
315321
318324
319325 Only used for the TCP git protocol (git://).
320326
321 :return: A tuple of (command, [list of arguments]).
327 Returns: A tuple of (command, [list of arguments]).
322328 """
323329 line = self.read_pkt_line()
324330 splice_at = line.find(b" ")
438444 def extract_capabilities(text):
439445 """Extract a capabilities list from a string, if present.
440446
441 :param text: String to extract from
442 :return: Tuple with text with capabilities removed and list of capabilities
447 Args:
448 text: String to extract from
449 Returns: Tuple with text with capabilities removed and list of capabilities
443450 """
444451 if b"\0" not in text:
445452 return text, []
455462
456463 want obj-id cap1 cap2 ...
457464
458 :param text: Want line to extract from
459 :return: Tuple with text with capabilities removed and list of capabilities
465 Args:
466 text: Want line to extract from
467 Returns: Tuple with text with capabilities removed and list of capabilities
460468 """
461469 split_text = text.rstrip().split(b" ")
462470 if len(split_text) < 3:
484492 def __init__(self, write, bufsize=65515):
485493 """Initialize the BufferedPktLineWriter.
486494
487 :param write: A write callback for the underlying writer.
488 :param bufsize: The internal buffer size, including length prefixes.
495 Args:
496 write: A write callback for the underlying writer.
497 bufsize: The internal buffer size, including length prefixes.
489498 """
490499 self._write = write
491500 self._bufsize = bufsize
3737 message):
3838 """Generate a single reflog line.
3939
40 :param old_sha: Old Commit SHA
41 :param new_sha: New Commit SHA
42 :param committer: Committer name and e-mail
43 :param timestamp: Timestamp
44 :param timezone: Timezone
45 :param message: Message
40 Args:
41 old_sha: Old Commit SHA
42 new_sha: New Commit SHA
43 committer: Committer name and e-mail
44 timestamp: Timestamp
45 timezone: Timezone
46 message: Message
4647 """
4748 if old_sha is None:
4849 old_sha = ZERO_SHA
5455 def parse_reflog_line(line):
5556 """Parse a reflog line.
5657
57 :param line: Line to parse
58 :return: Tuple of (old_sha, new_sha, committer, timestamp, timezone,
58 Args:
59 line: Line to parse
60 Returns: Tuple of (old_sha, new_sha, committer, timestamp, timezone,
5961 message)
6062 """
6163 (begin, message) = line.split(b'\t', 1)
6870 def read_reflog(f):
6971 """Read reflog.
7072
71 :param f: File-like object
72 :returns: Iterator over Entry objects
73 Args:
74 f: File-like object
75 Returns: Iterator over Entry objects
7376 """
7477 for l in f:
7578 yield parse_reflog_line(l)
5050 def parse_symref_value(contents):
5151 """Parse a symref value.
5252
53 :param contents: Contents to parse
54 :return: Destination
53 Args:
54 contents: Contents to parse
55 Returns: Destination
5556 """
5657 if contents.startswith(SYMREF):
5758 return contents[len(SYMREF):].rstrip(b'\r\n')
6667 [1]
6768 http://www.kernel.org/pub/software/scm/git/docs/git-check-ref-format.html
6869
69 :param refname: The refname to check
70 :return: True if refname is valid, False otherwise
70 Args:
71 refname: The refname to check
72 Returns: True if refname is valid, False otherwise
7173 """
7274 # These could be combined into one big expression, but are listed
7375 # separately to parallel [1].
110112 timezone=None, message=None):
111113 """Make a ref point at another ref.
112114
113 :param name: Name of the ref to set
114 :param other: Name of the ref to point at
115 :param message: Optional message
115 Args:
116 name: Name of the ref to set
117 other: Name of the ref to point at
118 message: Optional message
116119 """
117120 raise NotImplementedError(self.set_symbolic_ref)
118121
119122 def get_packed_refs(self):
120123 """Get contents of the packed-refs file.
121124
122 :return: Dictionary mapping ref names to SHA1s
123
124 :note: Will return an empty dictionary when no packed-refs file is
125 Returns: Dictionary mapping ref names to SHA1s
126
127 Note: Will return an empty dictionary when no packed-refs file is
125128 present.
126129 """
127130 raise NotImplementedError(self.get_packed_refs)
129132 def get_peeled(self, name):
130133 """Return the cached peeled value of a ref, if available.
131134
132 :param name: Name of the ref to peel
133 :return: The peeled value of the ref. If the ref is known not point to
135 Args:
136 name: Name of the ref to peel
137 Returns: The peeled value of the ref. If the ref is known not point to
134138 a tag, this will be the SHA the ref refers to. If the ref may point
135139 to a tag, but no cached information is available, None is returned.
136140 """
163167 def keys(self, base=None):
164168 """Refs present in this container.
165169
166 :param base: An optional base to return refs under.
167 :return: An unsorted set of valid refs in this container, including
170 Args:
171 base: An optional base to return refs under.
172 Returns: An unsorted set of valid refs in this container, including
168173 packed refs.
169174 """
170175 if base is not None:
175180 def subkeys(self, base):
176181 """Refs present in this container under a base.
177182
178 :param base: The base to return refs under.
179 :return: A set of valid refs in this container under the base; the base
183 Args:
184 base: The base to return refs under.
185 Returns: A set of valid refs in this container under the base; the base
180186 prefix is stripped from the ref names returned.
181187 """
182188 keys = set()
212218 refnames without the leading 'refs/', but this class requires that
213219 so it cannot touch anything outside the refs dir (or HEAD).
214220
215 :param name: The name of the reference.
216 :raises KeyError: if a refname is not HEAD or is otherwise not valid.
221 Args:
222 name: The name of the reference.
223 Raises:
224 KeyError: if a refname is not HEAD or is otherwise not valid.
217225 """
218226 if name in (b'HEAD', b'refs/stash'):
219227 return
223231 def read_ref(self, refname):
224232 """Read a reference without following any references.
225233
226 :param refname: The name of the reference
227 :return: The contents of the ref file, or None if it does
234 Args:
235 refname: The name of the reference
236 Returns: The contents of the ref file, or None if it does
228237 not exist.
229238 """
230239 contents = self.read_loose_ref(refname)
235244 def read_loose_ref(self, name):
236245 """Read a loose reference and return its contents.
237246
238 :param name: the refname to read
239 :return: The contents of the ref file, or None if it does
247 Args:
248 name: the refname to read
249 Returns: The contents of the ref file, or None if it does
240250 not exist.
241251 """
242252 raise NotImplementedError(self.read_loose_ref)
244254 def follow(self, name):
245255 """Follow a reference name.
246256
247 :return: a tuple of (refnames, sha), wheres refnames are the names of
257 Returns: a tuple of (refnames, sha), wheres refnames are the names of
248258 references in the chain
249259 """
250260 contents = SYMREF + name
294304 subclass, and can be used to perform an atomic compare-and-swap
295305 operation.
296306
297 :param name: The refname to set.
298 :param old_ref: The old sha the refname must refer to, or None to set
307 Args:
308 name: The refname to set.
309 old_ref: The old sha the refname must refer to, or None to set
299310 unconditionally.
300 :param new_ref: The new sha the refname will refer to.
301 :param message: Message for reflog
302 :return: True if the set was successful, False otherwise.
311 new_ref: The new sha the refname will refer to.
312 message: Message for reflog
313 Returns: True if the set was successful, False otherwise.
303314 """
304315 raise NotImplementedError(self.set_if_equals)
305316
306317 def add_if_new(self, name, ref):
307318 """Add a new reference only if it does not already exist.
308319
309 :param name: Ref name
310 :param ref: Ref value
311 :param message: Message for reflog
320 Args:
321 name: Ref name
322 ref: Ref value
323 message: Message for reflog
312324 """
313325 raise NotImplementedError(self.add_if_new)
314326
318330 This method follows all symbolic references if applicable for the
319331 subclass.
320332
321 :note: This method unconditionally overwrites the contents of a
333 Note: This method unconditionally overwrites the contents of a
322334 reference. To update atomically only if the reference has not
323335 changed, use set_if_equals().
324 :param name: The refname to set.
325 :param ref: The new sha the refname will refer to.
336
337 Args:
338 name: The refname to set.
339 ref: The new sha the refname will refer to.
326340 """
327341 self.set_if_equals(name, None, ref)
328342
334348 the subclass. It can be used to perform an atomic compare-and-delete
335349 operation.
336350
337 :param name: The refname to delete.
338 :param old_ref: The old sha the refname must refer to, or None to
351 Args:
352 name: The refname to delete.
353 old_ref: The old sha the refname must refer to, or None to
339354 delete unconditionally.
340 :param message: Message for reflog
341 :return: True if the delete was successful, False otherwise.
355 message: Message for reflog
356 Returns: True if the delete was successful, False otherwise.
342357 """
343358 raise NotImplementedError(self.remove_if_equals)
344359
348363 This method does not follow symbolic references, even if applicable for
349364 the subclass.
350365
351 :note: This method unconditionally deletes the contents of a reference.
366 Note: This method unconditionally deletes the contents of a reference.
352367 To delete atomically only if the reference has not changed, use
353368 remove_if_equals().
354369
355 :param name: The refname to delete.
370 Args:
371 name: The refname to delete.
356372 """
357373 self.remove_if_equals(name, None)
358374
359375 def get_symrefs(self):
360376 """Get a dict with all symrefs in this container.
361377
362 :return: Dictionary mapping source ref to target ref
378 Returns: Dictionary mapping source ref to target ref
363379 """
364380 ret = {}
365381 for src in self.allkeys():
558574 def get_packed_refs(self):
559575 """Get contents of the packed-refs file.
560576
561 :return: Dictionary mapping ref names to SHA1s
562
563 :note: Will return an empty dictionary when no packed-refs file is
577 Returns: Dictionary mapping ref names to SHA1s
578
579 Note: Will return an empty dictionary when no packed-refs file is
564580 present.
565581 """
566582 # TODO: invalidate the cache on repacking
593609 def get_peeled(self, name):
594610 """Return the cached peeled value of a ref, if available.
595611
596 :param name: Name of the ref to peel
597 :return: The peeled value of the ref. If the ref is known not point to
612 Args:
613 name: Name of the ref to peel
614 Returns: The peeled value of the ref. If the ref is known not point to
598615 a tag, this will be the SHA the ref refers to. If the ref may point
599616 to a tag, but no cached information is available, None is returned.
600617 """
614631 If the reference file a symbolic reference, only read the first line of
615632 the file. Otherwise, only read the first 40 bytes.
616633
617 :param name: the refname to read, relative to refpath
618 :return: The contents of the ref file, or None if the file does not
634 Args:
635 name: the refname to read, relative to refpath
636 Returns: The contents of the ref file, or None if the file does not
619637 exist.
620 :raises IOError: if any other error occurs
638 Raises:
639 IOError: if any other error occurs
621640 """
622641 filename = self.refpath(name)
623642 try:
659678 timezone=None, message=None):
660679 """Make a ref point at another ref.
661680
662 :param name: Name of the ref to set
663 :param other: Name of the ref to point at
664 :param message: Optional message to describe the change
681 Args:
682 name: Name of the ref to set
683 other: Name of the ref to point at
684 message: Optional message to describe the change
665685 """
666686 self._check_refname(name)
667687 self._check_refname(other)
686706 This method follows all symbolic references, and can be used to perform
687707 an atomic compare-and-swap operation.
688708
689 :param name: The refname to set.
690 :param old_ref: The old sha the refname must refer to, or None to set
709 Args:
710 name: The refname to set.
711 old_ref: The old sha the refname must refer to, or None to set
691712 unconditionally.
692 :param new_ref: The new sha the refname will refer to.
693 :param message: Set message for reflog
694 :return: True if the set was successful, False otherwise.
713 new_ref: The new sha the refname will refer to.
714 message: Set message for reflog
715 Returns: True if the set was successful, False otherwise.
695716 """
696717 self._check_refname(name)
697718 try:
741762 This method follows symrefs, and only ensures that the last ref in the
742763 chain does not exist.
743764
744 :param name: The refname to set.
745 :param ref: The new sha the refname will refer to.
746 :param message: Optional message for reflog
747 :return: True if the add was successful, False otherwise.
765 Args:
766 name: The refname to set.
767 ref: The new sha the refname will refer to.
768 message: Optional message for reflog
769 Returns: True if the add was successful, False otherwise.
748770 """
749771 try:
750772 realnames, contents = self.follow(name)
778800 This method does not follow symbolic references. It can be used to
779801 perform an atomic compare-and-delete operation.
780802
781 :param name: The refname to delete.
782 :param old_ref: The old sha the refname must refer to, or None to
803 Args:
804 name: The refname to delete.
805 old_ref: The old sha the refname must refer to, or None to
783806 delete unconditionally.
784 :param message: Optional message
785 :return: True if the delete was successful, False otherwise.
807 message: Optional message
808 Returns: True if the delete was successful, False otherwise.
786809 """
787810 self._check_refname(name)
788811 filename = self.refpath(name)
849872 def read_packed_refs(f):
850873 """Read a packed refs file.
851874
852 :param f: file-like object to read from
853 :return: Iterator over tuples with SHA1s and ref names.
875 Args:
876 f: file-like object to read from
877 Returns: Iterator over tuples with SHA1s and ref names.
854878 """
855879 for l in f:
856880 if l.startswith(b'#'):
868892 Assumes the "# pack-refs with: peeled" line was already read. Yields tuples
869893 with ref names, SHA1s, and peeled SHA1s (or None).
870894
871 :param f: file-like object to read from, seek'ed to the second line
895 Args:
896 f: file-like object to read from, seek'ed to the second line
872897 """
873898 last = None
874899 for line in f:
896921 def write_packed_refs(f, packed_refs, peeled_refs=None):
897922 """Write a packed refs file.
898923
899 :param f: empty file-like object to write to
900 :param packed_refs: dict of refname to sha of packed refs to write
901 :param peeled_refs: dict of refname to peeled value of sha
924 Args:
925 f: empty file-like object to write to
926 packed_refs: dict of refname to sha of packed refs to write
927 peeled_refs: dict of refname to peeled value of sha
902928 """
903929 if peeled_refs is None:
904930 peeled_refs = {}
182182 def check_user_identity(identity):
183183 """Verify that a user identity is formatted correctly.
184184
185 :param identity: User identity bytestring
186 :raise InvalidUserIdentity: Raised when identity is invalid
185 Args:
186 identity: User identity bytestring
187 Raises:
188 InvalidUserIdentity: Raised when identity is invalid
187189 """
188190 try:
189191 fst, snd = identity.split(b' <', 1)
196198 def parse_graftpoints(graftpoints):
197199 """Convert a list of graftpoints into a dict
198200
199 :param graftpoints: Iterator of graftpoint lines
201 Args:
202 graftpoints: Iterator of graftpoint lines
200203
201204 Each line is formatted as:
202205 <commit sha1> <parent sha1> [<parent sha1>]*
281284 This shouldn't be called directly, but rather through one of the
282285 base classes, such as MemoryRepo or Repo.
283286
284 :param object_store: Object store to use
285 :param refs: Refs container to use
287 Args:
288 object_store: Object store to use
289 refs: Refs container to use
286290 """
287291 self.object_store = object_store
288292 self.refs = refs
293297 def _determine_file_mode(self):
294298 """Probe the file-system to determine whether permissions can be trusted.
295299
296 :return: True if permissions can be trusted, False otherwise.
300 Returns: True if permissions can be trusted, False otherwise.
297301 """
298302 raise NotImplementedError(self._determine_file_mode)
299303
322326 the control dir in a disk-based Repo, the object returned need not be
323327 pointing to a file in that location.
324328
325 :param path: The path to the file, relative to the control dir.
326 :return: An open file object, or None if the file does not exist.
329 Args:
330 path: The path to the file, relative to the control dir.
331 Returns: An open file object, or None if the file does not exist.
327332 """
328333 raise NotImplementedError(self.get_named_file)
329334
330335 def _put_named_file(self, path, contents):
331336 """Write a file to the control dir with the given name and contents.
332337
333 :param path: The path to the file, relative to the control dir.
334 :param contents: A string to write to the file.
338 Args:
339 path: The path to the file, relative to the control dir.
340 contents: A string to write to the file.
335341 """
336342 raise NotImplementedError(self._put_named_file)
337343
342348 def open_index(self):
343349 """Open the index for this repository.
344350
345 :raise NoIndexPresent: If no index is present
346 :return: The matching `Index`
351 Raises:
352 NoIndexPresent: If no index is present
353 Returns: The matching `Index`
347354 """
348355 raise NotImplementedError(self.open_index)
349356
350357 def fetch(self, target, determine_wants=None, progress=None, depth=None):
351358 """Fetch objects into another repository.
352359
353 :param target: The target repository
354 :param determine_wants: Optional function to determine what refs to
360 Args:
361 target: The target repository
362 determine_wants: Optional function to determine what refs to
355363 fetch.
356 :param progress: Optional progress function
357 :param depth: Optional shallow fetch depth
358 :return: The local refs
364 progress: Optional progress function
365 depth: Optional shallow fetch depth
366 Returns: The local refs
359367 """
360368 if determine_wants is None:
361369 determine_wants = target.object_store.determine_wants_all
369377 get_tagged=None, depth=None):
370378 """Fetch the pack data required for a set of revisions.
371379
372 :param determine_wants: Function that takes a dictionary with heads
380 Args:
381 determine_wants: Function that takes a dictionary with heads
373382 and returns the list of heads to fetch.
374 :param graph_walker: Object that can iterate over the list of revisions
383 graph_walker: Object that can iterate over the list of revisions
375384 to fetch and has an "ack" method that will be called to acknowledge
376385 that a revision is present.
377 :param progress: Simple progress function that will be called with
386 progress: Simple progress function that will be called with
378387 updated progress strings.
379 :param get_tagged: Function that returns a dict of pointed-to sha ->
388 get_tagged: Function that returns a dict of pointed-to sha ->
380389 tag sha for including tags.
381 :param depth: Shallow fetch depth
382 :return: count and iterator over pack data
390 depth: Shallow fetch depth
391 Returns: count and iterator over pack data
383392 """
384393 # TODO(jelmer): Fetch pack data directly, don't create objects first.
385394 objects = self.fetch_objects(determine_wants, graph_walker, progress,
390399 get_tagged=None, depth=None):
391400 """Fetch the missing objects required for a set of revisions.
392401
393 :param determine_wants: Function that takes a dictionary with heads
402 Args:
403 determine_wants: Function that takes a dictionary with heads
394404 and returns the list of heads to fetch.
395 :param graph_walker: Object that can iterate over the list of revisions
405 graph_walker: Object that can iterate over the list of revisions
396406 to fetch and has an "ack" method that will be called to acknowledge
397407 that a revision is present.
398 :param progress: Simple progress function that will be called with
408 progress: Simple progress function that will be called with
399409 updated progress strings.
400 :param get_tagged: Function that returns a dict of pointed-to sha ->
410 get_tagged: Function that returns a dict of pointed-to sha ->
401411 tag sha for including tags.
402 :param depth: Shallow fetch depth
403 :return: iterator over objects, with __len__ implemented
412 depth: Shallow fetch depth
413 Returns: iterator over objects, with __len__ implemented
404414 """
405415 if depth not in (None, 0):
406416 raise NotImplementedError("depth not supported yet")
466476 A graph walker is used by a remote repository (or proxy)
467477 to find out which objects are present in this repository.
468478
469 :param heads: Repository heads to use (optional)
470 :return: A graph walker object
479 Args:
480 heads: Repository heads to use (optional)
481 Returns: A graph walker object
471482 """
472483 if heads is None:
473484 heads = [
479490 def get_refs(self):
480491 """Get dictionary with all refs.
481492
482 :return: A ``dict`` mapping ref names to SHA1s
493 Returns: A ``dict`` mapping ref names to SHA1s
483494 """
484495 return self.refs.as_dict()
485496
507518 def get_object(self, sha):
508519 """Retrieve the object with the specified SHA.
509520
510 :param sha: SHA to retrieve
511 :return: A ShaFile object
512 :raise KeyError: when the object can not be found
521 Args:
522 sha: SHA to retrieve
523 Returns: A ShaFile object
524 Raises:
525 KeyError: when the object can not be found
513526 """
514527 return self.object_store[sha]
515528
519532 If the specific commit is a graftpoint, the graft parents
520533 will be returned instead.
521534
522 :param sha: SHA of the commit for which to retrieve the parents
523 :param commit: Optional commit matching the sha
524 :return: List of parents
535 Args:
536 sha: SHA of the commit for which to retrieve the parents
537 commit: Optional commit matching the sha
538 Returns: List of parents
525539 """
526540
527541 try:
534548 def get_config(self):
535549 """Retrieve the config object.
536550
537 :return: `ConfigFile` object for the ``.git/config`` file.
551 Returns: `ConfigFile` object for the ``.git/config`` file.
538552 """
539553 raise NotImplementedError(self.get_config)
540554
541555 def get_description(self):
542556 """Retrieve the description for this repository.
543557
544 :return: String with the description of the repository
558 Returns: String with the description of the repository
545559 as set by the user.
546560 """
547561 raise NotImplementedError(self.get_description)
549563 def set_description(self, description):
550564 """Set the description for this repository.
551565
552 :param description: Text to set as description for this repository.
566 Args:
567 description: Text to set as description for this repository.
553568 """
554569 raise NotImplementedError(self.set_description)
555570
560575 itself (.git/config) and the global configuration, which usually
561576 lives in ~/.gitconfig.
562577
563 :return: `Config` instance for this repository
578 Returns: `Config` instance for this repository
564579 """
565580 from dulwich.config import StackedConfig
566581 backends = [self.get_config()] + StackedConfig.default_backends()
569584 def get_shallow(self):
570585 """Get the set of shallow commits.
571586
572 :return: Set of shallow commits.
587 Returns: Set of shallow commits.
573588 """
574589 f = self.get_named_file('shallow')
575590 if f is None:
580595 def update_shallow(self, new_shallow, new_unshallow):
581596 """Update the list of shallow objects.
582597
583 :param new_shallow: Newly shallow objects
584 :param new_unshallow: Newly no longer shallow objects
598 Args:
599 new_shallow: Newly shallow objects
600 new_unshallow: Newly no longer shallow objects
585601 """
586602 shallow = self.get_shallow()
587603 if new_shallow:
595611 def get_peeled(self, ref):
596612 """Get the peeled value of a ref.
597613
598 :param ref: The refname to peel.
599 :return: The fully-peeled SHA1 of a tag object, after peeling all
614 Args:
615 ref: The refname to peel.
616 Returns: The fully-peeled SHA1 of a tag object, after peeling all
600617 intermediate tags; if the original ref does not point to a tag,
601618 this will equal the original SHA1.
602619 """
608625 def get_walker(self, include=None, *args, **kwargs):
609626 """Obtain a walker for this repository.
610627
611 :param include: Iterable of SHAs of commits to include along with their
628 Args:
629 include: Iterable of SHAs of commits to include along with their
612630 ancestors. Defaults to [HEAD]
613 :param exclude: Iterable of SHAs of commits to exclude along with their
631 exclude: Iterable of SHAs of commits to exclude along with their
614632 ancestors, overriding includes.
615 :param order: ORDER_* constant specifying the order of results.
633 order: ORDER_* constant specifying the order of results.
616634 Anything other than ORDER_DATE may result in O(n) memory usage.
617 :param reverse: If True, reverse the order of output, requiring O(n)
635 reverse: If True, reverse the order of output, requiring O(n)
618636 memory.
619 :param max_entries: The maximum number of entries to yield, or None for
637 max_entries: The maximum number of entries to yield, or None for
620638 no limit.
621 :param paths: Iterable of file or subtree paths to show entries for.
622 :param rename_detector: diff.RenameDetector object for detecting
639 paths: Iterable of file or subtree paths to show entries for.
640 rename_detector: diff.RenameDetector object for detecting
623641 renames.
624 :param follow: If True, follow path across renames/copies. Forces a
642 follow: If True, follow path across renames/copies. Forces a
625643 default rename_detector.
626 :param since: Timestamp to list commits after.
627 :param until: Timestamp to list commits before.
628 :param queue_cls: A class to use for a queue of commits, supporting the
644 since: Timestamp to list commits after.
645 until: Timestamp to list commits before.
646 queue_cls: A class to use for a queue of commits, supporting the
629647 iterator protocol. The constructor takes a single argument, the
630648 Walker.
631 :return: A `Walker` object
649 Returns: A `Walker` object
632650 """
633651 from dulwich.walk import Walker
634652 if include is None:
644662 def __getitem__(self, name):
645663 """Retrieve a Git object by SHA1 or ref.
646664
647 :param name: A Git object SHA1 or a ref name
648 :return: A `ShaFile` object, such as a Commit or Blob
649 :raise KeyError: when the specified ref or object does not exist
665 Args:
666 name: A Git object SHA1 or a ref name
667 Returns: A `ShaFile` object, such as a Commit or Blob
668 Raises:
669 KeyError: when the specified ref or object does not exist
650670 """
651671 if not isinstance(name, bytes):
652672 raise TypeError("'name' must be bytestring, not %.80s" %
664684 def __contains__(self, name):
665685 """Check if a specific Git object or ref is present.
666686
667 :param name: Git object SHA1 or ref name
687 Args:
688 name: Git object SHA1 or ref name
668689 """
669690 if len(name) in (20, 40):
670691 return name in self.object_store or name in self.refs
674695 def __setitem__(self, name, value):
675696 """Set a ref.
676697
677 :param name: ref name
678 :param value: Ref value - either a ShaFile object, or a hex sha
698 Args:
699 name: ref name
700 value: Ref value - either a ShaFile object, or a hex sha
679701 """
680702 if name.startswith(b"refs/") or name == b'HEAD':
681703 if isinstance(value, ShaFile):
690712 def __delitem__(self, name):
691713 """Remove a ref.
692714
693 :param name: Name of the ref to remove
715 Args:
716 name: Name of the ref to remove
694717 """
695718 if name.startswith(b"refs/") or name == b"HEAD":
696719 del self.refs[name]
706729 def _add_graftpoints(self, updated_graftpoints):
707730 """Add or modify graftpoints
708731
709 :param updated_graftpoints: Dict of commit shas to list of parent shas
732 Args:
733 updated_graftpoints: Dict of commit shas to list of parent shas
710734 """
711735
712736 # Simple validation
719743 def _remove_graftpoints(self, to_remove=[]):
720744 """Remove graftpoints
721745
722 :param to_remove: List of commit shas
746 Args:
747 to_remove: List of commit shas
723748 """
724749 for sha in to_remove:
725750 del self._graftpoints[sha]
738763 ref=b'HEAD', merge_heads=None):
739764 """Create a new commit.
740765
741 :param message: Commit message
742 :param committer: Committer fullname
743 :param author: Author fullname (defaults to committer)
744 :param commit_timestamp: Commit timestamp (defaults to now)
745 :param commit_timezone: Commit timestamp timezone (defaults to GMT)
746 :param author_timestamp: Author timestamp (defaults to commit
766 Args:
767 message: Commit message
768 committer: Committer fullname
769 author: Author fullname (defaults to committer)
770 commit_timestamp: Commit timestamp (defaults to now)
771 commit_timezone: Commit timestamp timezone (defaults to GMT)
772 author_timestamp: Author timestamp (defaults to commit
747773 timestamp)
748 :param author_timezone: Author timestamp timezone
774 author_timezone: Author timestamp timezone
749775 (defaults to commit timestamp timezone)
750 :param tree: SHA1 of the tree root to use (if not specified the
776 tree: SHA1 of the tree root to use (if not specified the
751777 current index will be committed).
752 :param encoding: Encoding
753 :param ref: Optional ref to commit to (defaults to current branch)
754 :param merge_heads: Merge heads (defaults to .git/MERGE_HEADS)
755 :return: New commit SHA1
778 encoding: Encoding
779 ref: Optional ref to commit to (defaults to current branch)
780 merge_heads: Merge heads (defaults to .git/MERGE_HEADS)
781 Returns: New commit SHA1
756782 """
757783 import time
758784 c = Commit()
859885
860886 The first line of the file should start with "gitdir: "
861887
862 :param f: File-like object to read from
863 :return: A path
888 Args:
889 f: File-like object to read from
890 Returns: A path
864891 """
865892 cs = f.read()
866893 if not cs.startswith("gitdir: "):
958985 Return a Repo object for the first parent directory that looks like a
959986 Git repository.
960987
961 :param start: The directory to start discovery from (defaults to '.')
988 Args:
989 start: The directory to start discovery from (defaults to '.')
962990 """
963991 remaining = True
964992 path = os.path.abspath(start)
9881016 def _determine_file_mode(self):
9891017 """Probe the file-system to determine whether permissions can be trusted.
9901018
991 :return: True if permissions can be trusted, False otherwise.
1019 Returns: True if permissions can be trusted, False otherwise.
9921020 """
9931021 fname = os.path.join(self.path, '.probe-permissions')
9941022 with open(fname, 'w') as f:
10131041 def _put_named_file(self, path, contents):
10141042 """Write a file to the control dir with the given name and contents.
10151043
1016 :param path: The path to the file, relative to the control dir.
1017 :param contents: A string to write to the file.
1044 Args:
1045 path: The path to the file, relative to the control dir.
1046 contents: A string to write to the file.
10181047 """
10191048 path = path.lstrip(os.path.sep)
10201049 with GitFile(os.path.join(self.controldir(), path), 'wb') as f:
10351064 the control dir in a disk-based Repo, the object returned need not be
10361065 pointing to a file in that location.
10371066
1038 :param path: The path to the file, relative to the control dir.
1039 :param basedir: Optional argument that specifies an alternative to the
1067 Args:
1068 path: The path to the file, relative to the control dir.
1069 basedir: Optional argument that specifies an alternative to the
10401070 control dir.
1041 :return: An open file object, or None if the file does not exist.
1071 Returns: An open file object, or None if the file does not exist.
10421072 """
10431073 # TODO(dborowitz): sanitize filenames, since this is used directly by
10441074 # the dumb web serving code.
10591089 def open_index(self):
10601090 """Open the index for this repository.
10611091
1062 :raise NoIndexPresent: If no index is present
1063 :return: The matching `Index`
1092 Raises:
1093 NoIndexPresent: If no index is present
1094 Returns: The matching `Index`
10641095 """
10651096 from dulwich.index import Index
10661097 if not self.has_index():
10761107 def stage(self, fs_paths):
10771108 """Stage a set of paths.
10781109
1079 :param fs_paths: List of paths, relative to the repository path
1110 Args:
1111 fs_paths: List of paths, relative to the repository path
10801112 """
10811113
10821114 root_path_bytes = self.path.encode(sys.getfilesystemencoding())
11241156 origin=b"origin", checkout=None):
11251157 """Clone this repository.
11261158
1127 :param target_path: Target path
1128 :param mkdir: Create the target directory
1129 :param bare: Whether to create a bare repository
1130 :param origin: Base name for refs in target repository
1159 Args:
1160 target_path: Target path
1161 mkdir: Create the target directory
1162 bare: Whether to create a bare repository
1163 origin: Base name for refs in target repository
11311164 cloned from this repository
1132 :return: Created repository as `Repo`
1165 Returns: Created repository as `Repo`
11331166 """
11341167 if not bare:
11351168 target = self.init(target_path, mkdir=mkdir)
11781211 def reset_index(self, tree=None):
11791212 """Reset the index back to a specific tree.
11801213
1181 :param tree: Tree SHA to reset to, None for current HEAD tree.
1214 Args:
1215 tree: Tree SHA to reset to, None for current HEAD tree.
11821216 """
11831217 from dulwich.index import (
11841218 build_index_from_tree,
12021236 def get_config(self):
12031237 """Retrieve the config object.
12041238
1205 :return: `ConfigFile` object for the ``.git/config`` file.
1239 Returns: `ConfigFile` object for the ``.git/config`` file.
12061240 """
12071241 from dulwich.config import ConfigFile
12081242 path = os.path.join(self._controldir, 'config')
12181252 def get_description(self):
12191253 """Retrieve the description of this repository.
12201254
1221 :return: A string describing the repository or None.
1255 Returns: A string describing the repository or None.
12221256 """
12231257 path = os.path.join(self._controldir, 'description')
12241258 try:
12351269 def set_description(self, description):
12361270 """Set the description for this repository.
12371271
1238 :param description: Text to set as description for this repository.
1272 Args:
1273 description: Text to set as description for this repository.
12391274 """
12401275
12411276 self._put_named_file('description', description)
12541289 def init(cls, path, mkdir=False):
12551290 """Create a new repository.
12561291
1257 :param path: Path in which to create the repository
1258 :param mkdir: Whether to create the directory
1259 :return: `Repo` instance
1292 Args:
1293 path: Path in which to create the repository
1294 mkdir: Whether to create the directory
1295 Returns: `Repo` instance
12601296 """
12611297 if mkdir:
12621298 os.mkdir(path)
12711307 mkdir=False):
12721308 """Create a new working directory linked to a repository.
12731309
1274 :param path: Path in which to create the working tree.
1275 :param main_repo: Main repository to reference
1276 :param identifier: Worktree identifier
1277 :param mkdir: Whether to create the directory
1278 :return: `Repo` instance
1310 Args:
1311 path: Path in which to create the working tree.
1312 main_repo: Main repository to reference
1313 identifier: Worktree identifier
1314 mkdir: Whether to create the directory
1315 Returns: `Repo` instance
12791316 """
12801317 if mkdir:
12811318 os.mkdir(path)
13141351
13151352 ``path`` should already exist and be an empty directory.
13161353
1317 :param path: Path to create bare repository in
1318 :return: a `Repo` instance
1354 Args:
1355 path: Path to create bare repository in
1356 Returns: a `Repo` instance
13191357 """
13201358 if mkdir:
13211359 os.mkdir(path)
13721410 def _determine_file_mode(self):
13731411 """Probe the file-system to determine whether permissions can be trusted.
13741412
1375 :return: True if permissions can be trusted, False otherwise.
1413 Returns: True if permissions can be trusted, False otherwise.
13761414 """
13771415 return sys.platform != 'win32'
13781416
13791417 def _put_named_file(self, path, contents):
13801418 """Write a file to the control dir with the given name and contents.
13811419
1382 :param path: The path to the file, relative to the control dir.
1383 :param contents: A string to write to the file.
1420 Args:
1421 path: The path to the file, relative to the control dir.
1422 contents: A string to write to the file.
13841423 """
13851424 self._named_files[path] = contents
13861425
13971436 the control dir in a disk-baked Repo, the object returned need not be
13981437 pointing to a file in that location.
13991438
1400 :param path: The path to the file, relative to the control dir.
1401 :return: An open file object, or None if the file does not exist.
1439 Args:
1440 path: The path to the file, relative to the control dir.
1441 Returns: An open file object, or None if the file does not exist.
14021442 """
14031443 contents = self._named_files.get(path, None)
14041444 if contents is None:
14081448 def open_index(self):
14091449 """Fail to open index for this repo, since it is bare.
14101450
1411 :raise NoIndexPresent: Raised when no index is present
1451 Raises:
1452 NoIndexPresent: Raised when no index is present
14121453 """
14131454 raise NoIndexPresent()
14141455
14151456 def get_config(self):
14161457 """Retrieve the config object.
14171458
1418 :return: `ConfigFile` object.
1459 Returns: `ConfigFile` object.
14191460 """
14201461 return self._config
14211462
14231464 def init_bare(cls, objects, refs):
14241465 """Create a new bare repository in memory.
14251466
1426 :param objects: Objects for the new repository,
1467 Args:
1468 objects: Objects for the new repository,
14271469 as iterable
1428 :param refs: Refs as dictionary, mapping names
1470 refs: Refs as dictionary, mapping names
14291471 to object SHA1s
14301472 """
14311473 ret = cls()
126126 def open_repository(self, path):
127127 """Open the repository at a path.
128128
129 :param path: Path to the repository
130 :raise NotGitRepository: no git repository was found at path
131 :return: Instance of BackendRepo
129 Args:
130 path: Path to the repository
131 Raises:
132 NotGitRepository: no git repository was found at path
133 Returns: Instance of BackendRepo
132134 """
133135 raise NotImplementedError(self.open_repository)
134136
147149 """
148150 Get all the refs in the repository
149151
150 :return: dict of name -> sha
152 Returns: dict of name -> sha
151153 """
152154 raise NotImplementedError
153155
154156 def get_peeled(self, name):
155157 """Return the cached peeled value of a ref, if available.
156158
157 :param name: Name of the ref to peel
158 :return: The peeled value of the ref. If the ref is known not point to
159 Args:
160 name: Name of the ref to peel
161 Returns: The peeled value of the ref. If the ref is known not point to
159162 a tag, this will be the SHA the ref refers to. If no cached
160163 information about a tag is available, this method may return None,
161164 but it should attempt to peel the tag if possible.
167170 """
168171 Yield the objects required for a list of commits.
169172
170 :param progress: is a callback to send progress messages to the client
171 :param get_tagged: Function that returns a dict of pointed-to sha ->
173 Args:
174 progress: is a callback to send progress messages to the client
175 get_tagged: Function that returns a dict of pointed-to sha ->
172176 tag sha for including tags.
173177 """
174178 raise NotImplementedError
311315 def get_tagged(self, refs=None, repo=None):
312316 """Get a dict of peeled values of tags to their original tag shas.
313317
314 :param refs: dict of refname -> sha of possible tags; defaults to all
318 Args:
319 refs: dict of refname -> sha of possible tags; defaults to all
315320 of the backend's refs.
316 :param repo: optional Repo instance for getting peeled refs; defaults
321 repo: optional Repo instance for getting peeled refs; defaults
317322 to the backend's repo, if available
318 :return: dict of peeled_sha -> tag_sha, where tag_sha is the sha of a
323 Returns: dict of peeled_sha -> tag_sha, where tag_sha is the sha of a
319324 tag whose peeled value is peeled_sha.
320325 """
321326 if not self.has_capability(CAPABILITY_INCLUDE_TAG):
384389 def _split_proto_line(line, allowed):
385390 """Split a line read from the wire.
386391
387 :param line: The line read from the wire.
388 :param allowed: An iterable of command names that should be allowed.
392 Args:
393 line: The line read from the wire.
394 allowed: An iterable of command names that should be allowed.
389395 Command names not listed below as possible return values will be
390396 ignored. If None, any commands from the possible return values are
391397 allowed.
392 :return: a tuple having one of the following forms:
398 Returns: a tuple having one of the following forms:
393399 ('want', obj_id)
394400 ('have', obj_id)
395401 ('done', None)
396402 (None, None) (for a flush-pkt)
397403
398 :raise UnexpectedCommandError: if the line cannot be parsed into one of the
404 Raises:
405 UnexpectedCommandError: if the line cannot be parsed into one of the
399406 allowed return values.
400407 """
401408 if not line:
421428 def _find_shallow(store, heads, depth):
422429 """Find shallow commits according to a given depth.
423430
424 :param store: An ObjectStore for looking up objects.
425 :param heads: Iterable of head SHAs to start walking from.
426 :param depth: The depth of ancestors to include. A depth of one includes
431 Args:
432 store: An ObjectStore for looking up objects.
433 heads: Iterable of head SHAs to start walking from.
434 depth: The depth of ancestors to include. A depth of one includes
427435 only the heads themselves.
428 :return: A tuple of (shallow, not_shallow), sets of SHAs that should be
436 Returns: A tuple of (shallow, not_shallow), sets of SHAs that should be
429437 considered shallow and unshallow according to the arguments. Note that
430438 these sets may overlap if a commit is reachable along multiple paths.
431439 """
483491 def _all_wants_satisfied(store, haves, wants):
484492 """Check whether all the current wants are satisfied by a set of haves.
485493
486 :param store: Object store to retrieve objects from
487 :param haves: A set of commits we know the client has.
488 :param wants: A set of commits the client wants
489 :note: Wants are specified with set_wants rather than passed in since
494 Args:
495 store: Object store to retrieve objects from
496 haves: A set of commits we know the client has.
497 wants: A set of commits the client wants
498 Note: Wants are specified with set_wants rather than passed in since
490499 in the current interface they are determined outside this class.
491500 """
492501 haves = set(haves)
545554 walking the graph. Additionally, later code depends on this method
546555 consuming everything up to the first 'have' line.
547556
548 :param heads: a dict of refname->SHA1 to advertise
549 :return: a list of SHA1s requested by the client
557 Args:
558 heads: a dict of refname->SHA1 to advertise
559 Returns: a list of SHA1s requested by the client
550560 """
551561 symrefs = self.get_symrefs()
552562 values = set(heads.values())
637647 def read_proto_line(self, allowed):
638648 """Read a line from the wire.
639649
640 :param allowed: An iterable of command names that should be allowed.
641 :return: A tuple of (command, value); see _split_proto_line.
642 :raise UnexpectedCommandError: If an error occurred reading the line.
650 Args:
651 allowed: An iterable of command names that should be allowed.
652 Returns: A tuple of (command, value); see _split_proto_line.
653 Raises:
654 UnexpectedCommandError: If an error occurred reading the line.
643655 """
644656 return _split_proto_line(self.proto.read_pkt_line(), allowed)
645657
690702 def all_wants_satisfied(self, haves):
691703 """Check whether all the current wants are satisfied by a set of haves.
692704
693 :param haves: A set of commits we know the client has.
694 :note: Wants are specified with set_wants rather than passed in since
705 Args:
706 haves: A set of commits we know the client has.
707 Note: Wants are specified with set_wants rather than passed in since
695708 in the current interface they are determined outside this class.
696709 """
697710 return _all_wants_satisfied(self.store, haves, self._wants)
11321145 This is mostly useful for the implementation of commands used by e.g.
11331146 git+ssh.
11341147
1135 :param handler_cls: `Handler` class to use for the request
1136 :param argv: execv-style command-line arguments. Defaults to sys.argv.
1137 :param backend: `Backend` to use
1138 :param inf: File-like object to read from, defaults to standard input.
1139 :param outf: File-like object to write to, defaults to standard output.
1140 :return: Exit code for use with sys.exit. 0 on success, 1 on failure.
1148 Args:
1149 handler_cls: `Handler` class to use for the request
1150 argv: execv-style command-line arguments. Defaults to sys.argv.
1151 backend: `Backend` to use
1152 inf: File-like object to read from, defaults to standard input.
1153 outf: File-like object to write to, defaults to standard output.
1154 Returns: Exit code for use with sys.exit. 0 on success, 1 on failure.
11411155 """
11421156 if backend is None:
11431157 backend = FileSystemBackend()
7171 def push(self, committer=None, author=None, message=None):
7272 """Create a new stash.
7373
74 :param committer: Optional committer name to use
75 :param author: Optional author name to use
76 :param message: Optional commit message
74 Args:
75 committer: Optional committer name to use
76 author: Optional author name to use
77 message: Optional commit message
7778 """
7879 # First, create the index commit.
7980 commit_kwargs = {}
6363 def bin_path(self, name):
6464 """Determine the full path of a binary.
6565
66 :param name: Name of the script
67 :return: Full path
66 Args:
67 name: Name of the script
68 Returns: Full path
6869 """
6970 for d in self.bin_directories:
7071 p = os.path.join(d, name)
7677 def run_command(self, name, args):
7778 """Run a Dulwich command.
7879
79 :param name: Name of the command, as it exists in bin/
80 :param args: Arguments to the command
80 Args:
81 name: Name of the command, as it exists in bin/
82 args: Arguments to the command
8183 """
8284 env = dict(os.environ)
8385 env["PYTHONPATH"] = os.pathsep.join(sys.path)
132132 def create_new_worktree(self, repo_dir, branch):
133133 """Create a new worktree using git-worktree.
134134
135 :param repo_dir: The directory of the main working tree.
136 :param branch: The branch or commit to checkout in the new worktree.
137
138 :returns: The path to the new working tree.
135 Args:
136 repo_dir: The directory of the main working tree.
137 branch: The branch or commit to checkout in the new worktree.
138
139 Returns: The path to the new working tree.
139140 """
140141 temp_dir = tempfile.mkdtemp()
141142 run_git_or_fail(['worktree', 'add', temp_dir, branch],
4747 def git_version(git_path=_DEFAULT_GIT):
4848 """Attempt to determine the version of git currently installed.
4949
50 :param git_path: Path to the git executable; defaults to the version in
50 Args:
51 git_path: Path to the git executable; defaults to the version in
5152 the system path.
52 :return: A tuple of ints of the form (major, minor, point, sub-point), or
53 Returns: A tuple of ints of the form (major, minor, point, sub-point), or
5354 None if no git installation was found.
5455 """
5556 try:
7677 def require_git_version(required_version, git_path=_DEFAULT_GIT):
7778 """Require git version >= version, or skip the calling test.
7879
79 :param required_version: A tuple of ints of the form (major, minor, point,
80 Args:
81 required_version: A tuple of ints of the form (major, minor, point,
8082 sub-point); ommitted components default to 0.
81 :param git_path: Path to the git executable; defaults to the version in
83 git_path: Path to the git executable; defaults to the version in
8284 the system path.
83 :raise ValueError: if the required version tuple has too many parts.
84 :raise SkipTest: if no suitable git version was found at the given path.
85 Raises:
86 ValueError: if the required version tuple has too many parts.
87 SkipTest: if no suitable git version was found at the given path.
8588 """
8689 found_version = git_version(git_path=git_path)
8790 if found_version is None:
111114 Input is piped from the input parameter and output is sent to the standard
112115 streams, unless capture_stdout is set.
113116
114 :param args: A list of args to the git command.
115 :param git_path: Path to to the git executable.
116 :param input: Input data to be sent to stdin.
117 :param capture_stdout: Whether to capture and return stdout.
118 :param popen_kwargs: Additional kwargs for subprocess.Popen;
117 Args:
118 args: A list of args to the git command.
119 git_path: Path to to the git executable.
120 input: Input data to be sent to stdin.
121 capture_stdout: Whether to capture and return stdout.
122 popen_kwargs: Additional kwargs for subprocess.Popen;
119123 stdin/stdout args are ignored.
120 :return: A tuple of (returncode, stdout contents). If capture_stdout is
124 Returns: A tuple of (returncode, stdout contents). If capture_stdout is
121125 False, None will be returned as stdout contents.
122 :raise OSError: if the git executable was not found.
126 Raises:
127 OSError: if the git executable was not found.
123128 """
124129
125130 env = popen_kwargs.pop('env', {})
154159 These are used rather than binary repos for compat tests because they are
155160 more compact and human-editable, and we already depend on git.
156161
157 :param name: The name of the repository export file, relative to
162 Args:
163 name: The name of the repository export file, relative to
158164 dulwich/tests/data/repos.
159 :returns: The path to the imported repository.
165 Returns: The path to the imported repository.
160166 """
161167 temp_dir = tempfile.mkdtemp()
162168 export_path = os.path.join(_REPOS_DATA_DIR, name)
174180
175181 Defaults to checking 10 times with a delay of 0.1 sec between tries.
176182
177 :param limit: Number of attempts before deciding no daemon is running.
178 :param delay: Delay between connection attempts.
179 :param timeout: Socket timeout for connection attempts.
180 :param port: Port on which we expect the daemon to appear.
181 :returns: A boolean, true if a daemon is running on the specified port,
183 Args:
184 limit: Number of attempts before deciding no daemon is running.
185 delay: Delay between connection attempts.
186 timeout: Socket timeout for connection attempts.
187 port: Port on which we expect the daemon to appear.
188 Returns: A boolean, true if a daemon is running on the specified port,
182189 false if not.
183190 """
184191 for _ in range(limit):
230237 def import_repo(self, name):
231238 """Import a repo from a fast-export file in a temporary directory.
232239
233 :param name: The name of the repository export file, relative to
240 Args:
241 name: The name of the repository export file, relative to
234242 dulwich/tests/data/repos.
235 :returns: An initialized Repo object that lives in a temporary
243 Returns: An initialized Repo object that lives in a temporary
236244 directory.
237245 """
238246 path = import_repo_to_dir(name)
212212 def make_file_commit(self, file_cmds):
213213 """Create a trivial commit with the specified file commands.
214214
215 :param file_cmds: File commands to run.
216 :return: The created commit object
215 Args:
216 file_cmds: File commands to run.
217 Returns: The created commit object
217218 """
218219 from fastimport import commands
219220 cmd = commands.CommitCommand(
6666 accidentally or intentionally modifying those repos in place. Use
6767 tear_down_repo to delete any temp files created.
6868
69 :param name: The name of the repository, relative to
69 Args:
70 name: The name of the repository, relative to
7071 dulwich/tests/data/repos
71 :param temp_dir: temporary directory to initialize to. If not provided, a
72 temp_dir: temporary directory to initialize to. If not provided, a
7273 temporary directory will be created.
73 :returns: An initialized Repo object that lives in a temporary directory.
74 Returns: An initialized Repo object that lives in a temporary directory.
7475 """
7576 if temp_dir is None:
7677 temp_dir = tempfile.mkdtemp()
9495 reassignment, which is not otherwise possible with objects having
9596 __slots__.
9697
97 :param attrs: dict of attributes to set on the new object.
98 :return: A newly initialized object of type cls.
98 Args:
99 attrs: dict of attributes to set on the new object.
100 Returns: A newly initialized object of type cls.
99101 """
100102
101103 class TestObject(cls):
122124 def make_commit(**attrs):
123125 """Make a Commit object with a default set of members.
124126
125 :param attrs: dict of attributes to overwrite from the default values.
126 :return: A newly initialized Commit object.
127 Args:
128 attrs: dict of attributes to overwrite from the default values.
129 Returns: A newly initialized Commit object.
127130 """
128131 default_time = 1262304000 # 2010-01-01 00:00:00
129132 all_attrs = {'author': b'Test Author <test@nodomain.com>',
142145 def make_tag(target, **attrs):
143146 """Make a Tag object with a default set of values.
144147
145 :param target: object to be tagged (Commit, Blob, Tree, etc)
146 :param attrs: dict of attributes to overwrite from the default values.
147 :return: A newly initialized Tag object.
148 Args:
149 target: object to be tagged (Commit, Blob, Tree, etc)
150 attrs: dict of attributes to overwrite from the default values.
151 Returns: A newly initialized Tag object.
148152 """
149153 target_id = target.id
150154 target_type = object_class(target.type_name)
185189 test_foo = functest_builder(_do_some_test, foo_py)
186190 test_foo_extension = ext_functest_builder(_do_some_test, _foo_c)
187191
188 :param method: The method to run. It must must two parameters, self and the
192 Args:
193 method: The method to run. It must must two parameters, self and the
189194 function implementation to test.
190 :param func: The function implementation to pass to method.
195 func: The function implementation to pass to method.
191196 """
192197
193198 def do_test(self):
201206 def build_pack(f, objects_spec, store=None):
202207 """Write test pack data from a concise spec.
203208
204 :param f: A file-like object to write the pack to.
205 :param objects_spec: A list of (type_num, obj). For non-delta types, obj
209 Args:
210 f: A file-like object to write the pack to.
211 objects_spec: A list of (type_num, obj). For non-delta types, obj
206212 is the string of that object's data.
207213 For delta types, obj is a tuple of (base, data), where:
208214
212218 * data is a string of the full, non-deltified data for that object.
213219
214220 Note that offsets/refs and deltas are computed within this function.
215 :param store: An optional ObjectStore for looking up external refs.
216 :return: A list of tuples in the order specified by objects_spec:
221 store: An optional ObjectStore for looking up external refs.
222 Returns: A list of tuples in the order specified by objects_spec:
217223 (offset, type num, data, sha, CRC32)
218224 """
219225 sf = SHA1Writer(f)
284290 If not otherwise specified, commits will refer to the empty tree and have
285291 commit times increasing in the same order as the commit spec.
286292
287 :param object_store: An ObjectStore to commit objects to.
288 :param commit_spec: An iterable of iterables of ints defining the commit
293 Args:
294 object_store: An ObjectStore to commit objects to.
295 commit_spec: An iterable of iterables of ints defining the commit
289296 graph. Each entry defines one commit, and entries must be in
290297 topological order. The first element of each entry is a commit number,
291298 and the remaining elements are its parents. The commit numbers are only
292299 meaningful for the call to make_commits; since real commit objects are
293300 created, they will get created with real, opaque SHAs.
294 :param trees: An optional dict of commit number -> tree spec for building
301 trees: An optional dict of commit number -> tree spec for building
295302 trees for commits. The tree spec is an iterable of (path, blob, mode)
296303 or (path, blob) entries; if mode is omitted, it defaults to the normal
297304 file mode (0100644).
298 :param attrs: A dict of commit number -> (dict of attribute -> value) for
305 attrs: A dict of commit number -> (dict of attribute -> value) for
299306 assigning additional values to the commits.
300 :return: The list of commit objects created.
301 :raise ValueError: If an undefined commit identifier is listed as a parent.
307 Returns: The list of commit objects created.
308 Raises:
309 ValueError: If an undefined commit identifier is listed as a parent.
302310 """
303311 if trees is None:
304312 trees = {}
5959 def changes(self, path_prefix=None):
6060 """Get the tree changes for this entry.
6161
62 :param path_prefix: Portion of the path in the repository to
62 Args:
63 path_prefix: Portion of the path in the repository to
6364 use to filter changes. Must be a directory name. Must be
6465 a full, valid, path reference (no partial names or wildcards).
65 :return: For commits with up to one parent, a list of TreeChange
66 Returns: For commits with up to one parent, a list of TreeChange
6667 objects; if the commit has no parents, these will be relative to
6768 the empty tree. For merge commits, a list of lists of TreeChange
6869 objects; see dulwich.diff.tree_changes_for_merge.
237238 queue_cls=_CommitTimeQueue):
238239 """Constructor.
239240
240 :param store: ObjectStore instance for looking up objects.
241 :param include: Iterable of SHAs of commits to include along with their
241 Args:
242 store: ObjectStore instance for looking up objects.
243 include: Iterable of SHAs of commits to include along with their
242244 ancestors.
243 :param exclude: Iterable of SHAs of commits to exclude along with their
245 exclude: Iterable of SHAs of commits to exclude along with their
244246 ancestors, overriding includes.
245 :param order: ORDER_* constant specifying the order of results.
247 order: ORDER_* constant specifying the order of results.
246248 Anything other than ORDER_DATE may result in O(n) memory usage.
247 :param reverse: If True, reverse the order of output, requiring O(n)
249 reverse: If True, reverse the order of output, requiring O(n)
248250 memory.
249 :param max_entries: The maximum number of entries to yield, or None for
251 max_entries: The maximum number of entries to yield, or None for
250252 no limit.
251 :param paths: Iterable of file or subtree paths to show entries for.
252 :param rename_detector: diff.RenameDetector object for detecting
253 paths: Iterable of file or subtree paths to show entries for.
254 rename_detector: diff.RenameDetector object for detecting
253255 renames.
254 :param follow: If True, follow path across renames/copies. Forces a
256 follow: If True, follow path across renames/copies. Forces a
255257 default rename_detector.
256 :param since: Timestamp to list commits after.
257 :param until: Timestamp to list commits before.
258 :param get_parents: Method to retrieve the parents of a commit
259 :param queue_cls: A class to use for a queue of commits, supporting the
258 since: Timestamp to list commits after.
259 until: Timestamp to list commits before.
260 get_parents: Method to retrieve the parents of a commit
261 queue_cls: A class to use for a queue of commits, supporting the
260262 iterator protocol. The constructor takes a single argument, the
261263 Walker.
262264 """
316318 def _should_return(self, entry):
317319 """Determine if a walk entry should be returned..
318320
319 :param entry: The WalkEntry to consider.
320 :return: True if the WalkEntry should be returned by this walk, or
321 Args:
322 entry: The WalkEntry to consider.
323 Returns: True if the WalkEntry should be returned by this walk, or
321324 False otherwise (e.g. if it doesn't match any requested paths).
322325 """
323326 commit = entry.commit
363366 def _reorder(self, results):
364367 """Possibly reorder a results iterator.
365368
366 :param results: An iterator of WalkEntry objects, in the order returned
369 Args:
370 results: An iterator of WalkEntry objects, in the order returned
367371 from the queue_cls.
368 :return: An iterator or list of WalkEntry objects, in the order
372 Returns: An iterator or list of WalkEntry objects, in the order
369373 required by the Walker.
370374 """
371375 if self.order == ORDER_TOPO:
384388 This works best assuming the entries are already in almost-topological
385389 order, e.g. in commit time order.
386390
387 :param entries: An iterable of WalkEntry objects.
388 :param get_parents: Optional function for getting the parents of a commit.
389 :return: iterator over WalkEntry objects from entries in FIFO order, except
391 Args:
392 entries: An iterable of WalkEntry objects.
393 get_parents: Optional function for getting the parents of a commit.
394 Returns: iterator over WalkEntry objects from entries in FIFO order, except
390395 where a parent would be yielded before any of its children.
391396 """
392397 todo = collections.deque()
8888 def url_prefix(mat):
8989 """Extract the URL prefix from a regex match.
9090
91 :param mat: A regex match object.
92 :returns: The URL prefix, defined as the text before the match in the
91 Args:
92 mat: A regex match object.
93 Returns: The URL prefix, defined as the text before the match in the
9394 original string. Normalized to start with one leading slash and end
9495 with zero.
9596 """
104105 def send_file(req, f, content_type):
105106 """Send a file-like object to the request output.
106107
107 :param req: The HTTPGitRequest object to send output to.
108 :param f: An open file-like object to send; will be closed.
109 :param content_type: The MIME type for the file.
110 :return: Iterator over the contents of the file, as chunks.
108 Args:
109 req: The HTTPGitRequest object to send output to.
110 f: An open file-like object to send; will be closed.
111 content_type: The MIME type for the file.
112 Returns: Iterator over the contents of the file, as chunks.
111113 """
112114 if f is None:
113115 yield req.not_found('File not found')