docs: function updateDeploy() {
  
      function promisedGit(args, options) {
          const argsArr = ['git'];
          Array.prototype.push.apply(argsArr, args);
          options = options || {};
          options.capture = options.capture === undefined ? true : options.capture;
          options.useErrHandler = options.useErrHandler === undefined ? true : options.useErrHandler;
          return promisedSpawn(argsArr, options);
      }
  
      function chainedPgit(args, options) {
          const arg = args.shift();
          if (!arg) {
              return P.resolve();
          }
          return promisedGit(arg, options)
          .then((data) => {
              if (args.length === 0) {
                  return P.resolve(data);
              }
              return chainedPgit(args, options);
          });
      }
  
      // check if there is an alternative repo name defined
      return P.props({
          name: promisedGit(['config', 'deploy.name'], { ignoreErr: true }),
          remote: promisedGit(['config', 'deploy.remote'], { ignoreErr: true }),
          submodule_ref: promisedGit(['config', 'deploy.submodule'], { ignoreErr: true }),
          deploy_branch: promisedGit(['config', 'deploy.deploybranch'], { ignoreErr: true }),
          src_branch: promisedGit(['config', 'deploy.srcbranch'], { ignoreErr: true })
      }).then((props) => {
          opts.name = props.name || pkg.name;
          opts.remote_name = props.remote || 'origin';
          opts.submodule_ref = props.submodule_ref ||
              `https://gerrit.wikimedia.org/r/mediawiki/services/${opts.name}`;
          opts.src_branch = props.src_branch || 'master';
          opts.deploy_branch = props.deploy_branch || 'master';
          opts.remote_branch = `${opts.remote_name}/${opts.deploy_branch}`;
          // we need to CHDIR into the deploy dir for subsequent operations
          process.chdir(opts.dir);
          return chainedPgit([
              // make sure we are on master
              ['checkout', 'master'],
              // fetch all possible updates
              ['fetch', '--all'],
              // work on a topic branch forked off of the target branch
              ['checkout', '-B', 'sync-repo', opts.remote_branch],
              // check if the submodule is present
              ['submodule', 'status']
         ]);
      }).then((list) => {
          if (list) {
              // the submodule is present
              // in submodule the remote is always called 'origin', so ignore opts.
              opts.submodule = list.split(' ')[1];
              // update it fully
              return promisedGit(['submodule', 'update', '--init'])
              .then(() => {
                  process.chdir(`${opts.dir}/${opts.submodule}`);
                  return chainedPgit([
                      // fetch new commits
                      ['fetch', 'origin'],
                      // inspect what has changed
                      ['diff', '--name-only', `origin/${opts.src_branch}`]
                 ]).then((changes) => {
                      if (/package\.json/.test(changes)) {
                          // package.json has changed, so we need
                          // to rebuild the node_modules directory
                          opts.need_build = true;
                      }
                      // get the SHA1 of the latest commit on the src branch
                      return promisedGit(['rev-parse', '--short', `origin/${opts.src_branch}`]);
                  }).then((shortSha1) => {
                      opts.commit_msg = `Update ${opts.name} to ${shortSha1}\n\n`;
                      // get a nice list of commits included in the change
                      return promisedGit(['log',
                          `..origin/${opts.src_branch}`,
                          '--oneline',
                          '--no-merges',
                          '--reverse',
                          '--color=never']);
                  }).then((logs) => {
                      if (!logs && !opts.need_build) {
                          // no updates have happened, nothing to do here any more but clean up
                          // go back to the root dir
                          process.chdir(opts.dir);
                          // and get back to master
                          return promisedGit(['checkout', 'master'])
                          .then(() => {
                              console.log('The deploy repository is up to date already, exiting.');
                              process.exit(0);
                          });
                      } else if (logs) {
                          logs += '\n';
                      } else if (!logs) {
                          logs = '';
                      }
                      opts.commit_msg += `List of changes:\n${logs}`;
                      return promisedGit(['checkout', `origin/${opts.src_branch}`]);
                  }).then(() => {
                      // go back to the root dir
                      process.chdir(opts.dir);
                      // add the submodule changes
                      return promisedGit(['add', opts.submodule]);
                  });
              });
          } else {
              // no submodule, need to add it
              opts.submodule = 'src';
              opts.need_build = true;
              opts.commit_msg = `Initial import of ${opts.name}`;
              return promisedGit(['submodule',
                  'add',
                  opts.submodule_ref,
                  opts.submodule]);
          }
      }).then(() => // make sure the package.json symlink is in place
          fs.symlinkAsync(`${opts.submodule}/package.json`, 'package.json')
      .catch(() => {}).then(() => promisedGit(['add', 'package.json']))).then(() => {
          if (!opts.need_build) {
              return;
          }
          // update the commit message
          if (!/^initial/i.test(opts.commit_msg)) {
              opts.commit_msg += 'xxxxxxx Update node module dependencies\n';
          }
          // a rebuild is needed, start by removing the existing modules
          return promisedGit(['rm', '-r', 'node_modules'], { ignoreErr: true })
          .then(() => promisedSpawn(['rm', '-rf', 'node_modules'],
              { capture: true, ignoreErr: true }))
          // start the container which builds the modules
          .then(() => startContainer(['-v', `${opts.dir}:/opt/service`, '-w', '/opt/service'], true))
          .then(() => {
              // remove unnecessary files
              let findAttr;
              if (os.type() === 'Darwin') {
                  findAttr = [
                      'find',
                      '-E',
                      'node_modules/',
                      '-iregex',
                      '.*\\.git.*|.*\\.md|.*readme|.*licence',
                      '-exec', 'rm', '-rf', '{}', ';'
                 ];
              } else {
                  findAttr = [
                      'find',
                      'node_modules/',
                      '-regextype',
                      'posix-egrep',
                      '-iregex',
                      '(.*\\.git.*|.*\\.md|.*readme|.*licence)',
                      '-exec', 'rm', '-rf', '{}', ';'
                 ];
              }
              return promisedSpawn(findAttr, { capture: true, ignoreErr: true });
          }).then(() => // add the built submodules
              promisedGit(['add', 'node_modules']));
      }).then(() => // commit the changes
          promisedGit(['commit', '-m', opts.commit_msg]))
          .then(() => {
              if (!opts.review) {
                  console.log('\n\nChanges are sitting in the sync-repo branch in');
                  console.log(`${opts.dir} with the commit:`);
                  console.log(opts.commit_msg);
                  return;
              }
              return chainedPgit([
                  // send them for review
                  ['review', '-R', opts.deploy_branch],
                  // get back to master
                  ['checkout', 'master'],
                  // and reset the submodule pointer
                  ['submodule', 'update', '--init']
             ], { capture: false }).then(() => {
                  console.log('\n\nChanges sent to Gerrit for review!');
              });
          });
  }