Repository: ansible-collections/community.general

Issue:
git_config fails when using "scope=file"
### Summary

`git_config` does not work when using `scope=file`.  This is due to `git_config.py` treating `--file` the same as `--local`, `--global` and `--system`:

```
    if scope:
        args.append("--" + scope)
    if name:
        args.append(name)

    if scope == 'file':
        args.append('-f')
        args.append(params['file'])
```

This should be rewritten as something like (untested):

```
    if scope == 'file':
        args.append('-f')
        args.append(params['file'])
    elif scope:
        args.append("--" + scope)

    if name:
        args.append(name)
```

(Adding an integration test would probably be helpful as well.)

### Issue Type

Bug Report

### Component Name

git_config

### Ansible Version

```
ansible 2.9.18
  config file = /etc/ansible/ansible.cfg
  configured module search path = ['/home/tim/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/lib/python3.8/site-packages/ansible
  executable location = /usr/bin/ansible
  python version = 3.8.7 (default, Jan 20 2021, 00:00:00) [GCC 10.2.1 20201125 (Red Hat 10.2.1-9)]
```

### Configuration

_No response_

### OS / Environment

Fedora 32

### Steps to Reproduce

```
ANSIBLE_COLLECTIONS_PATHS=ansible/collections ansible -m community.general.git_config -a 'file=/tmp/temp-git-config name=test-key value=test-value scope=file' localhost
```

### Expected Results

`/tmp/temp-git-config` should be created and contain:

```
[test-section]
   test-key = test-value
```

### Actual Results

```
[tim@passepartout /tmp/etc.9ND]$ ANSIBLE_COLLECTIONS_PATHS=ansible/collections ansible -m community.general.git_config -a 'file=/tmp/temp-git-config name=test-section.test-key value=test-value scope=file' localhost
localhost | FAILED! => {
    "changed": false,
    "cmd": "/usr/bin/git config --includes --file test-section.test-key -f /tmp/temp-git-config",
    "msg": "usage: git config [<options>]\n\nConfig file location\n    --global              use global config file\n    --system              use system config file\n    --local               use repository config file\n    --worktree            use per-worktree config file\n    -f, --file <file>     use given config file\n    --blob <blob-id>      read config from given blob object\n\nAction\n    --get                 get value: name [value-regex]\n    --get-all             get all values: key [value-regex]\n    --get-regexp          get values for regexp: name-regex [value-regex]\n    --get-urlmatch        get value specific for the URL: section[.var] URL\n    --replace-all         replace all matching variables: name value [value_regex]\n    --add                 add a new variable: name value\n    --unset               remove a variable: name [value-regex]\n    --unset-all           remove all matches: name [value-regex]\n    --rename-section      rename section: old-name new-name\n    --remove-section      remove a section: name\n    -l, --list            list all\n    -e, --edit            open an editor\n    --get-color           find the color configured: slot [default]\n    --get-colorbool       find the color setting: slot [stdout-is-tty]\n\nType\n    -t, --type <>         value is given this type\n    --bool                value is \"true\" or \"false\"\n    --int                 value is decimal number\n    --bool-or-int         value is --bool or --int\n    --path                value is a path (file or directory name)\n    --expiry-date         value is an expiry date\n\nOther\n    -z, --null            terminate values with NUL byte\n    --name-only           show variable names only\n    --includes            respect include directives on lookup\n    --show-origin         show origin of config (file, standard input, blob, command line)\n    --show-scope          show scope of config (worktree, local, global, system, command)\n    --default <value>     with --get, use default value when missing entry\n\n",
    "rc": 129
}
[tim@passepartout /tmp/etc.9ND]$
```

### Code of Conduct

- [X] I agree to follow the Ansible Code of Conduct


Discussion:
Files identified in the description:
* [`plugins/modules/source_control/git_config.py`](https://github.com/ansible-collections/community.general/blob/master/plugins/modules/source_control/git_config.py)

If these files are inaccurate, 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 --->
cc @djmattyg007 @mgedmin
[click here for bot help](https://github.com/ansible/ansibullbot/blob/master/ISSUE_HELP.md)
<!--- boilerplate: notify --->

Resolving patch:
diff --git a/plugins/modules/source_control/git_config.py b/plugins/modules/source_control/git_config.py
--- a/plugins/modules/source_control/git_config.py
+++ b/plugins/modules/source_control/git_config.py
@@ -216,14 +216,13 @@ def main():
     args = [git_path, "config", "--includes"]
     if params['list_all']:
         args.append('-l')
-    if scope:
-        args.append("--" + scope)
-    if name:
-        args.append(name)
-
     if scope == 'file':
         args.append('-f')
         args.append(params['file'])
+    elif scope:
+        args.append("--" + scope)
+    if name:
+        args.append(name)
 
     if scope == 'local':
         dir = params['repo']


Test patch:
diff --git a/tests/integration/targets/git_config/aliases b/tests/integration/targets/git_config/aliases
--- a/tests/integration/targets/git_config/aliases
+++ b/tests/integration/targets/git_config/aliases
@@ -1,2 +1,3 @@
 shippable/posix/group3
 skip/aix
+destructive
diff --git a/tests/integration/targets/git_config/tasks/get_set_state_present_file.yml b/tests/integration/targets/git_config/tasks/get_set_state_present_file.yml
new file mode 100644
--- /dev/null
+++ b/tests/integration/targets/git_config/tasks/get_set_state_present_file.yml
@@ -0,0 +1,29 @@
+---
+- import_tasks: setup_no_value.yml
+
+- name: setting value with state=present
+  git_config:
+    name: "{{ option_name }}"
+    value: "{{ option_value }}"
+    scope: "file"
+    file: "{{ output_dir }}/gitconfig_file"
+    state: present
+  register: result
+
+- name: getting value with state=present
+  git_config:
+    name: "{{ option_name }}"
+    scope: "file"
+    file: "{{ output_dir }}/gitconfig_file"
+    state: present
+  register: get_result
+
+- name: assert set changed and value is correct with state=present
+  assert:
+    that:
+      - set_result is changed
+      - set_result.diff.before == "\n"
+      - set_result.diff.after == option_value + "\n"
+      - get_result is not changed
+      - get_result.config_value == option_value
+...
diff --git a/tests/integration/targets/git_config/tasks/main.yml b/tests/integration/targets/git_config/tasks/main.yml
--- a/tests/integration/targets/git_config/tasks/main.yml
+++ b/tests/integration/targets/git_config/tasks/main.yml
@@ -16,6 +16,8 @@
     - import_tasks: get_set_no_state.yml
     # testing get/set option with state=present
     - import_tasks: get_set_state_present.yml
+    # testing get/set option with state=present and scope=file
+    - import_tasks: get_set_state_present_file.yml
     # testing state=absent without value to delete
     - import_tasks: unset_no_value.yml
     # testing state=absent with value to delete
diff --git a/tests/integration/targets/git_config/tasks/setup_no_value.yml b/tests/integration/targets/git_config/tasks/setup_no_value.yml
--- a/tests/integration/targets/git_config/tasks/setup_no_value.yml
+++ b/tests/integration/targets/git_config/tasks/setup_no_value.yml
@@ -5,4 +5,9 @@
   file:
     path: ~/.gitconfig
     state: absent
-...
\ No newline at end of file
+
+- name: set up without value (file)
+  file:
+    path: "{{ output_dir }}/gitconfig_file"
+    state: absent
+...
diff --git a/tests/integration/targets/git_config/tasks/setup_value.yml b/tests/integration/targets/git_config/tasks/setup_value.yml
--- a/tests/integration/targets/git_config/tasks/setup_value.yml
+++ b/tests/integration/targets/git_config/tasks/setup_value.yml
@@ -5,4 +5,9 @@
   copy:
     src: gitconfig
     dest: ~/.gitconfig
-...
\ No newline at end of file
+
+- name: set up with value (file)
+  copy:
+    src: gitconfig
+    dest: "{{ output_dir }}/gitconfig_file"
+...