# HG changeset patch
# User Dan Villiom Podlaski Christiansen <danchr@gmail.com>
# Date 1625574832 -7200
#      Tue Jul 06 14:33:52 2021 +0200
# Node ID 5b271ae358e437a07df3052add7d1ff583a51e99
# Parent  3bd9a805ec00f4e68dbea4d4a3230ff11430f5ca
push: output when non-pushable commits exist

This is an area where we have no choice but diverging from stock
Mercurial, as Git does not allow anonymous heads. We can only push
something that has either a bookmark or a tag.

In order to lessen confusion for users, we output a message inspired
by Mercurial's (ignoring %d secret commits) — which serves a similar
purpose.

diff --git a/hggit/git_handler.py b/hggit/git_handler.py
--- a/hggit/git_handler.py
+++ b/hggit/git_handler.py
@@ -484,7 +484,33 @@
                 self.update_remote_branches(remote_name, new_refs_with_head)
 
         if old_refs == new_refs:
-            self.ui.status(_(b"no changes found\n"))
+            if revs or not old_refs:
+                # fast path to skip the check below
+                self.ui.status(_(b"no changes found\n"))
+            else:
+                # check whether any commits were skipped due to
+                # missing names; this is equivalent to the stock
+                # (ignoring %d secret commits) message, but specific
+                # to pushing to Git, which doesn't have anonymous
+                # heads
+                served = self.repo.filtered(b'served')
+                exported = set(filter(None, (
+                    self.map_hg_get(sha, deref=True)
+                    for sha in old_refs.values()
+                )))
+                unexported = served.revs(
+                    b"not ancestors(%s)" % b" or ".join(exported),
+                )
+
+                if not unexported:
+                    self.ui.status(_(b"no changes found\n"))
+                else:
+                    self.ui.status(
+                        b"no changes found "
+                        b"(ignoring %d changesets without bookmarks or tags)\n"
+                        % len(unexported),
+                    )
+
             ret = None
         elif len(new_refs) > len(old_refs):
             ret = 1 + (len(new_refs) - len(old_refs))
diff --git a/tests/test-push-anonymous.t b/tests/test-push-anonymous.t
new file mode 100644
--- /dev/null
+++ b/tests/test-push-anonymous.t
@@ -0,0 +1,52 @@
+Pushing to Git
+==============
+
+Anonymous HEAD
+--------------
+
+Git does not allow anonymous heads, so what happens if you try to push
+one? Well, you get nothing, since we only push bookmarks, but at we should inform the user of that.
+
+Load commonly used test logic
+  $ . "$TESTDIR/testutil"
+
+Create a Git repository with a commit in it
+
+  $ git init gitrepo
+  Initialized empty Git repository in $TESTTMP/gitrepo/.git/
+  $ cd gitrepo
+  $ echo alpha > alpha
+  $ git add alpha
+  $ fn_git_commit -m "add alpha"
+  $ git checkout -d master
+  HEAD is now at 7eeab2e add alpha
+  $ cd ..
+
+Clone it, deactivate the bookmark, add a commit, and push!
+
+  $ hg clone -U gitrepo hgrepo
+  importing 1 git commits
+  new changesets ff7a2f2d8d70 (1 drafts)
+  $ cd hgrepo
+  $ hg up tip
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ echo beta > beta
+  $ hg add beta
+  $ fn_hg_commit -m "add beta"
+
+Pushing that changeset should print a helpful message:
+
+  $ hg push
+  pushing to $TESTTMP/gitrepo
+  searching for changes
+  no changes found (ignoring 1 changesets without bookmarks or tags)
+  [1]
+
+But what about untagged, but secret changesets?
+
+  $ hg phase -fs tip
+  $ hg push
+  pushing to $TESTTMP/gitrepo
+  searching for changes
+  no changes found
+  [1]