SYNOPSIS
 --------
 [verse]
-'git-push' [--all] [--tags] [--receive-pack=<git-receive-pack>]
+'git-push' [--all] [--dry-run] [--tags] [--receive-pack=<git-receive-pack>]
            [--repo=all] [-f | --force] [-v] [<repository> <refspec>...]
 
 DESCRIPTION
        Instead of naming each ref to push, specifies that all
        refs under `$GIT_DIR/refs/heads/` be pushed.
 
+\--dry-run::
+       Do everything except actually send the updates.
+
 \--tags::
        All refs under `$GIT_DIR/refs/tags` are pushed, in
        addition to refspecs explicitly listed on the command
 
 #include "builtin.h"
 #include "remote.h"
 
-static const char push_usage[] = "git-push [--all] [--tags] [--receive-pack=<git-receive-pack>] [--repo=all] [-f | --force] [-v] [<repository> <refspec>...]";
+static const char push_usage[] = "git-push [--all] [--dry-run] [--tags] [--receive-pack=<git-receive-pack>] [--repo=all] [-f | --force] [-v] [<repository> <refspec>...]";
 
-static int all, force, thin, verbose;
+static int all, dry_run, force, thin, verbose;
 static const char *receivepack;
 
 static const char **refspec;
        argc = 1;
        if (all)
                argv[argc++] = "--all";
+       if (dry_run)
+               argv[argc++] = "--dry-run";
        if (force)
                argv[argc++] = "--force";
        if (receivepack)
                        all = 1;
                        continue;
                }
+               if (!strcmp(arg, "--dry-run")) {
+                       dry_run = 1;
+                       continue;
+               }
                if (!strcmp(arg, "--tags")) {
                        add_refspec("refs/tags/*");
                        continue;
 
 
 '
 
+test_expect_success 'push with dry-run' '
+
+       mk_test heads/master &&
+       cd testrepo &&
+       old_commit=$(git show-ref -s --verify refs/heads/master) &&
+       cd .. &&
+       git push --dry-run testrepo &&
+       check_push_result $old_commit heads/master
+'
+
 test_done