[PATCH v3 0/2] push: fix --force-if-includes consulting wrong ref
From: Tyler Cipriani <hidden>
Date: 2026-09-10 23:05:21
Changes since v2:
- Correct patch threading of 1/2 and 2/2 to reply to cover letter of
current patchset vs. cover letter of the initial iteration.
Changes since v1:
- Clarify in log message 1/2 that --force-if-includes will reject a
detached HEAD today (when the same-named local branch lacks the remote
tip). And note that this change makes it explicit to always reject
the detached HEAD case.
--force-if-includes has been checking the reflog of the local branch named
after the destination branch regardless of what's being pushed. This can cause
false rejections or unintended data loss.
False rejection has been reported twice that I could find:
- 2023-07-26 - Stefan Haller reported local branch with a different name
false rejection[0]
- 2025-05-08 - D. Ben Knoble reported detached HEAD false rejection[1]
The same root cause can result in data loss: when a same-name local branch
contains the remote tip but you --force-if-includes push an unrelated branch,
clobbering the remote repo. PoCs are in t/t5533-push-cas.sh -- new test cases
fail against maint, but pass with patches applied.
Existing tests covered refspecs with different names for --force-with-lease,
but missed --force-if-includes. New patches cover:
- allow forced-update using refspec with different-named local branch
- allow same as above, but with HEAD
- reject force-update using refspec with different-named local branch lacking
branch tip
- reject same as above using HEAD
- reject detached HEAD
Resolved question: the detached HEAD case; HEAD's reflog was considered
and rejected as too broad for purpose in the original review. cf. [2]
[0]: <https://lore.kernel.org/git/f51c73ed-eb03-83ca-fb31-d3e2645c9a63@haller-berlin.de (local)>
[1]: <https://lore.kernel.org/git/CALnO6CCk0SgwObQRnpd5Pt_DvCKF8dBmyVHivU6Nr_O-GusGLA@mail.gmail.com (local)>
[2]: <https://lore.kernel.org/git/CAHLx=O=tVhtiZpaRP9TpfiBfOMS2xPe3c3=mC3VNEdBrLOioFg@mail.gmail.com (local)>
Tyler Cipriani (2):
push: check pushed ref for --force-if-includes
push: fix --force-if-includes detached HEAD advice
Documentation/config/advice.adoc | 4 ++
advice.c | 1 +
advice.h | 1 +
builtin/push.c | 15 +++++++
builtin/send-pack.c | 5 +++
remote.c | 27 +++++++++++-
remote.h | 10 +++--
send-pack.c | 1 +
t/t5533-push-cas.sh | 70 +++++++++++++++++++++++++++++++-
transport-helper.c | 5 +++
transport.c | 8 ++++
transport.h | 1 +
12 files changed, 143 insertions(+), 5 deletions(-)
Range-diff against v2:
1: da27c421ed = 1: da27c421ed push: check pushed ref for --force-if-includes
2: e07d16d53e = 2: e07d16d53e push: fix --force-if-includes detached HEAD advice
--
2.47.3