Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Git module fails to change the current branch if there's no corresponding remote-tracking branch #82007

Open
1 task done
toadjaune opened this issue Oct 18, 2023 · 7 comments
Labels
affects_2.15 bug This issue/PR relates to a bug. module This issue/PR relates to a module.

Comments

@toadjaune
Copy link
Contributor

toadjaune commented Oct 18, 2023

Summary

When cloning a git repo while specifying single_branch: true, a subsequent attempt to change the branch fails.

My understanding of the issue is that when attempting to change the branch of an already existing repo, ansible implicitly assumes that the corresponding remote-tracking branch already exists, which may very well not be true in various situations.

Issue Type

Bug Report

Component Name

git

Ansible Version

ansible [core 2.15.5]
  config file = /etc/ansible/ansible.cfg
[...]
  python version = 3.10.13 (main, Aug 28 2023, 00:00:00) [GCC 13.2.1 20230728 (Red Hat 13.2.1-1)] ([...])
  jinja version = 3.0.3
  libyaml = True

Configuration

CONFIG_FILE() = /etc/ansible/ansible.cfg
EDITOR(env: EDITOR) = vim
PAGER(env: PAGER) = most

OS / Environment

Fedora 38 Workstation
ansible installed via pip in a virtualenv

Steps to Reproduce

- hosts: localhost
  tasks:
    - name: Remove git repo if required
      file:
        path: /tmp/test_clone_repo
        state: absent

    - name: Clone the git repo with only a single branch
      ansible.builtin.git:
        repo: https://github.com/ansible/ansible-examples.git
        version: master
        dest: /tmp/test_clone_repo
        single_branch: true

    - name: Attempt to change the branch
      ansible.builtin.git:
        repo: https://github.com/ansible/ansible-examples.git
        version: provisioning
        dest: /tmp/test_clone_repo

Expected Results

No error, and the repo would now be checked-out on the provisioning branch.

Actual Results

fatal: [localhost]: FAILED! => {
    "changed": false,
    "cmd": "/usr/bin/git checkout --track -b provisioning origin/provisioning",
    "invocation": {
        "module_args": {
            "accept_hostkey": false,
            "accept_newhostkey": false,
            "archive": null,
            "archive_prefix": null,
            "bare": false,
            "clone": true,
            "depth": null,
            "dest": "/tmp/test_clone_repo",
            "executable": null,
            "force": false,
            "gpg_whitelist": [],
            "key_file": null,
            "recursive": true,
            "reference": null,
            "refspec": null,
            "remote": "origin",
            "repo": "https://github.com/ansible/ansible-examples.git",
            "separate_git_dir": null,
            "single_branch": false,
            "ssh_opts": null,
            "track_submodules": false,
            "umask": null,
            "update": true,
            "verify_commit": false,
            "version": "provisioning"
        }
    },
    "msg": "Failed to checkout provisioning",
    "rc": 128,
    "stderr": "fatal: 'origin/provisioning' is not a commit and a branch 'provisioning' cannot be created from it\n",
    "stderr_lines": [
        "fatal: 'origin/provisioning' is not a commit and a branch 'provisioning' cannot be created from it"
    ],
    "stdout": "",
    "stdout_lines": []
}

Code of Conduct

  • I agree to follow the Ansible Code of Conduct
@toadjaune toadjaune changed the title Git module with single_branch: false fails to change the current branch Git module fails to change the current branch if there's no corresponding remote-tracking branch Oct 18, 2023
@ansibot ansibot added bug This issue/PR relates to a bug. needs_triage Needs a first human triage before being processed. affects_2.15 module This issue/PR relates to a module. labels Oct 18, 2023
@ansibot
Copy link
Contributor

ansibot commented Oct 18, 2023

Files identified in the description:

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

@mattclay
Copy link
Member

@toadjaune Can you clarify what you're trying to do? The issue summary mentions using single_branch: false, but the reproducer you provided uses single_branch: true instead.

@mattclay mattclay removed the needs_triage Needs a first human triage before being processed. label Oct 19, 2023
@toadjaune
Copy link
Contributor Author

Hi @mattclay,

Sorry about that, the reproducer is correct, but the description was typoed. I've corrected it.

Does this make the issue clear, or do you want me to add some extra clarifications ?

@s-hertel
Copy link
Contributor

The module performs a fetch before checking out the remote branch, but since it was cloned as a single-branch repo, it won't fetch other refs implicitly (see config with git config --get remote.origin.fetch). Setting remote: origin and refspec: provisioning allows fetching the new branch, but would be retrieved as FETCH_HEAD (so git checkout --track ... would still not work as it needs a branch).

You could make this work with the module by setting depth to a positive value on the second task, which will reconfigure the remote and fetch again (code here). The comment suggests depth implies single_branch: true, so maybe single_branch: true on the second task should also call this codepath? I think this behavior with depth is a little unintuitive though, I would fix this by reconfiguring what to fetch:

- name: Reconfigure fetch for the git remote
  command: git config remote.origin.fetch "+refs/heads/*:refs/remotes/origin/*"
  args:
    chdir: /tmp/test_clone_repo

@toadjaune
Copy link
Contributor Author

toadjaune commented Oct 23, 2023

That sounds like a nice workaround (better than always leaving single_branch: false anyway), I'll give it a try when I get a chance to refactor this bit of configuration. :)

It still feels like the module should handle it gracefully and not require any manual operation, though.

@jianghoy
Copy link

I just encountered similar behaviour, should I raise another issue? Or just comment in here to see if they actually overlap?

Code:

- hosts: localhost
  tasks:
    - name: Remove git repo if required
      file:
        path: /tmp/test_clone_repo
        state: absent

    - name: Clone the git repo with only a single branch
      ansible.builtin.git:
        repo: https://github.com/ansible/ansible-examples.git
        version: master
        dest: /tmp/test_clone_repo
        single_branch: true

    - name: Attempt to change the branch
      ansible.builtin.git:
        repo: https://github.com/ansible/ansible-examples.git
        version: feature-1
        dest: /tmp/test_clone_repo
        single_branch: true

Which will give this error:

FAILED! => {"changed": false, "cmd": "/usr/bin/git checkout --track -b feature-1 origin/feature-1 , "msg": "Failed to checkout feature-1 ", "rc": 128, "stderr": "fatal: 'origin/feature-1 ' is not a commit and a branch 'feature-1 ' cannot be created from it\n", "stderr_lines": ["fatal: 'origin/feature-1'  is not a commit and a branch 'feature-1 ' cannot be created from it"], "stdout": "", "stdout_lines": []}

@MohammedNoureldin
Copy link

I also have the same issue. I am trying to checkout a specific tag from a local branch. This local branch has a remote, but it is not up-to-date and only the local branch should be checked for tags. However, because the remote does not have the latest tags, the checked out version is not changed and I end up with the wrong state.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
affects_2.15 bug This issue/PR relates to a bug. module This issue/PR relates to a module.
Projects
None yet
Development

No branches or pull requests

6 participants