I am working on a Django based project that is version controlled with SVN. My main objective is porting it from Python2.7 to Python3.9. Whilst I port the project, my team brought some updates, now I want to get these updates and port them to Python3.9 as well.

Our issue here is, how will we manage 2.7 and 3.9 codes in version control. How will I get the changes in 2.7 codes and port them to 3.9? Should I simply merge them and try to solve the huge amount of merge conflicts?

We will drop the 2.7 support as soon as 3.9 version is fully usable. But currently we need to develop the project in 2.7 and port it to 3.9. Can you give any recommendations on how to proceed during this time?

Hope I clearly explained my concern. Thanks for your time and attention in advance.

3 Answers 3


Doing a Big Rewrite is usually a mistake. Trying to maintain two separate codebases takes a lot of effort, as you have discovered.

With a Python 2 → 3 migration, the typical approach is to gradually rewrite the codebase so that it can run under both Python versions. For example, uses of the print statement would be changed to the print function. Python 2.7 has back-ported various features from Python 3.x to help with this migration, but some have to be enabled on a module-by-module bases by importing from __future__. A big problem is the str vs bytes vs unicode problem, but here the helper types from the six package (6=2*3) can help.

Then, a migration would go through the following steps:

  • Modules are ported one by one to run under both Python 2 and 3, starting with leaf modules that have no other dependencies.
  • Tests are set up so that the automated tests for the ported code run under both versions.
  • Eventually, the entire software can run under both Python versions.
  • After thorough testing, the production version is changed to Python 3.
  • Once the migration has completed, Python 2 compatibility can be dropped. Automated tests using Python 2 can be removed.
  • The code base can then be overhauled again to make use of newer language features that are not 2.7 compatible.

Depending on where you are now in the migration process, one of the following strategies is going to be easier:

  • Start the migration anew. Your changes on the current branch would have served as an experiment (or a “spike” in XP terminology) and you can now apply that experience towards a speedy migration on the main branch. This avoids splitting the team, and all keep working on the same codebase.

  • Have a change control process so that all modifications that are applied to the old 2.7 version also get applied to the new Python 3 version. How to do this depends on your processes. It could involve going through the version history of the old branch and manually applying all changes to your work in progress. In case some files haven't yet been touched by your migration, it might be possible to copy the modifications for those files over directly. This is roughly what Doc Brown suggested in their answer, with the question being who is responsible for porting the modifications to the new version.

    • You as the person working on the migration could port the modifications. But I think that unless you're close to completion and unless the rate of changes to be ported is fairly low, that trying to duplicate all changes is going to take a lot of effort and will significantly delay the migration.
    • The people working on the features could implement them on both versions which probably scales better, but this work might also interfere with the migration. It could also be politically risky because this makes the cost of doing a migration by maintaining two parallel codebases more visible.
  • If the new version is effectively done, then freezing development on the old version could be helpful, or at least only doing the most urgent fixes but no new development on the old version. This is generally equivalent to the previous suggestion, but tries to reduce its workload. Such a development freeze is not typically possible though for political reasons, and more practically it also comes at a risk of significantly stalling development.


I guess the most effective solution is not a technical one, but an organizational solution (which is mostly independent from the version control system you are using): make it mandatory for everyone in the team that, once a certain module was ported to 3.9, whenever they make a change to the 2.7 code base which affects the same module, they need to apply the corresponding change to the 3.9 code base in parallel immediately (and test it there, too!). So you need a change your definition of done. As a bonus, you make sure all team members learn about the differences between Python 2 and 3.

Assumed your team is trained to use "small" commits, there will be no "huge amount of merge conflicts", only ones which are at most equally large as the latest change to the 2.7 module.

If certain modules were initially ported by an automatic tool like the 2to3, you may try to run that tool again after a V2.7 module was changed, and try to merge the result into the V3.9 codebase. If that does not work, this might be a sign there were too many manual tweaks into the V3.9 module during the first port - which means one has to resolve those manually, there is no way around it.

The key here is to enforce a strict policy to keep the corresponding 2.7 and 3.9 modules "as equal as possible" during the whole porting phase. Refrain from the temptation to use new, nifty 3.9 features which have no direct equivalent in 2.7 during the coding phase - you can do this later, when you are done with the porting.


how will we manage 2.7 and 3.9 codes in version control

In (at least 2) additional branches, semi-dependent (all features, added to 2.7 branch, must appear in 3.9 branch later, but not in inverse direction)

But in order to prevent chaos and wreck I'll recommend (if it not done yet) follow "Branch per task" flow and use 2.7 and 3.9 as pure aggregation point in which finished (and tested) feature-branches are merged

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.