{"thread":{"id":"41244","subject":"[ BUG ] push --force-with-lease status output signals a \"fast-fowarded\" push when the ref is force-updated","startedAt":"2016-01-22T21:47:58Z","lastAt":"2016-01-22T21:47:58Z","messageCount":1,"participants":["Andrew Wheeler"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"276576","messageId":"CAE=k0mv_Ouq=GbB-qWyRn9Js406Y0XwntyCp95JfOq3NGy+JzQ@mail.gmail.com","threadId":"41244","inReplyTo":null,"subject":"[ BUG ] push --force-with-lease status output signals a \"fast-fowarded\" push when the ref is force-updated","fromName":"Andrew Wheeler","fromEmail":"awheeler@motorola.com","sentAt":"2016-01-22T21:47:58Z","receivedAt":"2016-01-22T21:47:58Z","isPatch":false,"sender":{"key":"awheeler@motorola.com","avatar":"https://avatars.githubusercontent.com/u/6362528?v=4"},"body":"When using push --force the output reports if the reference(s) was\nforce-updated:\n\n$ git push --force origin origin/master^:master\nTotal 0 (delta 0), reused 0 (delta 0)\nTo /home/thf876/gittest/m\n + cc44495...8302fcb origin/master^ -> master (forced update)\n\n\nBut when using push --force-with-lease the output reports that the\nreference was \"fast-forward\" updated, even if the branch was\nforce-updated:\n\n$ git push --force-with-lease origin origin/master^:master\nTotal 0 (delta 0), reused 0 (delta 0)\nTo /home/thf876/gittest/m\n   a454b7f..cc44495  origin/master^ -> master\n\nThe main problem seems to be that ref.forced_update is never set in\nremote.c.  I have a patch below that works-around the problem, but it\nmay be not the right approach.\n\n\n\ncommit 81d8b713ee83161dbd7eb3dafd22718d1fa992a1\nAuthor: Andrew Wheeler <awheeler@motorola.com>\nDate:   Tue Jan 19 15:23:32 2016 -0600\n\n    push --force-with-lease: Fix ref status reporting\n\n    The --force--with-lease push option leads to less\n    detailed status information than --force. In particular,\n    the output indicates that a reference was fast-forwarded,\n    even when it was force-updated.\n\n    Modify the --force-with-lease ref status logic to leverage\n    the --force ref status logic when the \"lease\" conditions\n    are met.\n\n    Signed-off-by: Andrew Wheeler <awheeler@motorola.com>\n\ndiff --git a/remote.c b/remote.c\nindex 9d34b5a..bad6213 100644\n--- a/remote.c\n+++ b/remote.c\n@@ -1545,11 +1545,8 @@ void set_ref_status_for_push(struct ref\n*remote_refs, int send_mirror,\n                }\n\n                /*\n-                * Bypass the usual \"must fast-forward\" check but\n-                * replace it with a weaker \"the old value must be\n-                * this value we observed\".  If the remote ref has\n-                * moved and is now different from what we expect,\n-                * reject any push.\n+                * If the remote ref has moved and is now different\n+                * from what we expect, reject any push.\n                 *\n                 * It also is an error if the user told us to check\n                 * with the remote-tracking branch to find the value\n@@ -1560,10 +1557,14 @@ void set_ref_status_for_push(struct ref\n*remote_refs, int send_mirror,\n                        if (ref->expect_old_no_trackback ||\n                            oidcmp(&ref->old_oid, &ref->old_oid_expect))\n                                reject_reason = REF_STATUS_REJECT_STALE;\n+                       else\n+                               /* If the ref isn't stale then force\nthe update. */\n+                               force_ref_update = 1;\n                }\n\n                /*\n-                * The usual \"must fast-forward\" rules.\n+                * If the update isn't already rejected then check\n+                * the usual \"must fast-forward\" rules.\n                 *\n                 * Decide whether an individual refspec A:B can be\n                 * pushed.  The push will succeed if any of the\n@@ -1580,9 +1581,10 @@ void set_ref_status_for_push(struct ref\n*remote_refs, int send_mirror,\n                 *\n                 * (4) it is forced using the +A:B notation, or by\n                 *     passing the --force argument\n+                *\n                 */\n\n-               else if (!ref->deletion && !is_null_oid(&ref->old_oid)) {\n+               if (!reject_reason && !ref->deletion &&\n!is_null_oid(&ref->old_oid)) {\n                        if (starts_with(ref->name, \"refs/tags/\"))\n                                reject_reason =\nREF_STATUS_REJECT_ALREADY_EXISTS;\n                        else if (!has_object_file(&ref->old_oid))\nthf876@slug:~/git$\n"}]}