diff --git a/external_updater.py b/external_updater.py
index bc464ac3439b3e025b67eab9c6746ef87cf76e24..65a89644ff8ccd083739043d120a4c8dcd02c8ad 100644
--- a/external_updater.py
+++ b/external_updater.py
@@ -164,7 +164,12 @@ def update(args):
         _do_update(args)
     except subprocess.CalledProcessError as err:
         msg = _message_for_calledprocesserror(err)
-        print('{}\n{}'.format(msg, color_string('Failed to upgrade.', 'ERROR')))
+        print(
+            '{}\n{}'.format(
+                msg,
+                color_string(
+                    'Failed to upgrade.',
+                    'ERROR')))
 
 
 TMP_BRANCH_NAME = 'tmp_auto_upgrade'
@@ -192,11 +197,15 @@ def _do_update(args):
     if args.branch_and_commit:
         msg = 'Upgrade {} to {}\n\nTest: None'.format(
             args.path, updater.get_latest_version())
+        git_utils.add_file(full_path, '*')
         git_utils.commit(full_path, msg)
 
     if args.push_change:
         git_utils.push(full_path, args.remote_name)
 
+    if args.branch_and_commit:
+        git_utils.checkout(full_path, 'aosp/master')
+
 
 def parse_args():
     """Parses commandline arguments."""
diff --git a/notifier.py b/notifier.py
index d33dc651f02cfeb43ca971d7b4acc688ae01e746..982354cf8b896604bd2f81855f7b39a75e006e14 100644
--- a/notifier.py
+++ b/notifier.py
@@ -15,14 +15,16 @@
 
 Example usage:
 external_updater_notifier \
-    --result_file ~/updater/new_result \
     --history ~/updater/history \
-    --recipients xxx@xxx.xxx
+    --generate_change \
+    --recipients xxx@xxx.xxx \
+    googletest
 """
 
 import argparse
 import json
 import os
+import re
 import subprocess
 import time
 
@@ -32,9 +34,6 @@ def parse_args():
 
     parser = argparse.ArgumentParser(
         description='Check updates for third party projects in external/.')
-    parser.add_argument(
-        '--result_file',
-        help='Json check result generated by external updater.')
     parser.add_argument(
         '--history',
         help='Path of history file. If doesn'
@@ -42,24 +41,39 @@ def parse_args():
     parser.add_argument(
         '--recipients',
         help='Comma separated recipients of notification email.')
+    parser.add_argument(
+        '--generate_change',
+        help='If set, an upgrade change will be uploaded to Gerrit.',
+        action='store_true', required=False)
+    parser.add_argument(
+        'paths', nargs='*',
+        help='Paths of the project.')
 
     return parser.parse_args()
 
 
-def _send_email(proj, latest_ver, recipient):
+CHANGE_URL_PATTERN = r'(https:\/\/[^\s]*android-review[^\s]*) Upgrade'
+CHANGE_URL_RE = re.compile(CHANGE_URL_PATTERN)
+
+
+def _send_email(proj, latest_ver, recipient, upgrade_log):
     print('Sending email for {}: {}'.format(proj, latest_ver))
-    msg = """New version: {}
+    msg = "New version: {}".format(latest_ver)
+    match = CHANGE_URL_RE.search(upgrade_log)
+    if match is not None:
+        msg += '\n\nAn upgrade change is generated at:\n{}'.format(
+            match.group(1))
+
+    msg += '\n\n'
+    msg += upgrade_log
 
-To upgrade:
-    tools/external_updater/updater.sh update {}""".format(
-        latest_ver, proj)
     subprocess.run(['sendgmr', '--to=' + recipient,
                     '--subject=' + proj], check=True,
                    stdout=subprocess.PIPE, stderr=subprocess.PIPE,
                    input=msg, encoding='ascii')
 
 
-def _process_results(history, results, recipient):
+def _process_results(args, history, results):
     for proj, res in results.items():
         if 'latest' not in res:
             continue
@@ -69,8 +83,9 @@ def _process_results(history, results, recipient):
             continue
         proj_history = history.setdefault(proj, {})
         if latest_ver not in proj_history:
+            upgrade_log = _upgrade(proj) if args.generate_change else ""
             try:
-                _send_email(proj, latest_ver, recipient)
+                _send_email(proj, latest_ver, args.recipients, upgrade_log)
                 proj_history[latest_ver] = int(time.time())
             except subprocess.CalledProcessError as err:
                 msg = """Failed to send email for {} ({}).
@@ -79,10 +94,13 @@ stderr: {}""".format(proj, latest_ver, err.stdout, err.stderr)
                 print(msg)
 
 
+RESULT_FILE_PATH = '/tmp/update_check_result.json'
+
+
 def send_notification(args):
     """Compare results and send notification."""
     results = {}
-    with open(args.result_file, 'r') as f:
+    with open(RESULT_FILE_PATH, 'r') as f:
         results = json.load(f)
     history = {}
     try:
@@ -91,16 +109,45 @@ def send_notification(args):
     except FileNotFoundError:
         pass
 
-    _process_results(history, results, args.recipients)
+    _process_results(args, history, results)
 
     with open(args.history, 'w') as f:
         json.dump(history, f, sort_keys=True)
 
 
+def _upgrade(proj):
+    out = subprocess.run(['out/soong/host/linux-x86/bin/external_updater',
+                          'update', '--branch_and_commit', '--push_change',
+                          proj],
+                         stdout=subprocess.PIPE, stderr=subprocess.PIPE,
+                         cwd=os.environ['ANDROID_BUILD_TOP'])
+    stdout = out.stdout.decode('utf-8')
+    stderr = out.stderr.decode('utf-8')
+    return """
+====================
+|    Debug Info    |
+====================
+-=-=-=-=stdout=-=-=-=-
+{}
+
+-=-=-=-=stderr=-=-=-=-
+{}
+""".format(stdout, stderr)
+
+
+def _check_updates(args):
+    subprocess.run(['out/soong/host/linux-x86/bin/external_updater',
+                    'check',
+                    '--json_output', RESULT_FILE_PATH,
+                    '--delay', '0'] + args.paths,
+                   cwd=os.environ['ANDROID_BUILD_TOP'])
+
+
 def main():
     """The main entry."""
 
     args = parse_args()
+    _check_updates(args)
     send_notification(args)