|
@@ -9,6 +9,7 @@ import os |
|
|
|
|
|
|
|
|
from colorama import Fore, Style |
|
|
from colorama import Fore, Style |
|
|
from git import Repo, exc |
|
|
from git import Repo, exc |
|
|
|
|
|
from git.util import RemoteProgress |
|
|
|
|
|
|
|
|
__all__ = ["update_bookmarks", "update_directories"] |
|
|
__all__ = ["update_bookmarks", "update_directories"] |
|
|
|
|
|
|
|
@@ -22,6 +23,30 @@ INDENT1 = " " * 3 |
|
|
INDENT2 = " " * 7 |
|
|
INDENT2 = " " * 7 |
|
|
ERROR = RED + "Error:" + RESET |
|
|
ERROR = RED + "Error:" + RESET |
|
|
|
|
|
|
|
|
|
|
|
class _ProgressMonitor(RemoteProgress): |
|
|
|
|
|
"""Displays relevant output during the fetching process.""" |
|
|
|
|
|
|
|
|
|
|
|
def __init__(self, verbose): |
|
|
|
|
|
super(_ProgressMonitor, self).__init__() |
|
|
|
|
|
self._verbose = verbose |
|
|
|
|
|
|
|
|
|
|
|
def update(self, op_code, cur_count, max_count=None, message=''): |
|
|
|
|
|
"""Called whenever progress changes. Overrides default behavior.""" |
|
|
|
|
|
if self._verbose: |
|
|
|
|
|
if op_code & self.COUNTING: |
|
|
|
|
|
print(" ({0})".format(cur_count), end="") |
|
|
|
|
|
elif op_code & (self.COMPRESSING | self.RECEIVING): |
|
|
|
|
|
if op_code & self.BEGIN: |
|
|
|
|
|
print("\b, ", end="") |
|
|
|
|
|
if op_code & self.END: |
|
|
|
|
|
end = ")" |
|
|
|
|
|
else: |
|
|
|
|
|
end = "\b" * (1 + len(cur_count) + len(max_count)) |
|
|
|
|
|
print("{0}/{1}".format(cur_count, max_count), end=end) |
|
|
|
|
|
elif op_code & self.BEGIN: |
|
|
|
|
|
print(".", end="") |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class _Stasher(object): |
|
|
class _Stasher(object): |
|
|
"""Manages the stash state of a given repository.""" |
|
|
"""Manages the stash state of a given repository.""" |
|
|
|
|
|
|
|
@@ -50,11 +75,32 @@ def _read_config(repo, attr): |
|
|
except exc.GitCommandError: |
|
|
except exc.GitCommandError: |
|
|
return None |
|
|
return None |
|
|
|
|
|
|
|
|
def _fetch_remote(remote): |
|
|
|
|
|
"""Fetch a given remote, and display progress info along the way.""" |
|
|
|
|
|
print(INDENT2, "Fetching", remote.name, end="...") |
|
|
|
|
|
remote.fetch() ### TODO: show progress |
|
|
|
|
|
print(" done.") |
|
|
|
|
|
|
|
|
def _format_fetch_result(results): |
|
|
|
|
|
"""Format and print the results of a verbose fetch.""" |
|
|
|
|
|
info = [("NEW_HEAD", "new branches"), ("NEW_TAG", "new tags"), |
|
|
|
|
|
("FAST_FORWARD", "updates"), ("ERROR", "errors")] |
|
|
|
|
|
rlist = [] |
|
|
|
|
|
for attr, desc in info: |
|
|
|
|
|
names = [res.name for res in results if res.flags & getattr(res, attr)] |
|
|
|
|
|
if names: |
|
|
|
|
|
rlist.append("{0} ({1})".format(desc, ", ".join(names))) |
|
|
|
|
|
print(":", (", ".join(rlist) if rlist else "up to date") + ".") |
|
|
|
|
|
|
|
|
|
|
|
def _fetch_remotes(remotes, verbose): |
|
|
|
|
|
"""Fetch a list of remotes, displaying progress info along the way.""" |
|
|
|
|
|
if verbose: |
|
|
|
|
|
for remote in remotes: |
|
|
|
|
|
print(INDENT2, "Fetching", remote.name, end="") |
|
|
|
|
|
result = remote.fetch(progress=_ProgressMonitor(True)) |
|
|
|
|
|
_format_fetch_result(result) |
|
|
|
|
|
else: |
|
|
|
|
|
print(INDENT2, "Fetching:", end=" ") |
|
|
|
|
|
for i, remote in enumerate(remotes): |
|
|
|
|
|
print(remote.name, end="") |
|
|
|
|
|
remote.fetch(progress=_ProgressMonitor(False)) |
|
|
|
|
|
if i < len(remotes) - 1: |
|
|
|
|
|
print(", ", end="") |
|
|
|
|
|
print(".") |
|
|
|
|
|
|
|
|
def _is_up_to_date(repo, branch, upstream): |
|
|
def _is_up_to_date(repo, branch, upstream): |
|
|
"""Return whether *branch* is up-to-date with its *upstream*.""" |
|
|
"""Return whether *branch* is up-to-date with its *upstream*.""" |
|
@@ -106,6 +152,7 @@ def _update_branch(repo, branch, merge, rebase, stasher=None): |
|
|
if not upstream: |
|
|
if not upstream: |
|
|
print(" skipped: no upstream is tracked.") |
|
|
print(" skipped: no upstream is tracked.") |
|
|
return |
|
|
return |
|
|
|
|
|
|
|
|
try: |
|
|
try: |
|
|
branch.commit, upstream.commit |
|
|
branch.commit, upstream.commit |
|
|
except ValueError: |
|
|
except ValueError: |
|
@@ -114,6 +161,7 @@ def _update_branch(repo, branch, merge, rebase, stasher=None): |
|
|
if _is_up_to_date(repo, branch, upstream): |
|
|
if _is_up_to_date(repo, branch, upstream): |
|
|
print(" up to date.") |
|
|
print(" up to date.") |
|
|
return |
|
|
return |
|
|
|
|
|
|
|
|
if stasher: |
|
|
if stasher: |
|
|
stasher.clean() |
|
|
stasher.clean() |
|
|
branch.checkout() |
|
|
branch.checkout() |
|
@@ -150,8 +198,7 @@ def _update_repository(repo, current_only=False, rebase=False, merge=False, |
|
|
print(INDENT2, ERROR, "no remotes configured to pull from.") |
|
|
print(INDENT2, ERROR, "no remotes configured to pull from.") |
|
|
return |
|
|
return |
|
|
|
|
|
|
|
|
for remote in remotes: |
|
|
|
|
|
_fetch_remote(remote) |
|
|
|
|
|
|
|
|
_fetch_remotes(remotes, verbose) |
|
|
|
|
|
|
|
|
rebase = rebase or _read_config(repo, "pull.rebase") |
|
|
rebase = rebase or _read_config(repo, "pull.rebase") |
|
|
_update_branch(repo, active, merge, rebase) |
|
|
_update_branch(repo, active, merge, rebase) |
|
|