| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -24,7 +24,7 @@ | |||
| 24 | 24 | TagReference | |
| 25 | 25 | ) | |
| 26 | 26 | ||
| 27 | - from git.util import join_path | ||
| 27 | + from git.util import join_path | ||
| 28 | 28 | from gitdb.util import join | |
| 29 | 29 | ||
| 30 | 30 | import re | |
@@ -33,6 +33,58 @@ | |||
| 33 | 33 | ||
| 34 | 34 | __all__ = ('RemoteProgress', 'PushInfo', 'FetchInfo', 'Remote') | |
| 35 | 35 | ||
| 36 | + #{ Utilities | ||
| 37 | + | ||
| 38 | + def digest_process_messages(fh, progress): | ||
| 39 | + """Read progress messages from file-like object fh, supplying the respective | ||
| 40 | + progress messages to the progress instance. | ||
| 41 | + | ||
| 42 | + :param fh: File handle to read from | ||
| 43 | + :return: list(line, ...) list of lines without linebreaks that did | ||
| 44 | + not contain progress information""" | ||
| 45 | + line_so_far = '' | ||
| 46 | + dropped_lines = list() | ||
| 47 | + while True: | ||
| 48 | + char = fh.read(1) | ||
| 49 | + if not char: | ||
| 50 | + break | ||
| 51 | + | ||
| 52 | + if char in ('\r', '\n'): | ||
| 53 | + dropped_lines.extend(progress._parse_progress_line(line_so_far)) | ||
| 54 | + line_so_far = '' | ||
| 55 | + else: | ||
| 56 | + line_so_far += char | ||
| 57 | + # END process parsed line | ||
| 58 | + # END while file is not done reading | ||
| 59 | + return dropped_lines | ||
| 60 | + | ||
| 61 | + def finalize_process(proc): | ||
| 62 | + """Wait for the process (clone, fetch, pull or push) and handle its errors accordingly""" | ||
| 63 | + try: | ||
| 64 | + proc.wait() | ||
| 65 | + except GitCommandError,e: | ||
| 66 | + # if a push has rejected items, the command has non-zero return status | ||
| 67 | + # a return status of 128 indicates a connection error - reraise the previous one | ||
| 68 | + if proc.poll() == 128: | ||
| 69 | + raise | ||
| 70 | + pass | ||
| 71 | + # END exception handling | ||
| 72 | + | ||
| 73 | + def add_progress(kwargs, git, progress): | ||
| 74 | + """Add the --progress flag to the given kwargs dict if supported by the | ||
| 75 | + git command. If the actual progress in the given progress instance is not | ||
| 76 | + given, we do not request any progress | ||
| 77 | + :return: possibly altered kwargs""" | ||
| 78 | + if progress is not None: | ||
| 79 | + v = git.version_info | ||
| 80 | + if v[0] > 1 or v[1] > 7 or v[2] > 0 or v[3] > 3: | ||
| 81 | + kwargs['progress'] = True | ||
| 82 | + #END handle --progress | ||
| 83 | + #END handle progress | ||
| 84 | + return kwargs | ||
| 85 | + | ||
| 86 | + #} END utilities | ||
| 87 | + | ||
| 36 | 88 | ||
| 37 | 89 | class PushInfo(object): | |
| 38 | 90 | """ | |
@@ -432,42 +484,6 @@ def update(self, **kwargs): | |||
| 432 | 484 | self.repo.git.remote("update", self.name) | |
| 433 | 485 | return self | |
| 434 | 486 | ||
| 435 | - def _digest_process_messages(self, fh, progress): | ||
| 436 | - """Read progress messages from file-like object fh, supplying the respective | ||
| 437 | - progress messages to the progress instance. | ||
| 438 | - | ||
| 439 | - :return: list(line, ...) list of lines without linebreaks that did | ||
| 440 | - not contain progress information""" | ||
| 441 | - line_so_far = '' | ||
| 442 | - dropped_lines = list() | ||
| 443 | - while True: | ||
| 444 | - char = fh.read(1) | ||
| 445 | - if not char: | ||
| 446 | - break | ||
| 447 | - | ||
| 448 | - if char in ('\r', '\n'): | ||
| 449 | - dropped_lines.extend(progress._parse_progress_line(line_so_far)) | ||
| 450 | - line_so_far = '' | ||
| 451 | - else: | ||
| 452 | - line_so_far += char | ||
| 453 | - # END process parsed line | ||
| 454 | - # END while file is not done reading | ||
| 455 | - return dropped_lines | ||
| 456 | - | ||
| 457 | - | ||
| 458 | - def _finalize_proc(self, proc): | ||
| 459 | - """Wait for the process (fetch, pull or push) and handle its errors accordingly""" | ||
| 460 | - try: | ||
| 461 | - proc.wait() | ||
| 462 | - except GitCommandError,e: | ||
| 463 | - # if a push has rejected items, the command has non-zero return status | ||
| 464 | - # a return status of 128 indicates a connection error - reraise the previous one | ||
| 465 | - if proc.poll() == 128: | ||
| 466 | - raise | ||
| 467 | - pass | ||
| 468 | - # END exception handling | ||
| 469 | - | ||
| 470 | - | ||
| 471 | 487 | def _get_fetch_info_from_stderr(self, proc, progress): | |
| 472 | 488 | # skip first line as it is some remote info we are not interested in | |
| 473 | 489 | output = IterableList('name') | |
@@ -477,7 +493,7 @@ def _get_fetch_info_from_stderr(self, proc, progress): | |||
| 477 | 493 | # this also waits for the command to finish | |
| 478 | 494 | # Skip some progress lines that don't provide relevant information | |
| 479 | 495 | fetch_info_lines = list() | |
| 480 | - for line in self._digest_process_messages(proc.stderr, progress): | ||
| 496 | + for line in digest_process_messages(proc.stderr, progress): | ||
| 481 | 497 | if line.startswith('From') or line.startswith('remote: Total'): | |
| 482 | 498 | continue | |
| 483 | 499 | elif line.startswith('warning:'): | |
@@ -499,15 +515,15 @@ def _get_fetch_info_from_stderr(self, proc, progress): | |||
| 499 | 515 | output.extend(FetchInfo._from_line(self.repo, err_line, fetch_line) | |
| 500 | 516 | for err_line,fetch_line in zip(fetch_info_lines, fetch_head_info)) | |
| 501 | 517 | ||
| 502 | - self._finalize_proc(proc) | ||
| 518 | + finalize_process(proc) | ||
| 503 | 519 | return output | |
| 504 | 520 | ||
| 505 | 521 | def _get_push_info(self, proc, progress): | |
| 506 | 522 | # read progress information from stderr | |
| 507 | 523 | # we hope stdout can hold all the data, it should ... | |
| 508 | 524 | # read the lines manually as it will use carriage returns between the messages | |
| 509 | 525 | # to override the previous one. This is why we read the bytes manually | |
| 510 | - self._digest_process_messages(proc.stderr, progress) | ||
| 526 | + digest_process_messages(proc.stderr, progress) | ||
| 511 | 527 | ||
| 512 | 528 | output = IterableList('name') | |
| 513 | 529 | for line in proc.stdout.readlines(): | |
@@ -519,7 +535,7 @@ def _get_push_info(self, proc, progress): | |||
| 519 | 535 | # END exception handling | |
| 520 | 536 | # END for each line | |
| 521 | 537 | ||
| 522 | - self._finalize_proc(proc) | ||
| 538 | + finalize_process(proc) | ||
| 523 | 539 | return output | |
| 524 | 540 | ||
| 525 | 541 | ||
@@ -546,6 +562,7 @@ def fetch(self, refspec=None, progress=None, **kwargs): | |||
| 546 | 562 | :note: | |
| 547 | 563 | As fetch does not provide progress information to non-ttys, we cannot make | |
| 548 | 564 | it available here unfortunately as in the 'push' method.""" | |
| 565 | + kwargs = add_progress(kwargs, self.repo.git, progress) | ||
| 549 | 566 | proc = self.repo.git.fetch(self, refspec, with_extended_output=True, as_process=True, v=True, **kwargs) | |
| 550 | 567 | return self._get_fetch_info_from_stderr(proc, progress or RemoteProgress()) | |
| 551 | 568 | ||
@@ -557,6 +574,7 @@ def pull(self, refspec=None, progress=None, **kwargs): | |||
| 557 | 574 | :param progress: see 'push' method | |
| 558 | 575 | :param kwargs: Additional arguments to be passed to git-pull | |
| 559 | 576 | :return: Please see 'fetch' method """ | |
| 577 | + kwargs = add_progress(kwargs, self.repo.git, progress) | ||
| 560 | 578 | proc = self.repo.git.pull(self, refspec, with_extended_output=True, as_process=True, v=True, **kwargs) | |
| 561 | 579 | return self._get_fetch_info_from_stderr(proc, progress or RemoteProgress()) | |
| 562 | 580 | ||
@@ -578,6 +596,7 @@ def push(self, refspec=None, progress=None, **kwargs): | |||
| 578 | 596 | in their flags. | |
| 579 | 597 | If the operation fails completely, the length of the returned IterableList will | |
| 580 | 598 | be null.""" | |
| 599 | + kwargs = add_progress(kwargs, self.repo.git, progress) | ||
| 581 | 600 | proc = self.repo.git.push(self, refspec, porcelain=True, as_process=True, **kwargs) | |
| 582 | 601 | return self._get_push_info(proc, progress or RemoteProgress()) | |
| 583 | 602 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -11,13 +11,18 @@ | |||
| 11 | 11 | from git.index import IndexFile | |
| 12 | 12 | from git.objects import * | |
| 13 | 13 | from git.config import GitConfigParser | |
| 14 | - from git.remote import Remote | ||
| 14 | + from git.remote import ( | ||
| 15 | + Remote, | ||
| 16 | + digest_process_messages, | ||
| 17 | + finalize_process, | ||
| 18 | + add_progress | ||
| 19 | + ) | ||
| 20 | + | ||
| 15 | 21 | from git.db import ( | |
| 16 | 22 | GitCmdObjectDB, | |
| 17 | 23 | GitDB | |
| 18 | 24 | ) | |
| 19 | 25 | ||
| 20 | - | ||
| 21 | 26 | from gitdb.util import ( | |
| 22 | 27 | join, | |
| 23 | 28 | isfile, | |
@@ -652,7 +657,7 @@ def init(cls, path=None, mkdir=True, **kwargs): | |||
| 652 | 657 | return Repo(path) | |
| 653 | 658 | ||
| 654 | 659 | @classmethod | |
| 655 | - def _clone(cls, git, url, path, odb_default_type, **kwargs): | ||
| 660 | + def _clone(cls, git, url, path, odb_default_type, progress, **kwargs): | ||
| 656 | 661 | # special handling for windows for path at which the clone should be | |
| 657 | 662 | # created. | |
| 658 | 663 | # tilde '~' will be expanded to the HOME no matter where the ~ occours. Hence | |
@@ -679,7 +684,11 @@ def _clone(cls, git, url, path, odb_default_type, **kwargs): | |||
| 679 | 684 | # END windows handling | |
| 680 | 685 | ||
| 681 | 686 | try: | |
| 682 | - git.clone(url, path, **kwargs) | ||
| 687 | + proc = git.clone(url, path, with_extended_output=True, as_process=True, v=True, **add_progress(kwargs, git, progress)) | ||
| 688 | + if progress: | ||
| 689 | + digest_process_messages(proc.stderr, progress) | ||
| 690 | + #END handle progress | ||
| 691 | + finalize_process(proc) | ||
| 683 | 692 | finally: | |
| 684 | 693 | if prev_cwd is not None: | |
| 685 | 694 | os.chdir(prev_cwd) | |
@@ -703,28 +712,31 @@ def _clone(cls, git, url, path, odb_default_type, **kwargs): | |||
| 703 | 712 | # END handle remote repo | |
| 704 | 713 | return repo | |
| 705 | 714 | ||
| 706 | - def clone(self, path, **kwargs): | ||
| 715 | + def clone(self, path, progress=None, **kwargs): | ||
| 707 | 716 | """Create a clone from this repository. | |
| 708 | 717 | :param path: | |
| 709 | 718 | is the full path of the new repo (traditionally ends with ./<name>.git). | |
| 710 | 719 | ||
| 720 | + :param progress: See 'git.remote.Remote.push'. | ||
| 721 | + | ||
| 711 | 722 | :param kwargs: | |
| 712 | 723 | odbt = ObjectDatabase Type, allowing to determine the object database | |
| 713 | 724 | implementation used by the returned Repo instance | |
| 714 | 725 | ||
| 715 | 726 | All remaining keyword arguments are given to the git-clone command | |
| 716 | 727 | ||
| 717 | 728 | :return: ``git.Repo`` (the newly cloned repo)""" | |
| 718 | - return self._clone(self.git, self.git_dir, path, type(self.odb), **kwargs) | ||
| 729 | + return self._clone(self.git, self.git_dir, path, type(self.odb), progress, **kwargs) | ||
| 719 | 730 | ||
| 720 | 731 | @classmethod | |
| 721 | - def clone_from(cls, url, to_path, **kwargs): | ||
| 732 | + def clone_from(cls, url, to_path, progress=None, **kwargs): | ||
| 722 | 733 | """Create a clone from the given URL | |
| 723 | 734 | :param url: valid git url, see http://www.kernel.org/pub/software/scm/git/docs/git-clone.html#URLS | |
| 724 | 735 | :param to_path: Path to which the repository should be cloned to | |
| 736 | + :param progress: See 'git.remote.Remote.push'. | ||
| 725 | 737 | :param kwargs: see the ``clone`` method | |
| 726 | 738 | :return: Repo instance pointing to the cloned directory""" | |
| 727 | - return cls._clone(Git(os.getcwd()), url, to_path, GitCmdObjectDB, **kwargs) | ||
| 739 | + return cls._clone(Git(os.getcwd()), url, to_path, GitCmdObjectDB, progress, **kwargs) | ||
| 728 | 740 | ||
| 729 | 741 | def archive(self, ostream, treeish=None, prefix=None, **kwargs): | |
| 730 | 742 | """Archive the tree at the given revision. | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -109,8 +109,8 @@ class RemoteProgress(object): | |||
| 109 | 109 | Handler providing an interface to parse progress information emitted by git-push | |
| 110 | 110 | and git-fetch and to dispatch callbacks allowing subclasses to react to the progress. | |
| 111 | 111 | """ | |
| 112 | - _num_op_codes = 5 | ||
| 113 | - BEGIN, END, COUNTING, COMPRESSING, WRITING = [1 << x for x in range(_num_op_codes)] | ||
| 112 | + _num_op_codes = 7 | ||
| 113 | + BEGIN, END, COUNTING, COMPRESSING, WRITING, RECEIVING, RESOLVING = [1 << x for x in range(_num_op_codes)] | ||
| 114 | 114 | STAGE_MASK = BEGIN|END | |
| 115 | 115 | OP_MASK = ~STAGE_MASK | |
| 116 | 116 | ||
@@ -168,6 +168,10 @@ def _parse_progress_line(self, line): | |||
| 168 | 168 | op_code |= self.COMPRESSING | |
| 169 | 169 | elif op_name == "Writing objects": | |
| 170 | 170 | op_code |= self.WRITING | |
| 171 | + elif op_name == 'Receiving objects': | ||
| 172 | + op_code |= self.RECEIVING | ||
| 173 | + elif op_name == 'Resolving deltas': | ||
| 174 | + op_code |= self.RESOLVING | ||
| 171 | 175 | else: | |
| 172 | 176 | raise ValueError("Operation name %r unknown" % op_name) | |
| 173 | 177 | ||
| Back | FazBrowse Home | New Git URL |
0 commit comments