Repository: ansible/ansible
Pull request: git: Check if version is populated or not
##### SUMMARY

Before usage check if the git version is populated or not.

Fixes: #72321

Signed-off-by: Abhijeet Kasurde <akasurde@redhat.com>

##### ISSUE TYPE



- Test Pull Request

Problem statement:
ansible-pull git module fails when HOME is not set
##### SUMMARY
ansible-pull git module fails when HOME is not set. It will produce the error shown in `ACTUAL RESULTS` when eg. run as a LaunchDaemon on macOS. But will perform fine when run as a LaunchDaemon when explicitly setting HOME to eg "/var/root"

##### ISSUE TYPE
- Bug Report

##### COMPONENT NAME
ansible/modules/git.py

##### ANSIBLE VERSION
ansible==2.10.1 

##### CONFIGURATION


##### OS / ENVIRONMENT
macOS 10.15.7


##### STEPS TO REPRODUCE
`ansible-pull` will run fine when executed using the command line but will fail as a LaunchDaemon.

##### EXPECTED RESULTS
`ansible-pull` should deliver the same results no matter how it is started.


##### ACTUAL RESULTS
```
"module_stderr": "Traceback (most recent call last):
  File \"/var/root/.ansible/tmp/ansible-tmp-1603351341.240792-3548-191494314212665/AnsiballZ_git.py\", line 102, in <module>
    _ansiballz_main()
  File \"/var/root/.ansible/tmp/ansible-tmp-1603351341.240792-3548-191494314212665/AnsiballZ_git.py\", line 94, in _ansiballz_main
    invoke_module(zipped_mod, temp_path, ANSIBALLZ_PARAMS)
  File \"/var/root/.ansible/tmp/ansible-tmp-1603351341.240792-3548-191494314212665/AnsiballZ_git.py\", line 40, in invoke_module
    runpy.run_module(mod_name='ansible.modules.git', init_globals=None, run_name='__main__', alter_sys=True)
  File \"somepath/Python.framework/Versions/3.8/lib/python3.8/runpy.py\", line 207, in run_module
    return _run_module_code(code, init_globals, run_name, mod_spec)
  File \"somepath/Python.framework/Versions/3.8/lib/python3.8/runpy.py\", line 97, in _run_module_code
    _run_code(code, mod_globals, init_globals,
  File \"somepath/Python.framework/Versions/3.8/lib/python3.8/runpy.py\", line 87, in _run_code
    exec(code, run_globals)
  File \"/tmp/ansible_git_payload_k6elftyg/ansible_git_payload.zip/ansible/modules/git.py\", line 1277, in <module>
  File \"/tmp/ansible_git_payload_k6elftyg/ansible_git_payload.zip/ansible/modules/git.py\", line 1159, in main
  File \"somepath/Python.framework/Versions/3.8/lib/python3.8/distutils/version.py\", line 64, in __gt__
    c = self._cmp(other)
  File \"somepath/Python.framework/Versions/3.8/lib/python3.8/distutils/version.py\", line 335, in _cmp
    if self.version == other.version:
AttributeError: 'NoneType' object has no attribute 'version'
"
```

Hints from issue discussion:
Files identified in the description:
* [`lib/ansible/modules/git.py`](https://github.com/ansible/ansible/blob/devel/lib/ansible/modules/git.py)

If these files are incorrect, please update the `component name` section of the description or use the `!component` bot command.

[click here for bot help](https://github.com/ansible/ansibullbot/blob/master/ISSUE_HELP.md)
<!--- boilerplate: components_banner --->
This indicates that running `git --version` is failing, and `git_version` is returning `None`.  I'm not sure so much why `$HOME` would affect it, but we can probably guard against the traceback with something like:

```diff
diff --git a/lib/ansible/modules/git.py b/lib/ansible/modules/git.py
index b47e94517b..36c3edacf4 100644
--- a/lib/ansible/modules/git.py
+++ b/lib/ansible/modules/git.py
@@ -1156,7 +1156,7 @@ def main():
 
     git_version_used = git_version(git_path, module)
 
-    if depth is not None and git_version_used < LooseVersion('1.9.1'):
+    if depth is not None and git_version_used and git_version_used < LooseVersion('1.9.1'):
         result['warnings'].append("Your git version is too old to fully support the depth argument. Falling back to full checkouts.")
         depth = None
 
```
I can't reproduce it on Arch Linux. `ansible-pull` will run fine when `HOME` is not set (with stable2.10 and devel). Maybe a mac user could take a look.
This happens to me trying to connect to a mac book pro via ssh. OS: Big Sur 11.2.3
Unable to reproduce this on OSX 11.4.  Local git is `2.30.1`.

Commit message: git: Check if version is populated or not

Before usage check if the git version is populated or not.

Fixes: #72321

Signed-off-by: Abhijeet Kasurde <akasurde@redhat.com>

Patch to review:
diff --git a/changelogs/fragments/72321_git.yml b/changelogs/fragments/72321_git.yml
new file mode 100644
index 00000000000000..8ba0ca7558ccfb
--- /dev/null
+++ b/changelogs/fragments/72321_git.yml
@@ -0,0 +1,3 @@
+---
+bugfixes:
+- git - check if git version is available or not before using it for comparison (https://github.com/ansible/ansible/issues/72321).
diff --git a/lib/ansible/modules/git.py b/lib/ansible/modules/git.py
index 26d4c59f924b1f..89df655808c69b 100644
--- a/lib/ansible/modules/git.py
+++ b/lib/ansible/modules/git.py
@@ -669,6 +669,8 @@ def get_diff(module, git_path, dest, repo, remote, depth, bare, before, after):
     elif before != after:
         # Ensure we have the object we are referring to during git diff !
         git_version_used = git_version(git_path, module)
+        if git_version_used is None:
+            module.fail_json(msg='Cannot find git executable at %s' % git_path)
         fetch(git_path, module, repo, dest, after, remote, depth, bare, '', git_version_used)
         cmd = '%s diff %s %s' % (git_path, before, after)
         (rc, out, err) = module.run_command(cmd, cwd=dest)
@@ -1304,6 +1306,8 @@ def main():
 
     # iface changes so need it to make decisions
     git_version_used = git_version(git_path, module)
+    if git_version_used is None:
+        module.fail_json(msg='Cannot find git executable at %s' % git_path)
 
     # GIT_SSH=<path> as an environment variable, might create sh wrapper script for older versions.
     set_git_ssh_env(key_file, ssh_opts, git_version_used, module)


Code review comments:
diff_hunk: @@ -669,6 +669,8 @@ def get_diff(module, git_path, dest, repo, remote, depth, bare, before, after):
     elif before != after:
         # Ensure we have the object we are referring to during git diff !
         git_version_used = git_version(git_path, module)
+        if git_version_used is None:
+            module.fail_json(msg='Cannot find git executable at %s' % git_path)
path: lib/ansible/modules/git.py
text: @user1:
```suggestion

```
Otherwise lgtm