Skip to content

Commit

Permalink
fix(remote): allow to raise during push/fetch
Browse files Browse the repository at this point in the history
Do not swallow non-zero exit status during push and fetch unless
we managed to parse head information.

This behaviour will effetively handle cases were no work was done
due to invalid refspecs or insufficient permissions.

Fixes #271
  • Loading branch information
Byron committed Apr 8, 2015
1 parent 723f100 commit e9f8f15
Show file tree
Hide file tree
Showing 4 changed files with 18 additions and 34 deletions.
4 changes: 4 additions & 0 deletions doc/source/changes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ Changelog
* `IndexFile.add()` will now write the index without any extension data by default. However, you may override this behaviour with the new `write_extension_data` keyword argument.

- Renamed `ignore_tree_extension_data` keyword argument in `IndexFile.write(...)` to `ignore_extension_data`
* If the git command executed during `Remote.push(...)|fetch(...)` returns with an non-zero exit code and GitPython didn't
obtain any head-information, the corresponding `GitCommandError` will be raised. This may break previous code which expected
these operations to never raise. However, that behavious is undesirable as it would effectively hide the fact that there
was an error. See `this issue <https://github.com/gitpython-developers/GitPython/issues/271>`_ for more information.

0.3.6 - Features
================
Expand Down
13 changes: 11 additions & 2 deletions git/remote.py
Original file line number Diff line number Diff line change
Expand Up @@ -568,7 +568,12 @@ def _get_fetch_info_from_stderr(self, proc, progress):
# end

# We are only interested in stderr here ...
finalize_process(proc)
try:
finalize_process(proc)
except Exception:
if len(fetch_info_lines) == 0:
raise
# end exception handler

# read head information
fp = open(join(self.repo.git_dir, 'FETCH_HEAD'), 'rb')
Expand Down Expand Up @@ -601,7 +606,11 @@ def stdout_handler(line):
# END exception handling
# END for each line

handle_process_output(proc, stdout_handler, progress_handler, finalize_process)
try:
handle_process_output(proc, stdout_handler, progress_handler, finalize_process)
except Exception:
if len(output) == 0:
raise
return output

def fetch(self, refspec=None, progress=None, **kwargs):
Expand Down
3 changes: 1 addition & 2 deletions git/test/test_remote.py
Original file line number Diff line number Diff line change
Expand Up @@ -313,8 +313,7 @@ def _assert_push_and_pull(self, remote, rw_repo, remote_repo):
self._do_test_push_result(res, remote)

# invalid refspec
res = remote.push("hellothere")
assert len(res) == 0
self.failUnlessRaises(GitCommandError, remote.push, "hellothere")

# push new tags
progress = TestRemoteProgress()
Expand Down
32 changes: 2 additions & 30 deletions git/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,7 @@

# NOTE: Some of the unused imports might be used/imported by others.
# Handle once test-cases are back up and running.
from .exc import (
GitCommandError,
InvalidGitRepositoryError
)
from .exc import InvalidGitRepositoryError

from .compat import (
MAXSIZE,
Expand Down Expand Up @@ -154,32 +151,7 @@ def get_user_id():

def finalize_process(proc):
"""Wait for the process (clone, fetch, pull or push) and handle its errors accordingly"""
try:
proc.wait()
except GitCommandError:
# if a push has rejected items, the command has non-zero return status
# a return status of 128 indicates a connection error - reraise the previous one
# Everything else will still be parsed and made available through PushInfo flags
# Estimated error results look like this:
# ```bash
# To /var/folders/xp/m48gs2tx2vg95tmtzw7tprs40000gn/T/tmpk5jeBeremote_repo_test_base
# ! refs/heads/master:refs/heads/master [rejected] (non-fast-forward)
# Done
# error: failed to push some refs to
# '/var/folders/xp/m48gs2tx2vg95tmtzw7tprs40000gn/T/tmpk5jeBeremote_repo_test_base'
# hint: Updates were rejected because the tip of your current branch is behind
# hint: its remote counterpart. Integrate the remote changes (e.g.
# hint: 'git pull ...') before pushing again.
# hint: See the 'Note about fast-forwards' in 'git push --help' for details.
# ```
# See https://github.com/gitpython-developers/GitPython/blob/master/git/test/test_remote.py#L305
# on how to check for these kinds of errors.
# Also see this issue for a reason for this verbosity:
# https://github.com/gitpython-developers/GitPython/issues/271
if proc.poll() == 128:
raise
pass
# END exception handling
proc.wait()

#} END utilities

Expand Down

0 comments on commit e9f8f15

Please # to comment.