diff options
-rw-r--r-- | doc/source/tutorial.rst | 8 | ||||
-rw-r--r-- | git/remote.py | 31 | ||||
-rw-r--r-- | git/repo/base.py | 15 | ||||
-rw-r--r-- | git/test/test_git.py | 16 | ||||
-rw-r--r-- | git/test/test_remote.py | 5 |
5 files changed, 51 insertions, 24 deletions
diff --git a/doc/source/tutorial.rst b/doc/source/tutorial.rst index 632d2d0c..7cc296d8 100644 --- a/doc/source/tutorial.rst +++ b/doc/source/tutorial.rst @@ -343,6 +343,14 @@ This one sets a custom script to be executed in place of `ssh`, and can be used with repo.git.custom_environment(GIT_SSH=ssh_executable): repo.remotes.origin.fetch() +Here's an example executable that can be used in place of the `ssh_executable` above:: + + #!/bin/sh + ID_RSA=/var/lib/openshift/5562b947ecdd5ce939000038/app-deployments/id_rsa + exec /usr/bin/ssh -o StrictHostKeyChecking=no -i $ID_RSA "$@" + +Please note that the script must be executable (i.e. `chomd +x script.sh`). `StrictHostKeyChecking=no` is used to avoid prompts asking to save the hosts key to `~/.ssh/known_hosts`, which happens in case you run this as daemon. + You might also have a look at `Git.update_environment(...)` in case you want to setup a changed environment more permanently. Submodule Handling diff --git a/git/remote.py b/git/remote.py index 4baa2838..c9da1979 100644 --- a/git/remote.py +++ b/git/remote.py @@ -538,7 +538,6 @@ class Remote(LazyMixin, Iterable): def _get_fetch_info_from_stderr(self, proc, progress): # skip first line as it is some remote info we are not interested in - # TODO: Use poll() to process stdout and stderr at same time output = IterableList('name') # lines which are no progress are fetch info lines @@ -551,11 +550,9 @@ class Remote(LazyMixin, Iterable): progress_handler = progress.new_message_handler() - for line in proc.stderr: - line = line.decode(defenc) - line = line.rstrip() + def my_progress_handler(line): for pline in progress_handler(line): - if line.startswith('fatal:'): + if line.startswith('fatal:') or line.startswith('error:'): raise GitCommandError(("Error when fetching: %s" % line,), 2) # END handle special messages for cmd in cmds: @@ -568,12 +565,7 @@ class Remote(LazyMixin, Iterable): # end # We are only interested in stderr here ... - try: - finalize_process(proc) - except Exception: - if len(fetch_info_lines) == 0: - raise - # end exception handler + handle_process_output(proc, None, my_progress_handler, finalize_process) # read head information fp = open(join(self.repo.git_dir, 'FETCH_HEAD'), 'rb') @@ -593,7 +585,6 @@ class Remote(LazyMixin, Iterable): # we hope stdout can hold all the data, it should ... # read the lines manually as it will use carriage returns between the messages # to override the previous one. This is why we read the bytes manually - # TODO: poll() on file descriptors to know what to read next, process streams concurrently progress_handler = progress.new_message_handler() output = IterableList('name') @@ -613,6 +604,18 @@ class Remote(LazyMixin, Iterable): raise return output + def _assert_refspec(self): + """Turns out we can't deal with remotes if the refspec is missing""" + config = self.config_reader + try: + if config.get_value('fetch', default=type) is type: + msg = "Remote '%s' has no refspec set.\n" + msg += "You can set it as follows:" + msg += " 'git config --add \"remote.%s.fetch +refs/heads/*:refs/heads/*\"'." % self.name + raise AssertionError(msg) + finally: + config.release() + def fetch(self, refspec=None, progress=None, **kwargs): """Fetch the latest changes for this remote @@ -640,6 +643,7 @@ class Remote(LazyMixin, Iterable): :note: As fetch does not provide progress information to non-ttys, we cannot make it available here unfortunately as in the 'push' method.""" + self._assert_refspec() kwargs = add_progress(kwargs, self.repo.git, progress) if isinstance(refspec, list): args = refspec @@ -647,7 +651,6 @@ class Remote(LazyMixin, Iterable): args = [refspec] proc = self.repo.git.fetch(self, *args, with_extended_output=True, as_process=True, v=True, **kwargs) - proc.stdout.close() res = self._get_fetch_info_from_stderr(proc, progress or RemoteProgress()) if hasattr(self.repo.odb, 'update_cache'): self.repo.odb.update_cache() @@ -661,9 +664,9 @@ class Remote(LazyMixin, Iterable): :param progress: see 'push' method :param kwargs: Additional arguments to be passed to git-pull :return: Please see 'fetch' method """ + self._assert_refspec() kwargs = add_progress(kwargs, self.repo.git, progress) proc = self.repo.git.pull(self, refspec, with_extended_output=True, as_process=True, v=True, **kwargs) - proc.stdout.close() res = self._get_fetch_info_from_stderr(proc, progress or RemoteProgress()) if hasattr(self.repo.odb, 'update_cache'): self.repo.odb.update_cache() diff --git a/git/repo/base.py b/git/repo/base.py index c8915bbc..88e21379 100644 --- a/git/repo/base.py +++ b/git/repo/base.py @@ -563,7 +563,8 @@ class Repo(object): alternates = property(_get_alternates, _set_alternates, doc="Retrieve a list of alternates paths or set a list paths to be used as alternates") - def is_dirty(self, index=True, working_tree=True, untracked_files=False): + def is_dirty(self, index=True, working_tree=True, untracked_files=False, + submodules=True): """ :return: ``True``, the repository is considered dirty. By default it will react @@ -575,7 +576,9 @@ class Repo(object): return False # start from the one which is fastest to evaluate - default_args = ('--abbrev=40', '--full-index', '--raw') + default_args = ['--abbrev=40', '--full-index', '--raw'] + if not submodules: + default_args.append('--ignore-submodules') if index: # diff index against HEAD if isfile(self.index.path) and \ @@ -588,7 +591,7 @@ class Repo(object): return True # END working tree handling if untracked_files: - if len(self.untracked_files): + if len(self._get_untracked_files(ignore_submodules=not submodules)): return True # END untracked files return False @@ -604,10 +607,14 @@ class Repo(object): :note: ignored files will not appear here, i.e. files mentioned in .gitignore""" + return self._get_untracked_files() + + def _get_untracked_files(self, **kwargs): # make sure we get all files, no only untracked directores proc = self.git.status(porcelain=True, untracked_files=True, - as_process=True) + as_process=True, + **kwargs) # Untracked files preffix in porcelain mode prefix = "?? " untracked_files = list() diff --git a/git/test/test_git.py b/git/test/test_git.py index 742c842d..a4172f7a 100644 --- a/git/test/test_git.py +++ b/git/test/test_git.py @@ -192,10 +192,14 @@ class TestGit(TestBase): rw_repo = Repo.init(os.path.join(rw_dir, 'repo')) remote = rw_repo.create_remote('ssh-origin', "ssh://git@server/foo") - with rw_repo.git.custom_environment(GIT_SSH=path): - try: - remote.fetch() - except GitCommandError as err: - assert 'FOO' in str(err) + # This only works if we are not evaluating git-push/pull output in a thread ! + import select + if hasattr(select, 'poll'): + with rw_repo.git.custom_environment(GIT_SSH=path): + try: + remote.fetch() + except GitCommandError as err: + assert 'FOO' in str(err) + # end # end - # end + # end if select.poll exists diff --git a/git/test/test_remote.py b/git/test/test_remote.py index af854988..6c37614d 100644 --- a/git/test/test_remote.py +++ b/git/test/test_remote.py @@ -494,6 +494,11 @@ class TestRemote(TestBase): fetch_info_line_fmt = "c437ee5deb8d00cf02f03720693e4c802e99f390 not-for-merge %s '0.3' of " fetch_info_line_fmt += "git://github.com/gitpython-developers/GitPython" remote_info_line_fmt = "* [new branch] nomatter -> %s" + + self.failUnlessRaises(ValueError, FetchInfo._from_line, self.rorepo, + remote_info_line_fmt % "refs/something/branch", + "269c498e56feb93e408ed4558c8138d750de8893\t\t/Users/ben/test/foo\n") + fi = FetchInfo._from_line(self.rorepo, remote_info_line_fmt % "local/master", fetch_info_line_fmt % 'remote-tracking branch') |