tags:

views:

251

answers:

5

I have to develop two Django projects which share 90% of the same code, but have some variations in several applications, templates and within the model itself.

I'm using Git for distributed source-control.

My requirements are that :

  • common code for both projects is developed in one place (Project1's development environment)

  • periodically this is merged into the development environment of the second project (Project2)

  • the variations are not easily encapsulated within apps. (eg. there are apps. such as "profiles" which vary between Project1 and Project2 but for which there's also an ongoing common evolution)

  • both Project1 and Project2 have public repositories, so that I can collaborate with others

  • similarly Project1 and Project2 ought to have development, demo, staging and production servers.

  • however, the public repository is not on the same server in both cases. So, for example, when I'm developing in Project1, I want to be able to "push" to my github server, but not have Project2 stuff going there.

  • there are files such as local_settings.py which are completely different between Project1 and Project2, but should be shared between multiple developers of each Project

So what's the best way of managing this situation?

What would seem to be ideal would be something like a "filtered pull" where instead of .gitignore saying "ignore this file entirely", I can say "ignore this file when pulling from that repo" I couldn't see anything quite like that in the documentation, but might there be something like that?

A: 

I would make a third repo where I would place the code that Projects share. Then Project1 and Project2 would have their own repo and they can pull from that "shared" third repo.

I think that your idea of "filtered pull" will make it difficult to mantein.

Macarse
interstar
+3  A: 

Move the common code to its own library and make it a dependency of those two projects. This is not a question of version control, but a question of code reuse, design and eliminating duplication.

Esko Luontola
Hi Esko. This is not really a library. It's a Django / Pinax site. The variants are necessarily scattered around inside several different applications. It's not easy to encapsulate either what's common or what varies, within a single place.
interstar
Please give more detailed examples of what are the things that vary. I'm not familiar with Django applications.
Esko Luontola
For example, we might have a user "profiles" app., where the profile template lives in "/templates/profiles/profile.html". We need to maintain minor differences between this file in our two projects. But we don't want to add profile.html to .gitignore because then changes won't be shared between the different developers working within this project.
interstar
What differences would a profile.html template contain? What ways does Django provide for abstracting those differences away into a different file?
Esko Luontola
The point is that template differences may depend on the whim of each project. Today, the designers, clients etc. might prefer that Project1 template is broken into three tabbed areas, whereas Project2 shows them as a single scrolling page. In a month's time, Project2 might have adopted tabs, but using a different js widget library. What varies can vary enormously. What's constant is not what the template includes, but what includes it. (And passes information into it.)
interstar
+1  A: 

I would try submodules: http://www.kernel.org/pub/software/scm/git/docs/user-manual.html#submodules

kolbusa
+2  A: 

Considering it is a Django / Pinax site, with variants scattered around inside several different applications, I would not recommend using submodules.

The variants should be managed independently in project1 branch and project2 branch, removing the need to "filter" a gitignore result.

If you identify some really common codes, they may end up in a third repo you could then "subtree merged" to project1 and project2 repositories (the meaning of subtree merge strategy being illustrated in this SO answer)

VonC
+1  A: 

You can use two different git branches for development. When you make changes in one that are common to the other, just git-cherrypick them over. You can push and pull specific branches, too, so that no one ever need know you're working on both of them at the same time.

Xiong Chiamiov