Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit d91ae75

Browse files
authored
Merge pull request #693 from satahippy/master
commit-msg hook support
2 parents 610d4c9 + eae04bf commit d91ae75

File tree

3 files changed

+108
-32
lines changed

3 files changed

+108
-32
lines changed

‎git/index/base.py‎

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -948,13 +948,32 @@ def commit(self, message, parent_commits=None, head=True, author=None,
948948
:return: Commit object representing the new commit"""
949949
if not skip_hooks:
950950
run_commit_hook('pre-commit', self)
951+
952+
self._write_commit_editmsg(message)
953+
run_commit_hook('commit-msg', self, self._commit_editmsg_filepath())
954+
message = self._read_commit_editmsg()
955+
self._remove_commit_editmsg()
951956
tree = self.write_tree()
952957
rval = Commit.create_from_tree(self.repo, tree, message, parent_commits,
953958
head, author=author, committer=committer,
954959
author_date=author_date, commit_date=commit_date)
955960
if not skip_hooks:
956961
run_commit_hook('post-commit', self)
957962
return rval
963+
964+
def _write_commit_editmsg(self, message):
965+
with open(self._commit_editmsg_filepath(), "wb") as commit_editmsg_file:
966+
commit_editmsg_file.write(message.encode(defenc))
967+
968+
def _remove_commit_editmsg(self):
969+
os.remove(self._commit_editmsg_filepath())
970+
971+
def _read_commit_editmsg(self):
972+
with open(self._commit_editmsg_filepath(), "rb") as commit_editmsg_file:
973+
return commit_editmsg_file.read().decode(defenc)
974+
975+
def _commit_editmsg_filepath(self):
976+
return osp.join(self.repo.common_dir, "COMMIT_EDITMSG")
958977

959978
@classmethod
960979
def _flush_stdin_and_wait(cls, proc, ignore_stdout=False):

‎git/index/fun.py‎

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -62,10 +62,11 @@ def hook_path(name, git_dir):
6262
return osp.join(git_dir, 'hooks', name)
6363

6464

65-
def run_commit_hook(name, index):
65+
def run_commit_hook(name, index, *args):
6666
"""Run the commit hook of the given name. Silently ignores hooks that do not exist.
6767
:param name: name of hook, like 'pre-commit'
6868
:param index: IndexFile instance
69+
:param args: arguments passed to hook file
6970
:raises HookExecutionError: """
7071
hp = hook_path(name, index.repo.git_dir)
7172
if not os.access(hp, os.X_OK):
@@ -75,7 +76,7 @@ def run_commit_hook(name, index):
7576
env['GIT_INDEX_FILE'] = safe_decode(index.path) if PY3 else safe_encode(index.path)
7677
env['GIT_EDITOR'] = ':'
7778
try:
78-
cmd = subprocess.Popen(hp,
79+
cmd = subprocess.Popen([hp] +list(args),
7980
env=env,
8081
stdout=subprocess.PIPE,
8182
stderr=subprocess.PIPE,
@@ -93,7 +94,7 @@ def run_commit_hook(name, index):
9394
if cmd.returncode != 0:
9495
stdout = force_text(stdout, defenc)
9596
stderr = force_text(stderr, defenc)
96-
raise HookExecutionError(hp, cmd.returncode, stdout, stderr)
97+
raise HookExecutionError(hp, cmd.returncode, stderr, stdout)
9798
# end handle return code
9899

99100

‎git/test/test_index.py‎

Lines changed: 85 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -729,35 +729,6 @@ def make_paths():
729729
assert fkey not in index.entries
730730

731731
index.add(files, write=True)
732-
if is_win:
733-
hp = hook_path('pre-commit', index.repo.git_dir)
734-
hpd = osp.dirname(hp)
735-
if not osp.isdir(hpd):
736-
os.mkdir(hpd)
737-
with open(hp, "wt") as fp:
738-
fp.write("#!/usr/bin/env sh\necho stdout; echo stderr 1>&2; exit 1")
739-
# end
740-
os.chmod(hp, 0o744)
741-
try:
742-
index.commit("This should fail")
743-
except HookExecutionError as err:
744-
if is_win:
745-
self.assertIsInstance(err.status, OSError)
746-
self.assertEqual(err.command, [hp])
747-
self.assertEqual(err.stdout, '')
748-
self.assertEqual(err.stderr, '')
749-
assert str(err)
750-
else:
751-
self.assertEqual(err.status, 1)
752-
self.assertEqual(err.command, hp)
753-
self.assertEqual(err.stdout, 'stdout\n')
754-
self.assertEqual(err.stderr, 'stderr\n')
755-
assert str(err)
756-
else:
757-
raise AssertionError("Should have cought a HookExecutionError")
758-
# end exception handling
759-
os.remove(hp)
760-
# end hook testing
761732
nc = index.commit("2 files committed", head=False)
762733

763734
for fkey in keys:
@@ -859,3 +830,88 @@ def test_add_a_file_with_wildcard_chars(self, rw_dir):
859830
r = Repo.init(rw_dir)
860831
r.index.add([fp])
861832
r.index.commit('Added [.exe')
833+
834+
@with_rw_repo('HEAD', bare=True)
835+
def test_pre_commit_hook_success(self, rw_repo):
836+
index = rw_repo.index
837+
hp = hook_path('pre-commit', index.repo.git_dir)
838+
hpd = osp.dirname(hp)
839+
if not osp.isdir(hpd):
840+
os.mkdir(hpd)
841+
with open(hp, "wt") as fp:
842+
fp.write("#!/usr/bin/env sh\nexit 0")
843+
os.chmod(hp, 0o744)
844+
index.commit("This should not fail")
845+
846+
@with_rw_repo('HEAD', bare=True)
847+
def test_pre_commit_hook_fail(self, rw_repo):
848+
index = rw_repo.index
849+
hp = hook_path('pre-commit', index.repo.git_dir)
850+
hpd = osp.dirname(hp)
851+
if not osp.isdir(hpd):
852+
os.mkdir(hpd)
853+
with open(hp, "wt") as fp:
854+
fp.write("#!/usr/bin/env sh\necho stdout; echo stderr 1>&2; exit 1")
855+
os.chmod(hp, 0o744)
856+
try:
857+
index.commit("This should fail")
858+
except HookExecutionError as err:
859+
if is_win:
860+
self.assertIsInstance(err.status, OSError)
861+
self.assertEqual(err.command, [hp])
862+
self.assertEqual(err.stdout, '')
863+
self.assertEqual(err.stderr, '')
864+
assert str(err)
865+
else:
866+
self.assertEqual(err.status, 1)
867+
self.assertEqual(err.command, [hp])
868+
self.assertEqual(err.stdout, "\n stdout: 'stdout\n'")
869+
self.assertEqual(err.stderr, "\n stderr: 'stderr\n'")
870+
assert str(err)
871+
else:
872+
raise AssertionError("Should have cought a HookExecutionError")
873+
874+
@with_rw_repo('HEAD', bare=True)
875+
def test_commit_msg_hook_success(self, rw_repo):
876+
index = rw_repo.index
877+
commit_message = u"commit default head by Frèderic Çaufl€"
878+
from_hook_message = u"from commit-msg"
879+
880+
hp = hook_path('commit-msg', index.repo.git_dir)
881+
hpd = osp.dirname(hp)
882+
if not osp.isdir(hpd):
883+
os.mkdir(hpd)
884+
with open(hp, "wt") as fp:
885+
fp.write('#!/usr/bin/env sh\necho -n " {}" >> "1ドル"'.format(from_hook_message))
886+
os.chmod(hp, 0o744)
887+
888+
new_commit = index.commit(commit_message)
889+
self.assertEqual(new_commit.message, u"{} {}".format(commit_message, from_hook_message))
890+
891+
@with_rw_repo('HEAD', bare=True)
892+
def test_commit_msg_hook_fail(self, rw_repo):
893+
index = rw_repo.index
894+
hp = hook_path('commit-msg', index.repo.git_dir)
895+
hpd = osp.dirname(hp)
896+
if not osp.isdir(hpd):
897+
os.mkdir(hpd)
898+
with open(hp, "wt") as fp:
899+
fp.write("#!/usr/bin/env sh\necho stdout; echo stderr 1>&2; exit 1")
900+
os.chmod(hp, 0o744)
901+
try:
902+
index.commit("This should fail")
903+
except HookExecutionError as err:
904+
if is_win:
905+
self.assertIsInstance(err.status, OSError)
906+
self.assertEqual(err.command, [hp])
907+
self.assertEqual(err.stdout, '')
908+
self.assertEqual(err.stderr, '')
909+
assert str(err)
910+
else:
911+
self.assertEqual(err.status, 1)
912+
self.assertEqual(err.command, [hp])
913+
self.assertEqual(err.stdout, "\n stdout: 'stdout\n'")
914+
self.assertEqual(err.stderr, "\n stderr: 'stderr\n'")
915+
assert str(err)
916+
else:
917+
raise AssertionError("Should have cought a HookExecutionError")

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /