From 89ade7bfff534ae799d7dd693b206931d5ed3d4f Mon Sep 17 00:00:00 2001 From: Guyzmo Date: Thu, 12 May 2016 16:35:51 +0200 Subject: [PATCH] Fix order of operators before executing the git command Since Python 3.3, the hash value of an object is seeded randomly, making it change between each call. As a consequence, the `dict` type relying on the hash value for the order of the items upon iterating on it, and the parameters passed to `git` being passed as `kwargs` to the `execute()` method, the order of parameters will change randomly between calls. For example, when you call `git.remote.pull()` in a code, two consecutives run will generate: 1. git pull --progress -v origin master 2. git pull -v --progress origin master Within the `transform_kwargs()` method, I'm promoting `kwargs` into an `collections.OrderedDict` being built with `kwargs` sorted on the keys. Then it will ensure that each subsequent calls will execute the parameters in the same order. --- git/cmd.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/git/cmd.py b/git/cmd.py index e4e3d6da4..539482df8 100644 --- a/git/cmd.py +++ b/git/cmd.py @@ -13,6 +13,8 @@ import errno import mmap +from collections import OrderedDict + from contextlib import contextmanager import signal from subprocess import ( @@ -783,6 +785,7 @@ def transform_kwarg(self, name, value, split_single_char_options): def transform_kwargs(self, split_single_char_options=True, **kwargs): """Transforms Python style kwargs into git command line options.""" args = list() + kwargs = OrderedDict(sorted(kwargs.items(), key=lambda x: x[0])) for k, v in kwargs.items(): if isinstance(v, (list, tuple)): for value in v: