# Git module: don't pull when the clone is already up-to-date.

**URL:** <https://forum.ansible.com/t/git-module-dont-pull-when-the-clone-is-already-up-to-date/15421>\
**Category:** Ansible Project\
**Created:** [June 6, 2014, 8:27pm UTC](https://forum.ansible.com/t/git-module-dont-pull-when-the-clone-is-already-up-to-date/15421 "2014-06-06T20:27:00Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![parnigot](https://avatars.discourse-cdn.com/v4/letter/p/e480ec/32.png) [@parnigot](https://forum.ansible.com/u/parnigot)\
**Post date:** [June 6, 2014, 8:27pm UTC](https://forum.ansible.com/t/git-module-dont-pull-when-the-clone-is-already-up-to-date/15421/1 "2014-06-06T20:27:00Z")

</div>

Hi all,

I’m using ansible to manage a couple of django apps. In particular I’m using the git module to get a clone of these apps in the production machines.  
If you don’t know django, the configuration of the entire web application is saved in a file (named settings.py) that is usually committed along all the code.

For a lot of reasons i keep two different settings.py files:

1. The one committed in the git repo is the one containing the settings using during development.
2. For the production machine I have a different settings.py, not committed and manage separately (it contains all the passwords for databases, API keys for other service and other stuff that don’t belong in the main repo).

So, i run a playbook like this:

- name: Clone the repository  
git: repo=…  
dest=/path/to/clone  
version=master  
force=yes  
notify:

- django manage collectstatic

- django manage south migrate

- restart uWSGI

- name: Upload production settings.py (this will overwrite the dev one from the repo)  
template: src=settings.py.j2  
dest=/path/to/clone/settings.py  
owner=root  
group=root  
mode=0644

That works fine but it does have a problem.  
If I run the playbook a second time the git task will always pull the repository overwriting the production settings.py uploaded the first time, even when the clone is already up-to-date.  
Here’s the verbose output for the task:

TASK: [box | Clone the repository] \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*  
changed: [vagrant\_home\_server] =\> {“after”: “0d7a146a6eadd279218c1305d400d6058d17f26f”, “before”: “0d7a146a6eadd279218c1305d400d6058d17f26f”, “changed”: true, “item”: “/path/to/clone”, “msg”: “Local modifications exist”}

You can see that the target repo is already up-to-date but the task has pulled the code overwriting the productions settings.py. This will also trigger the tasks under the notify, in particular the _restart uWSGI_ one that shouldn’t be executed every time.

So my question is: it is possible to keep the force=yes behavior, but pulling only when really needed?

Best regards,  
EP

---

<div class="post-metadata">

**Author:** ![Dick\_Davies](https://avatars.discourse-cdn.com/v4/letter/d/b9e5f3/32.png) [@Dick\_Davies](https://forum.ansible.com/u/Dick_Davies)\
**Post date:** [June 7, 2014, 6:39pm UTC](https://forum.ansible.com/t/git-module-dont-pull-when-the-clone-is-already-up-to-date/15421/2 "2014-06-07T18:39:33Z")

</div>

Try using something other than 'master' as a version,

version=0d7a146a6eadd279218c1305d400d6058d17f26f

for example.

---

<div class="post-metadata">

**Author:** ![parnigot](https://avatars.discourse-cdn.com/v4/letter/p/e480ec/32.png) [@parnigot](https://forum.ansible.com/u/parnigot)\
**Post date:** [June 7, 2014, 7:45pm UTC](https://forum.ansible.com/t/git-module-dont-pull-when-the-clone-is-already-up-to-date/15421/3 "2014-06-07T19:45:54Z")

</div>

Thanks for the reply.

I’ve tried using the commit hash as argument for version, but it doesn’t work: it has the same effect of version=master.

---

<div class="post-metadata">

**Author:** ![Michael\_DeHaan1](https://avatars.discourse-cdn.com/v4/letter/m/5e9695/32.png) [@Michael\_DeHaan1](https://forum.ansible.com/u/Michael_DeHaan1)\
**Post date:** [June 9, 2014, 2:46pm UTC](https://forum.ansible.com/t/git-module-dont-pull-when-the-clone-is-already-up-to-date/15421/4 "2014-06-09T14:46:41Z")

</div>

“I’ve tried using the commit hash as argument for version, but it doesn’t work: it has the same effect of version=master.”

By same effect you mean it does the pull every time, rather than it checks out master, I’d assume? 🙂

I’d like to see the “-v” output in that case.

(Also note, in regard to the suggestion of using the SHA, I don’t really care for that approach as it’s hard to remember SHAs, you could also use a tag rather than the SHA)

–Michael

---

<div class="post-metadata">

**Author:** ![Greg\_Hurrell](https://avatars.discourse-cdn.com/v4/letter/g/76d3ee/32.png) [@Greg\_Hurrell](https://forum.ansible.com/u/Greg_Hurrell)\
**Post date:** [June 9, 2014, 2:56pm UTC](https://forum.ansible.com/t/git-module-dont-pull-when-the-clone-is-already-up-to-date/15421/5 "2014-06-09T14:56:09Z")

</div>

You could rename your development settings.py to settings.py.sample, continue to keep it under version control, and add settings.py itself to your .gitignore. This is what Rails does with things like database.yml, which may contain passwords.

---

<div class="post-metadata">

**Author:** ![parnigot](https://avatars.discourse-cdn.com/v4/letter/p/e480ec/32.png) [@parnigot](https://forum.ansible.com/u/parnigot)\
**Post date:** [June 10, 2014, 8:00pm UTC](https://forum.ansible.com/t/git-module-dont-pull-when-the-clone-is-already-up-to-date/15421/6 "2014-06-10T20:00:45Z")

</div>

> “I’ve tried using the commit hash as argument for version, but it doesn’t work: it has the same effect of version=master.”
> 
> By same effect you mean it does the pull every time, rather than it checks out master, I’d assume? 🙂
> 
> I’d like to see the “-v” output in that case.
> 
> (Also note, in regard to the suggestion of using the SHA, I don’t really care for that approach as it’s hard to remember SHAs, you could also use a tag rather than the SHA)
> 
> –Michael

The verbose output using the commit hash as version is the same one that I get with version=master: the one returned by [this](https://github.com/ansible/ansible/blob/devel/library/source_control/git#L565).

And, looking at the source, this is what I think happens (starting from [here](https://github.com/ansible/ansible/blob/devel/library/source_control/git#L554)):

1. local\_mods is True (there’s the settings.py file with the production settings).
2. I have forced=True and I am not doing a dry run, so the reset --HARD is executed reverting the settings.py to the one in the repo (the devel one).
3. before == remote\_head evaluates to true and the module exits with the message linked above.

My problem is the 2. The reset is always executed, even when before == remote\_head.

> You could rename your development settings.py to settings.py.sample, continue to keep it under version control, and add settings.py itself to your .gitignore. This is what Rails does with things like database.yml, which may contain passwords.

Nice idea. I could use a _settings.py_ with generic and development settings kept under git, and a separate _production\_settings.py_, excluded by _.gitignore_, with the production settings.  
To make everything work I just need to add something like:

try:  
import production\_settings  
except ImportError:  
pass

at the end of the _settings.py_ file.

Thanks

Best regards,  
EP
