Re: [PATCH v4 6/6] get_short_oid: document & warn if we ignore the type selector

2018-05-10 Thread Jeff King
On Thu, May 10, 2018 at 12:03:22PM -0400, Jeff King wrote:

> And finally, your 06fa example for me shows behavior that's either
> buggy, or I'm just confused. I get:
> 
>   $ git rev-parse 06fa^{blob}
>   error: short SHA1 06fa is ambiguous
>   hint: The candidates are:
>   hint:   06fa2b7c2b tag v2.1.4
>   hint:   06faa52353 commit 2005-10-18 - 2005-10-18 midnight
>   hint:   06fac427af blob
>   hint:   06faf6ba64 tree
> 
> (That 06fac blob comes Junio's refs/notes/amlog). Shouldn't the blob
> disambiguator show me just that object?

Ah, I see. No, "^{blob}" does not actually pass the blob disambiguator.
We only handle committish and treeish right now, and this iteration of
the series omits the function to fix that.

So I think the principle of this commit is sound without that patch, but
your example is not a good one anymore. :)

-Peff


Re: [PATCH v4 6/6] get_short_oid: document & warn if we ignore the type selector

2018-05-10 Thread Jeff King
On Thu, May 10, 2018 at 12:03:22PM -0400, Jeff King wrote:

> But some cases _don't_ issue an error. For example, try this:
> 
>   $ git log ..06faf
> 
> which returns an empty output! We return the single matching tree, even
> though the ".." triggers the commit hint. The revision machinery just
> queues the tree, and then later when we see we're not doing an --objects
> traversal, it just gets ignored. (That's a separate issue, but it shows
> that the hints are just that: hints. The code that runs after does not
> necessarily require a matching type).

I actually have a patch that generates a warning for this case (below).
I've been running with it for about a year, but it annoyingly produces
warnings for "git log --all":

  $ git log --all
  warning: ignoring blob object in traversal: refs/tags/junio-gpg-pub

I guess ideally it would distinguish between items added explicitly and
those added by a wildcard (or perhaps the wildcard adder should be more
careful about adding useless objects).

---
diff --git a/revision.c b/revision.c
index 1cff11833e..816d6b75ee 100644
--- a/revision.c
+++ b/revision.c
@@ -215,6 +215,16 @@ void add_pending_oid(struct rev_info *revs, const char 
*name,
add_pending_object(revs, object, name);
 }
 
+static void warn_ignored_object(struct object *object, const char *name)
+{
+   if (object->flags & UNINTERESTING)
+   return;
+
+   warning(_("ignoring %s object in traversal: %s"),
+   type_name(object->type),
+   (name && *name) ? name : oid_to_hex(>oid));
+}
+
 static struct commit *handle_commit(struct rev_info *revs,
struct object_array_entry *entry)
 {
@@ -272,8 +282,10 @@ static struct commit *handle_commit(struct rev_info *revs,
 */
if (object->type == OBJ_TREE) {
struct tree *tree = (struct tree *)object;
-   if (!revs->tree_objects)
+   if (!revs->tree_objects) {
+   warn_ignored_object(object, name);
return NULL;
+   }
if (flags & UNINTERESTING) {
mark_tree_contents_uninteresting(tree);
return NULL;
@@ -286,8 +298,10 @@ static struct commit *handle_commit(struct rev_info *revs,
 * Blob object? You know the drill by now..
 */
if (object->type == OBJ_BLOB) {
-   if (!revs->blob_objects)
+   if (!revs->blob_objects) {
+   warn_ignored_object(object, name);
return NULL;
+   }
if (flags & UNINTERESTING)
return NULL;
add_pending_object_with_path(revs, object, name, mode, path);


Re: [PATCH v4 6/6] get_short_oid: document & warn if we ignore the type selector

2018-05-10 Thread Jeff King
On Thu, May 10, 2018 at 12:43:03PM +, Ævar Arnfjörð Bjarmason wrote:

> The SHA1 prefix 06fa currently matches no blobs in git.git. When
> disambiguating short SHA1s we've been quietly ignoring the user's type
> selector as a fallback mechanism, this was intentionally added in
> 1ffa26c461 ("get_short_sha1: list ambiguous objects on error",
> 2016-09-26).
> 
> I think that behavior makes sense, it's not very useful to just show
> nothing because a preference has been expressed via core.disambiguate,
> but it's bad that we're quietly doing this. The user might thing that
> we just didn't understand what e.g 06fa^{blob} meant.

I had to read this through a few times to figure out what problem you
were solving. Possibly because you lead with 06fa, which is really just
an example (and also, I have an 06fa blob in my clone ;) ).

Maybe:

  If the short-sha1 disambiguation code is told to use a particular hint
  (e.g., treeish or blob) but no objects with that short-sha1 match that
  hint, we end up ignoring the hint. This can result in either:

1. We choose the non-matching object if there is only one. This will
   typically result in an error later up the stack (since whatever
   gave us the hint is expecting a particular type).

2. We list all objects with that short-sha1, including those with
   non-matching types.

  This second case can be confusing to the user, who might think that we
  didn't apply the hint properly (especially if the hint came from
  them). For example, in git.git there is no blob with the prefix 06fa.
  So the user may see:

$ git rev-parse 06fa^{blob}
hint: The candidates are:
hint:   06fa2b7c2b tag v2.1.4
hint:   06faf6ba64 tree
06fa^{blob}
fatal: ambiguous argument '06fa^{blob}': unknown revision or path not in 
the working tree.

  Let's help them out by issuing a warning whenever the hint is ignored.

So that at least explains it in a way that makes sense to me. But now
that I've propped up my strawman, let me take a few swings...

Your patch just covers case 2, I think. And for the error case, that's
probably OK:

  $ git rev-parse 06faf^{blob}
  error: 06faf^{blob}: expected blob type, but the object dereferences to tree 
type
  06faf^{blob}
  error: 06faf^{blob}: expected blob type, but the object dereferences to tree 
type
  fatal: ambiguous argument '06faf^{blob}': unknown revision or path not in the 
working tree.

(though there is a separate bug in showing the error twice).

But some cases _don't_ issue an error. For example, try this:

  $ git log ..06faf

which returns an empty output! We return the single matching tree, even
though the ".." triggers the commit hint. The revision machinery just
queues the tree, and then later when we see we're not doing an --objects
traversal, it just gets ignored. (That's a separate issue, but it shows
that the hints are just that: hints. The code that runs after does not
necessarily require a matching type).

And that example shows another issue, which is that the user does not
necessarily feed us the hint explicitly. We're using a committish hint
there, but I'm not sure if mentioning that would confuse the user or
not. Certainly this warning:

> warning: Your hint (via core.disambiguate or peel syntax) was ignored, we 
> fell
> back to showing all object types since no object of the requested type
> matched the provide short SHA1 06fa

is not accurate, because the hint came from neither of those places. ;)

So all that said together, I kind of wonder if we should consider
issuing the warning earlier, doing so for all cases, and being a bit
less chatty. Like:

  $ git rev-parse 06fa^{blob}
  warning: short object id 06fa did not match any objects of type 'blob'

If that were followed by any of:

  1. error: short SHA1 06fa is ambiguous, then a bunch of non-blobs

  2. error: expected blob but I got a tree

  3. the command proceeds and silently ignores the matched object

I think it would be helpful. We'd need to add in an extra mapping of
GET_OID_* back to a human-readable string, but I think that should be
pretty easy.

And finally, your 06fa example for me shows behavior that's either
buggy, or I'm just confused. I get:

  $ git rev-parse 06fa^{blob}
  error: short SHA1 06fa is ambiguous
  hint: The candidates are:
  hint:   06fa2b7c2b tag v2.1.4
  hint:   06faa52353 commit 2005-10-18 - 2005-10-18 midnight
  hint:   06fac427af blob
  hint:   06faf6ba64 tree

(That 06fac blob comes Junio's refs/notes/amlog). Shouldn't the blob
disambiguator show me just that object?

-Peff


Re: [PATCH v4 6/6] get_short_oid: document & warn if we ignore the type selector

2018-05-10 Thread Martin Ågren
On 10 May 2018 at 14:43, Ævar Arnfjörð Bjarmason  wrote:
> The SHA1 prefix 06fa currently matches no blobs in git.git. When
> disambiguating short SHA1s we've been quietly ignoring the user's type
> selector as a fallback mechanism, this was intentionally added in
> 1ffa26c461 ("get_short_sha1: list ambiguous objects on error",
> 2016-09-26).
>
> I think that behavior makes sense, it's not very useful to just show
> nothing because a preference has been expressed via core.disambiguate,
> but it's bad that we're quietly doing this. The user might thing that
> we just didn't understand what e.g 06fa^{blob} meant.
>
> Now we'll instead print a warning if no objects of the requested type
> were found:
>
> $ git rev-parse 06fa^{blob}
> error: short SHA1 06fa is ambiguous
> hint: The candidates are:
> [... no blobs listed ...]
> warning: Your hint (via core.disambiguate or peel syntax) was ignored, we 
> fell
> back to showing all object types since no object of the requested type
> matched the provide short SHA1 06fa

s/ignored, we/ignored. We/? IMHO, it would read easier.

s/provide short/provided short/

Also: s/SHA1/object id/? That said, you add the warning. The error
message is already there and you are simply following its "SHA1".

Martin


[PATCH v4 6/6] get_short_oid: document & warn if we ignore the type selector

2018-05-10 Thread Ævar Arnfjörð Bjarmason
The SHA1 prefix 06fa currently matches no blobs in git.git. When
disambiguating short SHA1s we've been quietly ignoring the user's type
selector as a fallback mechanism, this was intentionally added in
1ffa26c461 ("get_short_sha1: list ambiguous objects on error",
2016-09-26).

I think that behavior makes sense, it's not very useful to just show
nothing because a preference has been expressed via core.disambiguate,
but it's bad that we're quietly doing this. The user might thing that
we just didn't understand what e.g 06fa^{blob} meant.

Now we'll instead print a warning if no objects of the requested type
were found:

$ git rev-parse 06fa^{blob}
error: short SHA1 06fa is ambiguous
hint: The candidates are:
[... no blobs listed ...]
warning: Your hint (via core.disambiguate or peel syntax) was ignored, we 
fell
back to showing all object types since no object of the requested type
matched the provide short SHA1 06fa

Signed-off-by: Ævar Arnfjörð Bjarmason 
---
 sha1-name.c | 11 ++-
 t/t1512-rev-parse-disambiguation.sh |  5 -
 2 files changed, 14 insertions(+), 2 deletions(-)

diff --git a/sha1-name.c b/sha1-name.c
index 46d8b1afa6..df33cc2dba 100644
--- a/sha1-name.c
+++ b/sha1-name.c
@@ -438,6 +438,7 @@ static int get_short_oid(const char *name, int len, struct 
object_id *oid,
 
if (!quietly && (status == SHORT_NAME_AMBIGUOUS)) {
struct oid_array collect = OID_ARRAY_INIT;
+   int ignored_hint = 0;
 
error(_("short SHA1 %s is ambiguous"), ds.hex_pfx);
 
@@ -447,8 +448,10 @@ static int get_short_oid(const char *name, int len, struct 
object_id *oid,
 * that case, we still want to show them, so disable the hint
 * function entirely.
 */
-   if (!ds.ambiguous)
+   if (!ds.ambiguous) {
ds.fn = NULL;
+   ignored_hint = 1;
+   }
 
advise(_("The candidates are:"));
for_each_abbrev(ds.hex_pfx, collect_ambiguous, );
@@ -457,6 +460,12 @@ static int get_short_oid(const char *name, int len, struct 
object_id *oid,
if (oid_array_for_each(, show_ambiguous_object, ))
BUG("show_ambiguous_object shouldn't return non-zero");
oid_array_clear();
+
+   if (ignored_hint) {
+   warning(_("Your hint (via core.disambiguate or peel 
syntax) was ignored, we fell\n"
+ "back to showing all object types since no 
object of the requested type\n"
+ "matched the provide short SHA1 %s"), 
ds.hex_pfx);
+   }
}
 
return status;
diff --git a/t/t1512-rev-parse-disambiguation.sh 
b/t/t1512-rev-parse-disambiguation.sh
index 2701462041..1f06c1e61f 100755
--- a/t/t1512-rev-parse-disambiguation.sh
+++ b/t/t1512-rev-parse-disambiguation.sh
@@ -344,7 +344,10 @@ test_expect_success C_LOCALE_OUTPUT 'failed type-selector 
still shows hint' '
echo 872 | git hash-object --stdin -w &&
test_must_fail git rev-parse ee3d^{commit} 2>stderr &&
grep ^hint: stderr >hints &&
-   test_line_count = 3 hints
+   test_line_count = 3 hints &&
+   grep ^warning stderr >warnings &&
+   grep -q "Your hint.*was ignored" warnings &&
+   grep -q "the provide short SHA1 ee3d" stderr
 '
 
 test_expect_success 'core.disambiguate config can prefer types' '
-- 
2.17.0.410.g4ac3413cc8