Repository: gitpython-developers/GitPython
Pull request #469 (2016-06-13 14:38:54)

FIx issue #464 corrupt log file
Must only append the first line of the commit to the log
Otherwise the log file is not parsable by GitPython.


Patch:
diff --git a/git/cmd.py b/git/cmd.py
index d8469565..00a73e33 100644
--- a/git/cmd.py
+++ b/git/cmd.py
@@ -43,6 +43,9 @@ from git.compat import (
     safe_decode,
 )
 
+# value of Windows process creation flag taken from MSDN
+CREATE_NO_WINDOW = 0x08000000
+
 execute_kwargs = ('istream', 'with_keep_cwd', 'with_extended_output',
                   'with_exceptions', 'as_process', 'stdout_as_string',
                   'output_stream', 'with_stdout', 'kill_after_timeout',
@@ -609,6 +612,11 @@ class Git(LazyMixin):
         # end handle
 
         try:
+            if sys.platform == 'win32':
+                creationflags = CREATE_NO_WINDOW
+            else:
+                creationflags = 0
+
             proc = Popen(command,
                          env=env,
                          cwd=cwd,
@@ -619,6 +627,7 @@ class Git(LazyMixin):
                          shell=self.USE_SHELL,
                          close_fds=(os.name == 'posix'),  # unsupported on windows
                          universal_newlines=universal_newlines,
+                         creationflags=creationflags,
                          **subprocess_kwargs
                          )
         except cmd_not_found_exception as err:
@@ -629,7 +638,12 @@ class Git(LazyMixin):
 
         def _kill_process(pid):
             """ Callback method to kill a process. """
-            p = Popen(['ps', '--ppid', str(pid)], stdout=PIPE)
+            if sys.platform == 'win32':
+                creationflags = CREATE_NO_WINDOW
+            else:
+                creationflags = 0
+
+            p = Popen(['ps', '--ppid', str(pid)], stdout=PIPE, creationflags=creationflags)
             child_pids = []
             for line in p.stdout:
                 if len(line.split()) > 0:
diff --git a/git/refs/log.py b/git/refs/log.py
index fed13608..3078355d 100644
--- a/git/refs/log.py
+++ b/git/refs/log.py
@@ -114,7 +114,7 @@ class RefLogEntry(tuple):
         newhexsha = info[41:81]
         for hexsha in (oldhexsha, newhexsha):
             if not cls._re_hexsha_only.match(hexsha):
-                raise ValueError("Invalid hexsha: %s" % hexsha)
+                raise ValueError("Invalid hexsha: %r" % (hexsha,))
             # END if hexsha re doesn't match
         # END for each hexsha
 
@@ -274,11 +274,12 @@ class RefLog(list, Serializable):
             raise ValueError("Shas need to be given in binary format")
         # END handle sha type
         assure_directory_exists(filepath, is_file=True)
+        first_line = message.split('\n')[0]
         committer = isinstance(config_reader, Actor) and config_reader or Actor.committer(config_reader)
         entry = RefLogEntry((
             bin_to_hex(oldbinsha).decode('ascii'),
             bin_to_hex(newbinsha).decode('ascii'),
-            committer, (int(time.time()), time.altzone), message
+            committer, (int(time.time()), time.altzone), first_line
         ))
 
         lf = LockFile(filepath)


Test patch:
diff --git a/git/test/test_repo.py b/git/test/test_repo.py
index 87887bad..48900c26 100644
--- a/git/test/test_repo.py
+++ b/git/test/test_repo.py
@@ -775,12 +775,23 @@ class TestRepo(TestBase):
         new_file_path = os.path.join(rw_dir, "new_file.ext")
         touch(new_file_path)
         r.index.add([new_file_path])
-        r.index.commit("initial commit")
+        r.index.commit("initial commit\nBAD MESSAGE 1\n")
 
         # Now a branch should be creatable
         nb = r.create_head('foo')
         assert nb.is_valid()
 
+        with open(new_file_path, 'w') as f:
+            f.write('Line 1\n')
+
+        r.index.add([new_file_path])
+        r.index.commit("add line 1\nBAD MESSAGE 2\n")
+
+        with open('%s/.git/logs/refs/heads/master' % (rw_dir,), 'r') as f:
+            contents = f.read()
+
+        assert 'BAD MESSAGE' not in contents, 'log is corrupt'
+
     def test_merge_base(self):
         repo = self.rorepo
         c1 = 'f6aa8d1'