I'm trying to retrieve a single file from by bitbucket branch instead of getting the entire branch using the git module. It's taking more than 2 minutes to get the entire branch and I really just need that one file.
4 Answers
You can try git archive
to get a file from remote git repository
git archive --remote=git://git.example.com/project.git HEAD:path/in/repo filename | tar -x
You can refer to the answer by Vonc for detailed information - For more info

- 2,211
- 3
- 21
- 33
You can use sparse checkout option
git config core.sparseCheckout true
git remote add -f origin git:<<providde url>
echo "path/to/folder/*" > .git/info/sparse-checkout
git checkout <branchname>

- 2,308
- 2
- 17
- 41
Ansible's module git
can do git archive
but the problem is it does it from a local clone. If there is no local clone it clones first which is what you want to avoid so you cannot use module git
.
Hence you have to use command
or shell
:
- name: Get a file using git archive
command: git archive --remote=https://bitbucket.com/user/project.git HEAD:path/in/repo filename -o /path/to/archive.zip

- 82,685
- 13
- 120
- 165
-
To my knowledge, Bitbucket does not support the archive command, as it uses https and not git. – user228505 Feb 15 '21 at 21:59
Ansible doesn't seem to support a sparse checkout. To do a sparse checkout with ansible, you can use the following code that i found here
---
- hosts: all
vars:
repo_url: ssh://git@github.com/user/repo.git
base_dir: /var/www
sparse_checkout:
- path/to/archive.zip
tasks:
- name: prepare sparse git repository
shell: |
git init
git config core.sparsecheckout true
git remote add origin {{ repo_url }}
args:
chdir: "{{ base_dir }}"
creates: "{{ base_dir }}/.git"
- name: configure sparse-checkout
copy:
dest: "{{ base_dir }}/.git/info/sparse-checkout"
content: '{{ sparse_checkout | join("\n") }}'
- name: clone code
shell: git pull origin master
args:
chdir: "{{ base_dir }}"
creates: "{{ base_dir }}/{{ sparse_checkout | first }}"
You can adapt the folder to a single file as ive done above
If you want to just put all the code on your tasks file, you can use set_fact: "above" the previous code. example below
- name: set needed facts for ansible sparse checkout
vars:
git_user: '<git-token-name>'
git_ansible_token: '<your-token>'
ansible_repo_user: '<username>' #(this should probably already be configured in your main vars file, e.g. all.yml, or some group_vars, but if not, you can add it here)
set_fact:
# using gitlab as an example
repo_url: 'https://{{ git_user }}:{{ git_ansible_token }}@gitlab.com/project/repo.git'
base_dir: "~{{ ansible_repo_user }}/<your/path/to/desired/repo/folder>"
# folders we want to reduce the repo to
sparse_checkout:
- path/to/archive.zip
Some additional code you may or may not need, is to create the base repo dir, because this checkout expects that it exists. so you would put this above the top git task that prepares the sparse checkout to create it first
- name: make parent repo dir for sparse checkout
become: yes
vars:
ansible_become_user: '{{ ansible_repo_user }}'
file:
path: "{{ ansible_base_dir }}"
state: directory
mode: '0750'
So to pull all that together, including adding become to all the tasks, the entire thing could look like this on your tasks file;
- name: set needed facts for ansible sparse checkout
vars:
git_user: '<git-token-name>'
git_ansible_token: '<your-token>'
ansible_repo_user: '<username>' #(this should probably already be configured in your main vars file, e.g. all.yml, or some group_vars, but if not, you can add it here)
set_fact:
repo_url: 'https://{{ git_user }}:{{ git_ansible_token }}@gitlab.com/project/repo.git'
base_dir: "~{{ ansible_repo_user }}/<your/path/to/desired/repo/folder>"
# folders we want to reduce the repo to
sparse_checkout:
- path/to/archive.zip
- name: make parent repo dir for sparse checkout
become: yes
vars:
ansible_become_user: '{{ ansible_repo_user }}'
file:
path: "{{ ansible_base_dir }}"
state: directory
mode: '0750'
- name: prepare sparse git repository
become: yes
vars:
ansible_become_user: '{{ ansible_repo_user }}'
shell: |
git init
git config core.sparsecheckout true
git remote add origin {{ repo_url }}
args:
chdir: "{{ base_dir }}"
creates: "{{ base_dir }}/.git"
- name: configure sparse-checkout
become: yes
vars:
ansible_become_user: '{{ ansible_repo_user }}'
copy:
dest: "{{ base_dir }}/.git/info/sparse-checkout"
content: '{{ sparse_checkout | join("\n") }}'
- name: clone code
become: yes
vars:
ansible_become_user: '{{ ansible_repo_user }}'
shell: git pull origin master
args:
chdir: "{{ base_dir }}"
creates: "{{ base_dir }}/{{ sparse_checkout | first }}"
There was one other piece of additional functionality you could look into if its still not fast enough for you. I saw a way you can retreive a shorter history when you do your clone, so that you only bring in the last n
commits. If i get time ill add that here.
Note, for the git project token, if your using gitlab, you create a project access token, for me i needed at least Role developer
, and access RO for repo. If your using git, or another vcs
, you will need to adapt accordingly.
Enjoy..

- 4,220
- 4
- 32
- 50