Re: [PATCH 3 of 3 v2] hooks: fix potentially invalid interpreter in git hooks (Issue #333)

2019-04-07 Thread Mads Kiilerich

On 4/7/19 9:23 AM, Thomas De Schampheleire wrote:



Can we somehow make it show a more useful error message in
this case? I
guess not - none of our code is executed ...


Actually, there is some of our code executed: SimpleGit. But, at
that point you don't know that the git hook call is going to fail.



First: Since we install Git hooks in the file system, they will
also be invoked if someone push directly. That may or may not be a
feature, but we have to handle it.


I don't think this is a valid argument: for mercurial repos the hooks 
are not installed on the file system. Direct pushing is not supported.



I would say that direct pushing for Mercurial repos is supported, in the 
sense that Kallithea doesn't modify repos at all and doesn't prevent it. 
After direct pushes, you might want to run repo-update-metadata to let 
Kallithea know about it.


With Git hooks installed into the repos, I think we kind of have a 
responsibility to make sure they work in all cases, without error 
messages. If not, users might get the impression that Kallithea 
"destroyed" their repositories. I don't know if I would prefer that the 
hook did nothing if not invoked from Kallithea, or if it would be fine 
if it did logging etc, even though we don't have that with Mercurial.


We could perhaps just decide that it is no big deal and ignore that aspect.



We kind of *have* to run something inside the hook. That is the
only way to know exactly what is pushed (or pulled). If we want
branch access control, it will(!?) also have to run inside hooks.


Knowing what was pushed and what not is a more convincing argument. 
But how do we know this in mercurial? Does mercurial tell us, or do we 
find out? Is it impossible/fragile to do the same in git?



Yes, the Mercurial hook tells us when the log_push_action hook is invoked.

Git does the same, but it is a bit more work, both because the data 
model and hooks are different, and because it is a separate process. 
Thus we have the git hook which calls into handle_git_post_receive .


(I think it will be more readable in the future as
https://kallithea-scm.org/repos/kallithea-incoming/files/d9c3498964118a7fe6e484572d8c88f85118398f/kallithea/lib/hooks.py#L102
https://kallithea-scm.org/repos/kallithea-incoming/files/d9c3498964118a7fe6e484572d8c88f85118398f/kallithea/lib/hooks.py#L344 
)




Summarizing: I don't think that is feasible. But if it is, it will
not be simple. Not suitable for the stable branch.


Ok. But when deciding what to do on the stable branch, I think it 
makes sense to have an idea what we'll do for default. I think we 
should avoid introducing user visible changes like ini settings if 
they will not apply on default.



Agreed. But I don't think it is feasible to stop using hooks, so in 
either case, we have to make sure they work. This fix is thus important 
and sound: We have to make sure the Git hooks use the right interpreter.


/Mads

___
kallithea-general mailing list
kallithea-general@sfconservancy.org
https://lists.sfconservancy.org/mailman/listinfo/kallithea-general


Re: [PATCH 3 of 3 v2] hooks: fix potentially invalid interpreter in git hooks (Issue #333)

2019-04-07 Thread Thomas De Schampheleire
On Sun, Apr 7, 2019, 00:25 Mads Kiilerich  wrote:

> On 4/6/19 9:22 PM, Thomas De Schampheleire wrote:
>
>
>
> El jue., 4 abr. 2019 a las 0:41, Mads Kiilerich ()
> escribió:
>
>> > And pushing to such repo would result in following client errors:
>> >
>> >  $ git push
>> >  Password for 'http://user@localhost:5050':
>> >  Enumerating objects: 3, done.
>> >  Counting objects: 100% (3/3), done.
>> >  Writing objects: 100% (3/3), 241 bytes | 241.00 KiB/s, done.
>> >  Total 3 (delta 0), reused 0 (delta 0)
>> >  remote: unable to load configuration from hooks/pre-receive
>> >  To http://localhost:5050/gitrepo-new
>> >   ! [remote rejected] master -> master (pre-receive hook declined)
>> >  error: failed to push some refs to '
>> http://user@localhost:5050/gitrepo-new'
>>
>>
>> Can we somehow make it show a more useful error message in this case? I
>> guess not - none of our code is executed ...
>>
>
> Actually, there is some of our code executed: SimpleGit. But, at that
> point you don't know that the git hook call is going to fail.
>
>
> First: Since we install Git hooks in the file system, they will also be
> invoked if someone push directly. That may or may not be a feature, but we
> have to handle it.
>

I don't think this is a valid argument: for mercurial repos the hooks are
not installed on the file system. Direct pushing is not supported.


But yes, usually, SimpleGit will invoke the `git` command which then invoke
> the hooks.
>
> Also, I have significant refactorings in this area lined up, preparing for
> clean hook handling, also for ssh. Our first goal on the stable branch
> should be to fix regressions - perhaps by recommending workarounds.
>
>
>
>
>>
>> > The approach taken by this commit is:
>>
>>
>> FWIW, this:
>>
>> > - Introduce a new configuration setting: hook_python_path, and use its
>> value
>> >as the Python interpreter to use in git hooks.
>> > - If the value is absent or empty, fall back to the current logic
>> >'sys.executable' or if that is also invalid, 'python2'.
>>
>>
>> and this:
>>
>>
>> > - Let `kallithea-cli config-create` fill in its own interpreter as
>> default
>> >value, which should be valid as long as the virtual environment is
>> not
>> >moved/replaced.
>>
>>
>> *could* be separate "milestones" and separate changesets. But no big
>> deal. Split or keep together as you like.
>>
>
>
> Yes, I considered it, but got a bit stuck with the comments referring to
> code that does not yet exist.
> I'll think about it a second time.
>
>
> Yes, the first changeset will need comments about the potential, and the
> second changeset might update these comments. But the the phrasing and
> change of the comments might help to be aware what actually is changed and
> why ... and how it ideally should be done.
>
>
>
>
>> > The main downside of this approach is its fragility in case a new
>> virtualenv
>> > is used. Previously, the configuration file was the same regardless of
>> > virtualenv, but this is no longer true after this patch.
>>
>>
>> But also, it is crucial that the *right* virtualenv is used, also if Git
>> should be invoked directly, outside any virtual env. It is thus inherent
>> that the new virtualenv *has* to be written to the hooks somehow. The
>> previous use of same 'python2' was wrong and fragile. I thus don't think
>> the new way is more fragile. Explicit expectations and failing early is
>> *less* fragile ;-)
>>
>
> In fact, my understanding was not fully complete before: when users push
> to a git repo, they actually communicate with our Git middleware, which
> itself uses dulwich. All this should normally happen inside the virtualenv
> (if used). Only when the hooks get called, there is a decoupling into
> another process. (I am theorizing here, not explicitly checked)
>
> So if that is correct, then I wonder if we could not avoid the decoupling.
> We are already handling pull hooks in
> kallithea.lib.middleware.simplegit._handle_githooks .
> Can we not handle push hooks pre-receive/post-receive in the same place?
> In this case, we are definitely in the right environment, we are and stay
> within Python. I guess it will also simplify the situation for Windows.
>
> Am I overlooking something?
>
>
> We kind of *have* to run something inside the hook. That is the only way
> to know exactly what is pushed (or pulled). If we want branch access
> control, it will(!?) also have to run inside hooks.
>

Knowing what was pushed and what not is a more convincing argument. But how
do we know this in mercurial? Does mercurial tell us, or do we find out? Is
it impossible/fragile to do the same in git?

We can perhaps revisit after landing my cleanups and see if we can find a
> fundamentally new way to do it.
>
>
>
> Thanks for these comments, I generally agree.
>
> But before going further, I'd like to hear your opinion on the idea of
> calling the hooks directly from our own code (see above).
>
>
> Summarizing: I don't th

Re: [PATCH 3 of 3 v2] hooks: fix potentially invalid interpreter in git hooks (Issue #333)

2019-04-06 Thread Mads Kiilerich

On 4/6/19 9:22 PM, Thomas De Schampheleire wrote:



El jue., 4 abr. 2019 a las 0:41, Mads Kiilerich (>) escribió:


> And pushing to such repo would result in following client errors:
>
>      $ git push
>      Password for 'http://user@localhost:5050':
>      Enumerating objects: 3, done.
>      Counting objects: 100% (3/3), done.
>      Writing objects: 100% (3/3), 241 bytes | 241.00 KiB/s, done.
>      Total 3 (delta 0), reused 0 (delta 0)
>      remote: unable to load configuration from hooks/pre-receive
>      To http://localhost:5050/gitrepo-new
>       ! [remote rejected] master -> master (pre-receive hook
declined)
>      error: failed to push some refs to
'http://user@localhost:5050/gitrepo-new'


Can we somehow make it show a more useful error message in this
case? I
guess not - none of our code is executed ...


Actually, there is some of our code executed: SimpleGit. But, at that 
point you don't know that the git hook call is going to fail.



First: Since we install Git hooks in the file system, they will also be 
invoked if someone push directly. That may or may not be a feature, but 
we have to handle it.


But yes, usually, SimpleGit will invoke the `git` command which then 
invoke the hooks.


Also, I have significant refactorings in this area lined up, preparing 
for clean hook handling, also for ssh. Our first goal on the stable 
branch should be to fix regressions - perhaps by recommending workarounds.





> The approach taken by this commit is:


FWIW, this:

> - Introduce a new configuration setting: hook_python_path, and
use its value
>    as the Python interpreter to use in git hooks.
> - If the value is absent or empty, fall back to the current logic
>    'sys.executable' or if that is also invalid, 'python2'.


and this:


> - Let `kallithea-cli config-create` fill in its own interpreter
as default
>    value, which should be valid as long as the virtual
environment is not
>    moved/replaced.


*could* be separate "milestones" and separate changesets. But no big
deal. Split or keep together as you like.



Yes, I considered it, but got a bit stuck with the comments referring 
to code that does not yet exist.

I'll think about it a second time.



Yes, the first changeset will need comments about the potential, and the 
second changeset might update these comments. But the the phrasing and 
change of the comments might help to be aware what actually is changed 
and why ... and how it ideally should be done.




> The main downside of this approach is its fragility in case a
new virtualenv
> is used. Previously, the configuration file was the same
regardless of
> virtualenv, but this is no longer true after this patch.


But also, it is crucial that the *right* virtualenv is used, also
if Git
should be invoked directly, outside any virtual env. It is thus
inherent
that the new virtualenv *has* to be written to the hooks somehow. The
previous use of same 'python2' was wrong and fragile. I thus don't
think
the new way is more fragile. Explicit expectations and failing
early is
*less* fragile ;-)


In fact, my understanding was not fully complete before: when users 
push to a git repo, they actually communicate with our Git middleware, 
which itself uses dulwich. All this should normally happen inside the 
virtualenv (if used). Only when the hooks get called, there is a 
decoupling into another process. (I am theorizing here, not explicitly 
checked)

So if that is correct, then I wonder if we could not avoid the decoupling.
We are already handling pull hooks in 
kallithea.lib.middleware.simplegit._handle_githooks .
Can we not handle push hooks pre-receive/post-receive in the same 
place? In this case, we are definitely in the right environment, we 
are and stay within Python. I guess it will also simplify the 
situation for Windows.


Am I overlooking something?



We kind of *have* to run something inside the hook. That is the only way 
to know exactly what is pushed (or pulled). If we want branch access 
control, it will(!?) also have to run inside hooks.


We can perhaps revisit after landing my cleanups and see if we can find 
a fundamentally new way to do it.





Thanks for these comments, I generally agree.

But before going further, I'd like to hear your opinion on the idea of 
calling the hooks directly from our own code (see above).



Summarizing: I don't think that is feasible. But if it is, it will not 
be simple. Not suitable for the stable branch.



/Mads

___
kallithea-general mailing list
kallithea-general@sfconservancy.org
https://lists.sfconservancy.org/mailman/listinfo/kallithea-general


Re: [PATCH 3 of 3 v2] hooks: fix potentially invalid interpreter in git hooks (Issue #333)

2019-04-06 Thread Thomas De Schampheleire
El jue., 4 abr. 2019 a las 0:41, Mads Kiilerich ()
escribió:

> On 4/3/19 10:28 PM, Thomas De Schampheleire wrote:
> > # HG changeset patch
> > # User Thomas De Schampheleire 
> > # Date 1554323208 -7200
> > #  Wed Apr 03 22:26:48 2019 +0200
> > # Branch stable
> > # Node ID 0d91f710606b72027456a1183794ee38f26fe741
> > # Parent  06b511848fb1a3ead56de583e19df5f317bdf7e0
> > hooks: fix potentially invalid interpreter in git hooks (Issue #333)
>
>
> Thanks for iterating on this.
>
>
> > Commit 5e501b6ee639 introduced the use of 'sys.executable' as interpreter
> > for git hooks instead of 'python2' with the following argument:
> >
> >  "Windows doesn't necessarily have "python2" available in $PATH, but
> we
> >  still want to make sure we don't end up invoking a python3. Using
> the
> >  absolute path seems more safe."
> >
> > But, sys.executable does not necessarily point to Python. When Kallithea
> is
> > started under uWSGI, sys.executable points to the uwsgi executable. As a
> > result, the interpreter encoded in the git hooks on the server
> repositories
> > would be:
> >
> >  #!/usr/bin/env /path/to/uwsgi
> >
> > And pushing to such repo would result in following client errors:
> >
> >  $ git push
> >  Password for 'http://user@localhost:5050':
> >  Enumerating objects: 3, done.
> >  Counting objects: 100% (3/3), done.
> >  Writing objects: 100% (3/3), 241 bytes | 241.00 KiB/s, done.
> >  Total 3 (delta 0), reused 0 (delta 0)
> >  remote: unable to load configuration from hooks/pre-receive
> >  To http://localhost:5050/gitrepo-new
> >   ! [remote rejected] master -> master (pre-receive hook declined)
> >  error: failed to push some refs to 'http://user@localhost
> :5050/gitrepo-new'
>
>
> Can we somehow make it show a more useful error message in this case? I
> guess not - none of our code is executed ...
>

Actually, there is some of our code executed: SimpleGit. But, at that point
you don't know that the git hook call is going to fail.


>
>
> > The approach taken by this commit is:
>
>
> FWIW, this:
>
> > - Introduce a new configuration setting: hook_python_path, and use its
> value
> >as the Python interpreter to use in git hooks.
> > - If the value is absent or empty, fall back to the current logic
> >'sys.executable' or if that is also invalid, 'python2'.
>
>
> and this:
>
>
> > - Let `kallithea-cli config-create` fill in its own interpreter as
> default
> >value, which should be valid as long as the virtual environment is not
> >moved/replaced.
>
>
> *could* be separate "milestones" and separate changesets. But no big
> deal. Split or keep together as you like.
>


Yes, I considered it, but got a bit stuck with the comments referring to
code that does not yet exist.
I'll think about it a second time.


>
>
> > The main downside of this approach is its fragility in case a new
> virtualenv
> > is used. Previously, the configuration file was the same regardless of
> > virtualenv, but this is no longer true after this patch.
>
>
> But also, it is crucial that the *right* virtualenv is used, also if Git
> should be invoked directly, outside any virtual env. It is thus inherent
> that the new virtualenv *has* to be written to the hooks somehow. The
> previous use of same 'python2' was wrong and fragile. I thus don't think
> the new way is more fragile. Explicit expectations and failing early is
> *less* fragile ;-)
>

In fact, my understanding was not fully complete before: when users push to
a git repo, they actually communicate with our Git middleware, which itself
uses dulwich. All this should normally happen inside the virtualenv (if
used). Only when the hooks get called, there is a decoupling into another
process. (I am theorizing here, not explicitly checked)

So if that is correct, then I wonder if we could not avoid the decoupling.
We are already handling pull hooks in
kallithea.lib.middleware.simplegit._handle_githooks .
Can we not handle push hooks pre-receive/post-receive in the same place? In
this case, we are definitely in the right environment, we are and stay
within Python. I guess it will also simplify the situation for Windows.

Am I overlooking something?


>
> > diff --git a/development.ini b/development.ini
> > --- a/development.ini
> > +++ b/development.ini
> > @@ -117,6 +117,16 @@ use_htsts = false
> >   ## number of commits stats will parse on each iteration
> >   commit_parse_limit = 25
> >
> > +## Path to Python executable to be used in git hooks.
> > +## When empty, the value of 'sys.executable' at the time of installation
> > +## of the git hooks is used, which is correct in many cases but not when
> > +## using uwsgi.
> > +## When creating a config file via `kallithea-cli config-create`, the
> > +## Python executable used for that invocation is filled in below.
> > +## If you change this setting, you should reinstall the git hooks via
> > +## Admin > Settings > Remap and Rescan.
> > +hook_python_path 

Re: [PATCH 3 of 3 v2] hooks: fix potentially invalid interpreter in git hooks (Issue #333)

2019-04-03 Thread Mads Kiilerich

On 4/3/19 10:28 PM, Thomas De Schampheleire wrote:

# HG changeset patch
# User Thomas De Schampheleire 
# Date 1554323208 -7200
#  Wed Apr 03 22:26:48 2019 +0200
# Branch stable
# Node ID 0d91f710606b72027456a1183794ee38f26fe741
# Parent  06b511848fb1a3ead56de583e19df5f317bdf7e0
hooks: fix potentially invalid interpreter in git hooks (Issue #333)



Thanks for iterating on this.



Commit 5e501b6ee639 introduced the use of 'sys.executable' as interpreter
for git hooks instead of 'python2' with the following argument:

 "Windows doesn't necessarily have "python2" available in $PATH, but we
 still want to make sure we don't end up invoking a python3. Using the
 absolute path seems more safe."

But, sys.executable does not necessarily point to Python. When Kallithea is
started under uWSGI, sys.executable points to the uwsgi executable. As a
result, the interpreter encoded in the git hooks on the server repositories
would be:

 #!/usr/bin/env /path/to/uwsgi

And pushing to such repo would result in following client errors:

 $ git push
 Password for 'http://user@localhost:5050':
 Enumerating objects: 3, done.
 Counting objects: 100% (3/3), done.
 Writing objects: 100% (3/3), 241 bytes | 241.00 KiB/s, done.
 Total 3 (delta 0), reused 0 (delta 0)
 remote: unable to load configuration from hooks/pre-receive
 To http://localhost:5050/gitrepo-new
  ! [remote rejected] master -> master (pre-receive hook declined)
 error: failed to push some refs to 'http://user@localhost:5050/gitrepo-new'



Can we somehow make it show a more useful error message in this case? I 
guess not - none of our code is executed ...




The approach taken by this commit is:



FWIW, this:


- Introduce a new configuration setting: hook_python_path, and use its value
   as the Python interpreter to use in git hooks.
- If the value is absent or empty, fall back to the current logic
   'sys.executable' or if that is also invalid, 'python2'.



and this:



- Let `kallithea-cli config-create` fill in its own interpreter as default
   value, which should be valid as long as the virtual environment is not
   moved/replaced.



*could* be separate "milestones" and separate changesets. But no big 
deal. Split or keep together as you like.




The main downside of this approach is its fragility in case a new virtualenv
is used. Previously, the configuration file was the same regardless of
virtualenv, but this is no longer true after this patch.



But also, it is crucial that the *right* virtualenv is used, also if Git 
should be invoked directly, outside any virtual env. It is thus inherent 
that the new virtualenv *has* to be written to the hooks somehow. The 
previous use of same 'python2' was wrong and fragile. I thus don't think 
the new way is more fragile. Explicit expectations and failing early is 
*less* fragile ;-)




diff --git a/development.ini b/development.ini
--- a/development.ini
+++ b/development.ini
@@ -117,6 +117,16 @@ use_htsts = false
  ## number of commits stats will parse on each iteration
  commit_parse_limit = 25
  
+## Path to Python executable to be used in git hooks.

+## When empty, the value of 'sys.executable' at the time of installation
+## of the git hooks is used, which is correct in many cases but not when
+## using uwsgi.
+## When creating a config file via `kallithea-cli config-create`, the
+## Python executable used for that invocation is filled in below.
+## If you change this setting, you should reinstall the git hooks via
+## Admin > Settings > Remap and Rescan.
+hook_python_path =
+
  ## path to git executable
  git_path = git
  
diff --git a/kallithea/lib/inifile.py b/kallithea/lib/inifile.py

--- a/kallithea/lib/inifile.py
+++ b/kallithea/lib/inifile.py
@@ -23,6 +23,7 @@ other custom values.
  import logging
  import re
  import os
+import sys
  
  import mako.template
  
@@ -40,6 +41,7 @@ default_variables = {

  'host': '127.0.0.1',
  'port': '5000',
  'uuid': lambda: 'VERY-SECRET',
+'python_executable': sys.executable or '',
  }
  
  
diff --git a/kallithea/lib/paster_commands/template.ini.mako b/kallithea/lib/paster_commands/template.ini.mako

--- a/kallithea/lib/paster_commands/template.ini.mako
+++ b/kallithea/lib/paster_commands/template.ini.mako
@@ -211,6 +211,16 @@ use_htsts = false
  <%text>## number of commits stats will parse on each iteration
  commit_parse_limit = 25
  
+<%text>## Path to Python executable to be used in git hooks.

+<%text>## When empty, the value of 'sys.executable' at the time of 
installation
+<%text>## of the git hooks is used, which is correct in many cases but not 
when
+<%text>## using uwsgi.



Perhaps clarify that "used" means "written into the git hook script files".



+<%text>## When creating a config file via `kallithea-cli config-create`, 
the
+<%text>## Python executable used for that invocation is filled in 
below.
+<%text>## If you change this setting, you should reinstall the git h

[PATCH 3 of 3 v2] hooks: fix potentially invalid interpreter in git hooks (Issue #333)

2019-04-03 Thread Thomas De Schampheleire
# HG changeset patch
# User Thomas De Schampheleire 
# Date 1554323208 -7200
#  Wed Apr 03 22:26:48 2019 +0200
# Branch stable
# Node ID 0d91f710606b72027456a1183794ee38f26fe741
# Parent  06b511848fb1a3ead56de583e19df5f317bdf7e0
hooks: fix potentially invalid interpreter in git hooks (Issue #333)

Commit 5e501b6ee639 introduced the use of 'sys.executable' as interpreter
for git hooks instead of 'python2' with the following argument:

"Windows doesn't necessarily have "python2" available in $PATH, but we
still want to make sure we don't end up invoking a python3. Using the
absolute path seems more safe."

But, sys.executable does not necessarily point to Python. When Kallithea is
started under uWSGI, sys.executable points to the uwsgi executable. As a
result, the interpreter encoded in the git hooks on the server repositories
would be:

#!/usr/bin/env /path/to/uwsgi

And pushing to such repo would result in following client errors:

$ git push
Password for 'http://user@localhost:5050':
Enumerating objects: 3, done.
Counting objects: 100% (3/3), done.
Writing objects: 100% (3/3), 241 bytes | 241.00 KiB/s, done.
Total 3 (delta 0), reused 0 (delta 0)
remote: unable to load configuration from hooks/pre-receive
To http://localhost:5050/gitrepo-new
 ! [remote rejected] master -> master (pre-receive hook declined)
error: failed to push some refs to 'http://user@localhost:5050/gitrepo-new'


The approach taken by this commit is:

- Introduce a new configuration setting: hook_python_path, and use its value
  as the Python interpreter to use in git hooks.
- If the value is absent or empty, fall back to the current logic
  'sys.executable' or if that is also invalid, 'python2'.
- Let `kallithea-cli config-create` fill in its own interpreter as default
  value, which should be valid as long as the virtual environment is not
  moved/replaced.
- To avoid private paths being encoded in development.ini, pass an empty
  default value.

The main downside of this approach is its fragility in case a new virtualenv
is used. Previously, the configuration file was the same regardless of
virtualenv, but this is no longer true after this patch.

Suggested-by: Mads Kiilerich 

diff --git a/development.ini b/development.ini
--- a/development.ini
+++ b/development.ini
@@ -117,6 +117,16 @@ use_htsts = false
 ## number of commits stats will parse on each iteration
 commit_parse_limit = 25
 
+## Path to Python executable to be used in git hooks.
+## When empty, the value of 'sys.executable' at the time of installation
+## of the git hooks is used, which is correct in many cases but not when
+## using uwsgi.
+## When creating a config file via `kallithea-cli config-create`, the
+## Python executable used for that invocation is filled in below.
+## If you change this setting, you should reinstall the git hooks via
+## Admin > Settings > Remap and Rescan.
+hook_python_path =
+
 ## path to git executable
 git_path = git
 
diff --git a/kallithea/lib/inifile.py b/kallithea/lib/inifile.py
--- a/kallithea/lib/inifile.py
+++ b/kallithea/lib/inifile.py
@@ -23,6 +23,7 @@ other custom values.
 import logging
 import re
 import os
+import sys
 
 import mako.template
 
@@ -40,6 +41,7 @@ default_variables = {
 'host': '127.0.0.1',
 'port': '5000',
 'uuid': lambda: 'VERY-SECRET',
+'python_executable': sys.executable or '',
 }
 
 
diff --git a/kallithea/lib/paster_commands/template.ini.mako 
b/kallithea/lib/paster_commands/template.ini.mako
--- a/kallithea/lib/paster_commands/template.ini.mako
+++ b/kallithea/lib/paster_commands/template.ini.mako
@@ -211,6 +211,16 @@ use_htsts = false
 <%text>## number of commits stats will parse on each iteration
 commit_parse_limit = 25
 
+<%text>## Path to Python executable to be used in git hooks.
+<%text>## When empty, the value of 'sys.executable' at the time of 
installation
+<%text>## of the git hooks is used, which is correct in many cases but not 
when
+<%text>## using uwsgi.
+<%text>## When creating a config file via `kallithea-cli config-create`, 
the
+<%text>## Python executable used for that invocation is filled in 
below.
+<%text>## If you change this setting, you should reinstall the git hooks 
via
+<%text>## Admin > Settings > Remap and Rescan.
+hook_python_path = ${python_executable}
+
 <%text>## path to git executable
 git_path = git
 
diff --git a/kallithea/model/scm.py b/kallithea/model/scm.py
--- a/kallithea/model/scm.py
+++ b/kallithea/model/scm.py
@@ -721,8 +721,11 @@ class ScmModel(object):
 return choices, hist_l
 
 def _get_python_executable(self):
-"""Return a Python executable for use in hooks."""
-return sys.executable or 'python2'
+"""Return a Python executable for use in hooks.
+
+This is not simply sys.executable because under uwsgi it will be the
+uwsgi program itself."""
+return kallithea.CONFIG.get('hook_python_path', sys.executable) or 
'python2'