Today I learned that git push will silently try to recreate a remote funny ref if you push to it. "Hypothetically" ... lets say I have a reimplementation of Git called JGit. Lets say its on a server somewhere on the network. Lets say its a bit more liberal in what it accepts... $ git push origin HEAD^:refs/wtf Counting objects: 3, done. Writing objects: 100% (3/3), 206 bytes | 0 bytes/s, done. Total 3 (delta 0), reused 0 (delta 0) To ...blahblah.../wtf * [new branch] HEAD^ -> refs/wtf Okaaaay. We are the proud new owners of $ git ls-remote origin 4da022e5c7e2c33025374ddd1c3aeeb082d7b394 refs/wtf Yea. Great. Here is the WTF. git push will silently send a creation command instead of an update. $ GIT_TRACE_PACKET=1 git push origin HEAD:refs/wtf 22:48:09.277446 pkt-line.c:46 packet: push< 4da022e5c7e2c33025374ddd1c3aeeb082d7b394 refs/wtf\0 side-band-64k delete-refs report-status quiet ofs-delta agent=JGit/4-... 22:48:09.277522 pkt-line.c:46 packet: push< 0000 22:48:09.277595 pkt-line.c:46 packet: push> 0000000000000000000000000000000000000000 f721fb36771dc587d45e8a95ef9f7edcc3849236 refs/wtf\0 report-status side-band-64k agent=git/2.4.3.573.g4eafbef 22:48:09.277605 pkt-line.c:46 packet: push> 0000 Counting objects: 6, done. Delta compression using up to 12 threads. Compressing objects: 100% (2/2), done. Writing objects: 100% (6/6), 409 bytes | 0 bytes/s, done. Total 6 (delta 0), reused 0 (delta 0) 22:48:09.419038 pkt-line.c:46 packet: push< \1000eunpack ok001fng refs/wtf already exists0000 22:48:09.419066 pkt-line.c:46 packet: push< 0000 22:48:09.419073 pkt-line.c:46 packet: push< unpack ok 22:48:09.419082 pkt-line.c:46 packet: push< ng refs/wtf already exists 22:48:09.419092 pkt-line.c:46 packet: push< 0000 To rpc://user/sop/wtf ! [remote rejected] HEAD -> refs/wtf (already exists) error: failed to push some refs to '...blahblah.../wtf' I think the cause is get_remote_heads() gets passed REF_NORMAL during send-pack, which filters out that refs/wtf advertisement from the server. Once its filtered out send-pack thinks the ref is new and happily sends along the command to create it. In git-core this rejection of the funny ref is done at the server. This JGit server was fine with the funny ref. It didn't care earlier when git push created it. Now git push isn't so happy with that funny ref on the RHS, because it always forgets it in the advertisement. This makes it hard to update the ref. Or delete it remotely. If we don't want that ref in the advertisement, push should refuse it in the RHS. If we want to let the remote decide, send-pack should honor the advertisement. -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html