NOTE: After writing this article several months ago, I gradually realized that despite this solution works, it is error-prone, and too verbose. I'll write a new article explaing how I deal with it now.
When I started wirting my blog, one thing that confused me is different versions of
settings.py. As we know, different
settings.py should be kept for developement and deployment, however when it comes to using Git, things get messy. The main difficulties lies on two things:
- Should I upload
settings.pyfrom developement environment to Git server? If I did, does that mean I have to change the file every time after doing
Git pullon deployment server?
- If I choose not to upload
settings.py, there is a risk of losing data.
My purpose is to keep different versions of
settings.py. Here's what I did:
- First, on the computer I do developing,
pusheverything as you normally do, including
- Create a new branch called
- Then, on deployment server,
git pullfrom branch
settings.pyfor deployment, e.g. set
STATIC_ROOT, etc. The ONLY file you should change is
settings.py, DO NOT TOUCH OTHER FILES !
- Back to developing environment, type this command:
bash git update-index --assume-unchanged my_blog/settings.pyDone :)
The key part is step 5. First you should understand what
git update-index --assume-unchanged is doing, basically it assumes that the file does not change. From git-scm:
When these flags are specified, the object names recorded for the paths are not updated. Instead, these options set and unset the "assume unchanged" bit for the paths. When the "assume unchanged" bit is on, Git stops checking the working tree files for possible modifications, so you need to manually unset the bit to tell Git when you change the working tree file. This is sometimes helpful when working with a big project on a filesystem that has very slow lstat(2) system call (e.g. cifs).
This option can be also used as a coarse file-level mechanism to ignore uncommitted changes in tracked files (akin to what .gitignore does for untracked files). Git will fail (gracefully) in case it needs to modify this file in the index e.g. when merging in a commit; thus, in case the assumed-untracked file is changed upstream, you will need to handle the situation manually.
So next time you
commit your work, though
settings.py may has been changed, those changes won't get uploaded to Git server, which means there is no confict when you
pull from master branch on deployment server no matter how many times your
settings.py has been edited there. You could also achieve this by adding
Finally, workflow is like this:
Coding, Push to
master —> On deployment server, pull from
settings.py on deployment server (if needed) —> Push to
Be careful, NEVER push to branch
master from deployment server.
Now you've pushed some new commits to Github and want to apply it on your server. Here are the steps:
# step 1 make sure you're on master branch, if not, git checkout master # step 2 $ git pull # step 3 $ git checkout deploy # step 4 $ git rebase master # step 5 $ git push origin deploy
I'm open to changes and suggestions, if you have better ideas, feel free to comment.comments powered by Disqus