From 06efeae598c6dafbe56d2ea323a0dccdd5bf2b8e Mon Sep 17 00:00:00 2001
From: Claude Paroz <claude@2xlibre.net>
Date: Thu, 6 Mar 2014 10:13:22 +0100
Subject: [PATCH] Added --previous flag to msgmerge command used by
 makemessages
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Also took the opportunity to slightly refactor gettext options
so as to ease customization by subclassing the command.
Thanks Michal Čihař for the report and initial patch.
---
 .../core/management/commands/makemessages.py  | 57 ++++++++-----------
 docs/ref/django-admin.txt                     |  5 ++
 docs/releases/1.7.txt                         |  4 ++
 3 files changed, 32 insertions(+), 34 deletions(-)

diff --git a/django/core/management/commands/makemessages.py b/django/core/management/commands/makemessages.py
index 9c81bc8e20..7c2555ba2f 100644
--- a/django/core/management/commands/makemessages.py
+++ b/django/core/management/commands/makemessages.py
@@ -80,14 +80,8 @@ class TranslatableFile(object):
                 '--keyword=ngettext_lazy:1,2',
                 '--keyword=pgettext:1c,2',
                 '--keyword=npgettext:1c,2,3',
-                '--from-code=UTF-8',
-                '--add-comments=Translators',
                 '--output=-'
-            ]
-            if command.wrap:
-                args.append(command.wrap)
-            if command.location:
-                args.append(command.location)
+            ] + command.xgettext_options
             args.append(work_file)
         elif domain == 'django' and (file_ext == '.py' or file_ext in command.extensions):
             thefile = self.file
@@ -115,14 +109,8 @@ class TranslatableFile(object):
                 '--keyword=npgettext:1c,2,3',
                 '--keyword=pgettext_lazy:1c,2',
                 '--keyword=npgettext_lazy:1c,2,3',
-                '--from-code=UTF-8',
-                '--add-comments=Translators',
                 '--output=-'
-            ]
-            if command.wrap:
-                args.append(command.wrap)
-            if command.location:
-                args.append(command.location)
+            ] + command.xgettext_options
             args.append(work_file)
         else:
             return
@@ -206,6 +194,11 @@ class Command(NoArgsCommand):
     requires_system_checks = False
     leave_locale_alone = True
 
+    msgmerge_options = ['-q', '--previous']
+    msguniq_options = ['--to-code=utf-8']
+    msgattrib_options = ['--no-obsolete']
+    xgettext_options = ['--from-code=UTF-8', '--add-comments=Translators']
+
     def handle_noargs(self, *args, **options):
         locale = options.get('locale')
         self.domain = options.get('domain')
@@ -217,8 +210,19 @@ class Command(NoArgsCommand):
         if options.get('use_default_ignore_patterns'):
             ignore_patterns += ['CVS', '.*', '*~', '*.pyc']
         self.ignore_patterns = list(set(ignore_patterns))
-        self.wrap = '--no-wrap' if options.get('no_wrap') else ''
-        self.location = '--no-location' if options.get('no_location') else ''
+
+        # Avoid messing with mutable class variables
+        if options.get('no_wrap'):
+            self.msgmerge_options = self.msgmerge_options[:] + ['--no-wrap']
+            self.msguniq_options = self.msguniq_options[:] + ['--no-wrap']
+            self.msgattrib_options = self.msgattrib_options[:] + ['--no-wrap']
+            self.xgettext_options = self.xgettext_options[:] + ['--no-wrap']
+        if options.get('no_location'):
+            self.msgmerge_options = self.msgmerge_options[:] + ['--no-location']
+            self.msguniq_options = self.msguniq_options[:] + ['--no-location']
+            self.msgattrib_options = self.msgattrib_options[:] + ['--no-location']
+            self.xgettext_options = self.xgettext_options[:] + ['--no-location']
+
         self.no_obsolete = options.get('no_obsolete')
         self.keep_pot = options.get('keep_pot')
 
@@ -307,12 +311,7 @@ class Command(NoArgsCommand):
             potfile = os.path.join(path, '%s.pot' % str(self.domain))
             if not os.path.exists(potfile):
                 continue
-            args = ['msguniq', '--to-code=utf-8']
-            if self.wrap:
-                args.append(self.wrap)
-            if self.location:
-                args.append(self.location)
-            args.append(potfile)
+            args = ['msguniq'] + self.msguniq_options + [potfile]
             msgs, errors, status = popen_wrapper(args)
             if errors:
                 if status != STATUS_OK:
@@ -389,12 +388,7 @@ class Command(NoArgsCommand):
         pofile = os.path.join(basedir, '%s.po' % str(self.domain))
 
         if os.path.exists(pofile):
-            args = ['msgmerge', '-q']
-            if self.wrap:
-                args.append(self.wrap)
-            if self.location:
-                args.append(self.location)
-            args.extend([pofile, potfile])
+            args = ['msgmerge'] + self.msgmerge_options + [pofile, potfile]
             msgs, errors, status = popen_wrapper(args)
             if errors:
                 if status != STATUS_OK:
@@ -413,12 +407,7 @@ class Command(NoArgsCommand):
             fp.write(msgs)
 
         if self.no_obsolete:
-            args = ['msgattrib', '-o', pofile, '--no-obsolete']
-            if self.wrap:
-                args.append(self.wrap)
-            if self.location:
-                args.append(self.location)
-            args.append(pofile)
+            args = ['msgattrib'] + self.msgattrib_options + ['-o', pofile, pofile]
             msgs, errors, status = popen_wrapper(args)
             if errors:
                 if status != STATUS_OK:
diff --git a/docs/ref/django-admin.txt b/docs/ref/django-admin.txt
index 853f64b936..4571c24d3d 100644
--- a/docs/ref/django-admin.txt
+++ b/docs/ref/django-admin.txt
@@ -569,6 +569,11 @@ Example usage::
 
     Added the ability to specify multiple locales.
 
+.. versionchanged:: 1.7
+
+    Added the ``--previous`` option to the ``msgmerge`` command when merging
+    with existing po files.
+
 .. django-admin-option:: --domain
 
 Use the ``--domain`` or ``-d`` option to change the domain of the messages files.
diff --git a/docs/releases/1.7.txt b/docs/releases/1.7.txt
index 6c1ab36c90..359bc4d217 100644
--- a/docs/releases/1.7.txt
+++ b/docs/releases/1.7.txt
@@ -572,6 +572,10 @@ Internationalization
   app or project message file. See :ref:`how-to-create-language-files` for
   details.
 
+* The :djadmin:`makemessages` command now always adds the ``--previous``
+  command line flag to the ``msgmerge`` command, keeping previously translated
+  strings in po files for fuzzy strings.
+
 * The following settings to adjust the language cookie options were introduced:
   :setting:`LANGUAGE_COOKIE_AGE`, :setting:`LANGUAGE_COOKIE_DOMAIN`
   and :setting:`LANGUAGE_COOKIE_PATH`.