2023-05-16 08:33:57 +02:00
|
|
|
#include "git-compat-util.h"
|
2023-04-11 09:41:49 +02:00
|
|
|
#include "object-name.h"
|
2023-04-11 05:00:39 +02:00
|
|
|
#include "advice.h"
|
2017-06-14 20:07:36 +02:00
|
|
|
#include "config.h"
|
2023-03-21 07:26:03 +01:00
|
|
|
#include "environment.h"
|
2023-03-21 07:25:54 +01:00
|
|
|
#include "gettext.h"
|
2023-02-24 01:09:27 +01:00
|
|
|
#include "hex.h"
|
2005-10-14 03:57:40 +02:00
|
|
|
#include "tag.h"
|
2005-08-04 07:15:49 +02:00
|
|
|
#include "commit.h"
|
2005-10-14 03:57:40 +02:00
|
|
|
#include "tree.h"
|
|
|
|
#include "blob.h"
|
2006-04-19 20:56:53 +02:00
|
|
|
#include "tree-walk.h"
|
2006-05-17 11:56:09 +02:00
|
|
|
#include "refs.h"
|
2009-09-10 17:25:57 +02:00
|
|
|
#include "remote.h"
|
2015-05-19 23:44:23 +02:00
|
|
|
#include "dir.h"
|
2020-03-30 16:03:46 +02:00
|
|
|
#include "oid-array.h"
|
2023-04-22 22:17:27 +02:00
|
|
|
#include "oidtree.h"
|
2017-08-19 00:20:19 +02:00
|
|
|
#include "packfile.h"
|
2023-04-22 22:17:26 +02:00
|
|
|
#include "pretty.h"
|
2023-05-16 08:34:06 +02:00
|
|
|
#include "object-store-ll.h"
|
2023-05-16 08:33:56 +02:00
|
|
|
#include "read-cache-ll.h"
|
2018-03-23 18:20:57 +01:00
|
|
|
#include "repository.h"
|
2023-03-21 07:26:05 +01:00
|
|
|
#include "setup.h"
|
2019-04-16 11:33:36 +02:00
|
|
|
#include "submodule.h"
|
2018-07-12 21:39:35 +02:00
|
|
|
#include "midx.h"
|
2018-07-20 18:33:04 +02:00
|
|
|
#include "commit-reach.h"
|
date API: create a date.h, split from cache.h
Move the declaration of the date.c functions from cache.h, and adjust
the relevant users to include the new date.h header.
The show_ident_date() function belonged in pretty.h (it's defined in
pretty.c), its two users outside of pretty.c didn't strictly need to
include pretty.h, as they get it indirectly, but let's add it to them
anyway.
Similarly, the change to "builtin/{fast-import,show-branch,tag}.c"
isn't needed as far as the compiler is concerned, but since they all
use the "DATE_MODE()" macro we now define in date.h, let's have them
include it.
We could simply include this new header in "cache.h", but as this
change shows these functions weren't common enough to warrant
including in it in the first place. By moving them out of cache.h
changes to this API will no longer cause a (mostly) full re-build of
the project when "make" is run.
Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2022-02-16 09:14:02 +01:00
|
|
|
#include "date.h"
|
2005-08-04 07:15:49 +02:00
|
|
|
|
2019-04-16 11:33:29 +02:00
|
|
|
static int get_oid_oneline(struct repository *r, const char *, struct object_id *, struct commit_list *);
|
2010-12-13 04:01:15 +01:00
|
|
|
|
2019-04-16 11:33:23 +02:00
|
|
|
typedef int (*disambiguate_hint_fn)(struct repository *, const struct object_id *, void *);
|
2012-06-21 07:07:36 +02:00
|
|
|
|
|
|
|
struct disambiguate_state {
|
2016-09-26 14:00:04 +02:00
|
|
|
int len; /* length of prefix in hex chars */
|
2017-03-26 18:01:24 +02:00
|
|
|
char hex_pfx[GIT_MAX_HEXSZ + 1];
|
2017-03-26 18:01:33 +02:00
|
|
|
struct object_id bin_pfx;
|
2016-09-26 14:00:04 +02:00
|
|
|
|
2019-04-16 11:33:23 +02:00
|
|
|
struct repository *repo;
|
2012-06-21 07:07:36 +02:00
|
|
|
disambiguate_hint_fn fn;
|
|
|
|
void *cb_data;
|
2017-03-26 18:01:33 +02:00
|
|
|
struct object_id candidate;
|
2012-06-21 07:07:36 +02:00
|
|
|
unsigned candidate_exists:1;
|
|
|
|
unsigned candidate_checked:1;
|
|
|
|
unsigned candidate_ok:1;
|
|
|
|
unsigned disambiguate_fn_used:1;
|
|
|
|
unsigned ambiguous:1;
|
2012-07-03 23:21:59 +02:00
|
|
|
unsigned always_call_fn:1;
|
2012-06-21 07:07:36 +02:00
|
|
|
};
|
|
|
|
|
2017-03-26 18:01:34 +02:00
|
|
|
static void update_candidates(struct disambiguate_state *ds, const struct object_id *current)
|
2012-06-21 07:07:36 +02:00
|
|
|
{
|
2012-07-03 23:21:59 +02:00
|
|
|
if (ds->always_call_fn) {
|
2019-04-16 11:33:23 +02:00
|
|
|
ds->ambiguous = ds->fn(ds->repo, current, ds->cb_data) ? 1 : 0;
|
2012-07-03 23:21:59 +02:00
|
|
|
return;
|
|
|
|
}
|
2012-06-21 07:07:36 +02:00
|
|
|
if (!ds->candidate_exists) {
|
|
|
|
/* this is the first candidate */
|
2017-03-26 18:01:34 +02:00
|
|
|
oidcpy(&ds->candidate, current);
|
2012-06-21 07:07:36 +02:00
|
|
|
ds->candidate_exists = 1;
|
|
|
|
return;
|
convert "oidcmp() == 0" to oideq()
Using the more restrictive oideq() should, in the long run,
give the compiler more opportunities to optimize these
callsites. For now, this conversion should be a complete
noop with respect to the generated code.
The result is also perhaps a little more readable, as it
avoids the "zero is equal" idiom. Since it's so prevalent in
C, I think seasoned programmers tend not to even notice it
anymore, but it can sometimes make for awkward double
negations (e.g., we can drop a few !!oidcmp() instances
here).
This patch was generated almost entirely by the included
coccinelle patch. This mechanical conversion should be
completely safe, because we check explicitly for cases where
oidcmp() is compared to 0, which is what oideq() is doing
under the hood. Note that we don't have to catch "!oidcmp()"
separately; coccinelle's standard isomorphisms make sure the
two are treated equivalently.
I say "almost" because I did hand-edit the coccinelle output
to fix up a few style violations (it mostly keeps the
original formatting, but sometimes unwraps long lines).
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2018-08-28 23:22:40 +02:00
|
|
|
} else if (oideq(&ds->candidate, current)) {
|
2012-06-21 07:07:36 +02:00
|
|
|
/* the same as what we already have seen */
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!ds->fn) {
|
|
|
|
/* cannot disambiguate between ds->candidate and current */
|
|
|
|
ds->ambiguous = 1;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!ds->candidate_checked) {
|
2019-04-16 11:33:23 +02:00
|
|
|
ds->candidate_ok = ds->fn(ds->repo, &ds->candidate, ds->cb_data);
|
2012-06-21 07:07:36 +02:00
|
|
|
ds->disambiguate_fn_used = 1;
|
|
|
|
ds->candidate_checked = 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!ds->candidate_ok) {
|
2013-07-22 23:02:23 +02:00
|
|
|
/* discard the candidate; we know it does not satisfy fn */
|
2017-03-26 18:01:34 +02:00
|
|
|
oidcpy(&ds->candidate, current);
|
2012-06-21 07:07:36 +02:00
|
|
|
ds->candidate_checked = 0;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* if we reach this point, we know ds->candidate satisfies fn */
|
2019-04-16 11:33:23 +02:00
|
|
|
if (ds->fn(ds->repo, current, ds->cb_data)) {
|
2012-06-21 07:07:36 +02:00
|
|
|
/*
|
|
|
|
* if both current and candidate satisfy fn, we cannot
|
|
|
|
* disambiguate.
|
|
|
|
*/
|
|
|
|
ds->candidate_ok = 0;
|
|
|
|
ds->ambiguous = 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* otherwise, current can be discarded and candidate is still good */
|
|
|
|
}
|
|
|
|
|
2020-12-31 12:56:20 +01:00
|
|
|
static int match_hash(unsigned, const unsigned char *, const unsigned char *);
|
2017-06-22 20:19:48 +02:00
|
|
|
|
2021-07-08 01:10:19 +02:00
|
|
|
static enum cb_next match_prefix(const struct object_id *oid, void *arg)
|
|
|
|
{
|
|
|
|
struct disambiguate_state *ds = arg;
|
|
|
|
/* no need to call match_hash, oidtree_each did prefix match */
|
|
|
|
update_candidates(ds, oid);
|
|
|
|
return ds->ambiguous ? CB_BREAK : CB_CONTINUE;
|
|
|
|
}
|
|
|
|
|
2016-09-26 14:00:04 +02:00
|
|
|
static void find_short_object_filename(struct disambiguate_state *ds)
|
2005-08-04 07:15:49 +02:00
|
|
|
{
|
2018-11-12 15:48:47 +01:00
|
|
|
struct object_directory *odb;
|
2005-10-03 06:40:51 +02:00
|
|
|
|
2021-07-08 01:10:19 +02:00
|
|
|
for (odb = ds->repo->objects->odb; odb && !ds->ambiguous; odb = odb->next)
|
|
|
|
oidtree_each(odb_loose_cache(odb, &ds->bin_pfx),
|
|
|
|
&ds->bin_pfx, ds->len, match_prefix, ds);
|
2005-08-04 07:15:49 +02:00
|
|
|
}
|
|
|
|
|
2020-12-31 12:56:20 +01:00
|
|
|
static int match_hash(unsigned len, const unsigned char *a, const unsigned char *b)
|
2005-08-04 07:15:49 +02:00
|
|
|
{
|
|
|
|
do {
|
|
|
|
if (*a != *b)
|
|
|
|
return 0;
|
|
|
|
a++;
|
|
|
|
b++;
|
|
|
|
len -= 2;
|
|
|
|
} while (len > 1);
|
|
|
|
if (len)
|
|
|
|
if ((*a ^ *b) & 0xf0)
|
|
|
|
return 0;
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2018-07-12 21:39:35 +02:00
|
|
|
static void unique_in_midx(struct multi_pack_index *m,
|
|
|
|
struct disambiguate_state *ds)
|
|
|
|
{
|
|
|
|
uint32_t num, i, first = 0;
|
|
|
|
const struct object_id *current = NULL;
|
|
|
|
num = m->num_objects;
|
|
|
|
|
|
|
|
if (!num)
|
|
|
|
return;
|
|
|
|
|
|
|
|
bsearch_midx(&ds->bin_pfx, m, &first);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* At this point, "first" is the location of the lowest object
|
|
|
|
* with an object name that could match "bin_pfx". See if we have
|
|
|
|
* 0, 1 or more objects that actually match(es).
|
|
|
|
*/
|
|
|
|
for (i = first; i < num && !ds->ambiguous; i++) {
|
|
|
|
struct object_id oid;
|
|
|
|
current = nth_midxed_object_oid(&oid, m, i);
|
2020-12-31 12:56:20 +01:00
|
|
|
if (!match_hash(ds->len, ds->bin_pfx.hash, current->hash))
|
2018-07-12 21:39:35 +02:00
|
|
|
break;
|
|
|
|
update_candidates(ds, current);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-09-26 14:00:04 +02:00
|
|
|
static void unique_in_pack(struct packed_git *p,
|
2012-06-21 07:07:36 +02:00
|
|
|
struct disambiguate_state *ds)
|
2005-08-04 07:15:49 +02:00
|
|
|
{
|
2018-03-24 17:41:08 +01:00
|
|
|
uint32_t num, i, first = 0;
|
2012-06-18 22:10:38 +02:00
|
|
|
|
midx: add packs to packed_git linked list
The multi-pack-index allows searching for objects across multiple
packs using one object list. The original design gains many of
these performance benefits by keeping the packs in the
multi-pack-index out of the packed_git list.
Unfortunately, this has one major drawback. If the multi-pack-index
covers thousands of packs, and a command loads many of those packs,
then we can hit the limit for open file descriptors. The
close_one_pack() method is used to limit this resource, but it
only looks at the packed_git list, and uses an LRU cache to prevent
thrashing.
Instead of complicating this close_one_pack() logic to include
direct references to the multi-pack-index, simply add the packs
opened by the multi-pack-index to the packed_git list. This
immediately solves the file-descriptor limit problem, but requires
some extra steps to avoid performance issues or other problems:
1. Create a multi_pack_index bit in the packed_git struct that is
one if and only if the pack was loaded from a multi-pack-index.
2. Skip packs with the multi_pack_index bit when doing object
lookups and abbreviations. These algorithms already check the
multi-pack-index before the packed_git struct. This has a very
small performance hit, as we need to walk more packed_git
structs. This is acceptable, since these operations run binary
search on the other packs, so this walk-and-ignore logic is
very fast by comparison.
3. When closing a multi-pack-index file, do not close its packs,
as those packs will be closed using close_all_packs(). In some
cases, such as 'git repack', we run 'close_midx()' without also
closing the packs, so we need to un-set the multi_pack_index bit
in those packs. This is necessary, and caught by running
t6501-freshen-objects.sh with GIT_TEST_MULTI_PACK_INDEX=1.
To manually test this change, I inserted trace2 logging into
close_pack_fd() and set pack_max_fds to 10, then ran 'git rev-list
--all --objects' on a copy of the Git repo with 300+ pack-files and
a multi-pack-index. The logs verified the packs are closed as
we read them beyond the file descriptor limit.
Signed-off-by: Derrick Stolee <dstolee@microsoft.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2019-04-29 18:18:56 +02:00
|
|
|
if (p->multi_pack_index)
|
|
|
|
return;
|
|
|
|
|
2017-10-12 14:02:20 +02:00
|
|
|
if (open_pack_index(p) || !p->num_objects)
|
|
|
|
return;
|
|
|
|
|
2012-06-18 22:10:38 +02:00
|
|
|
num = p->num_objects;
|
2018-03-24 17:41:08 +01:00
|
|
|
bsearch_pack(&ds->bin_pfx, p, &first);
|
2012-06-18 22:10:38 +02:00
|
|
|
|
|
|
|
/*
|
|
|
|
* At this point, "first" is the location of the lowest object
|
2012-06-21 07:35:43 +02:00
|
|
|
* with an object name that could match "bin_pfx". See if we have
|
2012-06-18 22:10:38 +02:00
|
|
|
* 0, 1 or more objects that actually match(es).
|
|
|
|
*/
|
2012-06-21 07:07:36 +02:00
|
|
|
for (i = first; i < num && !ds->ambiguous; i++) {
|
2017-03-26 18:01:34 +02:00
|
|
|
struct object_id oid;
|
2020-02-24 05:27:36 +01:00
|
|
|
nth_packed_object_id(&oid, p, i);
|
2020-12-31 12:56:20 +01:00
|
|
|
if (!match_hash(ds->len, ds->bin_pfx.hash, oid.hash))
|
2012-06-18 22:10:38 +02:00
|
|
|
break;
|
2020-02-24 05:27:36 +01:00
|
|
|
update_candidates(ds, &oid);
|
2005-08-04 07:15:49 +02:00
|
|
|
}
|
2012-06-18 22:10:38 +02:00
|
|
|
}
|
|
|
|
|
2016-09-26 14:00:04 +02:00
|
|
|
static void find_short_packed_object(struct disambiguate_state *ds)
|
2005-08-04 07:15:49 +02:00
|
|
|
{
|
2018-07-12 21:39:35 +02:00
|
|
|
struct multi_pack_index *m;
|
2005-08-04 07:15:49 +02:00
|
|
|
struct packed_git *p;
|
|
|
|
|
2019-04-16 11:33:23 +02:00
|
|
|
for (m = get_multi_pack_index(ds->repo); m && !ds->ambiguous;
|
2018-07-12 21:39:35 +02:00
|
|
|
m = m->next)
|
|
|
|
unique_in_midx(m, ds);
|
2019-04-16 11:33:23 +02:00
|
|
|
for (p = get_packed_git(ds->repo); p && !ds->ambiguous;
|
2018-03-23 18:20:59 +01:00
|
|
|
p = p->next)
|
2016-09-26 14:00:04 +02:00
|
|
|
unique_in_pack(p, ds);
|
2005-10-03 06:40:51 +02:00
|
|
|
}
|
|
|
|
|
2012-06-21 07:07:36 +02:00
|
|
|
static int finish_object_disambiguation(struct disambiguate_state *ds,
|
sha1_name: convert get_sha1* to get_oid*
Now that all the callers of get_sha1 directly or indirectly use struct
object_id, rename the functions starting with get_sha1 to start with
get_oid. Convert the internals in sha1_name.c to use struct object_id
as well, and eliminate explicit length checks where possible. Convert a
use of 40 in get_oid_basic to GIT_SHA1_HEXSZ.
Outside of sha1_name.c and cache.h, this transition was made with the
following semantic patch:
@@
expression E1, E2;
@@
- get_sha1(E1, E2.hash)
+ get_oid(E1, &E2)
@@
expression E1, E2;
@@
- get_sha1(E1, E2->hash)
+ get_oid(E1, E2)
@@
expression E1, E2;
@@
- get_sha1_committish(E1, E2.hash)
+ get_oid_committish(E1, &E2)
@@
expression E1, E2;
@@
- get_sha1_committish(E1, E2->hash)
+ get_oid_committish(E1, E2)
@@
expression E1, E2;
@@
- get_sha1_treeish(E1, E2.hash)
+ get_oid_treeish(E1, &E2)
@@
expression E1, E2;
@@
- get_sha1_treeish(E1, E2->hash)
+ get_oid_treeish(E1, E2)
@@
expression E1, E2;
@@
- get_sha1_commit(E1, E2.hash)
+ get_oid_commit(E1, &E2)
@@
expression E1, E2;
@@
- get_sha1_commit(E1, E2->hash)
+ get_oid_commit(E1, E2)
@@
expression E1, E2;
@@
- get_sha1_tree(E1, E2.hash)
+ get_oid_tree(E1, &E2)
@@
expression E1, E2;
@@
- get_sha1_tree(E1, E2->hash)
+ get_oid_tree(E1, E2)
@@
expression E1, E2;
@@
- get_sha1_blob(E1, E2.hash)
+ get_oid_blob(E1, &E2)
@@
expression E1, E2;
@@
- get_sha1_blob(E1, E2->hash)
+ get_oid_blob(E1, E2)
@@
expression E1, E2, E3, E4;
@@
- get_sha1_with_context(E1, E2, E3.hash, E4)
+ get_oid_with_context(E1, E2, &E3, E4)
@@
expression E1, E2, E3, E4;
@@
- get_sha1_with_context(E1, E2, E3->hash, E4)
+ get_oid_with_context(E1, E2, E3, E4)
Signed-off-by: brian m. carlson <sandals@crustytoothpaste.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-07-14 01:49:28 +02:00
|
|
|
struct object_id *oid)
|
2005-10-03 06:40:51 +02:00
|
|
|
{
|
2012-06-21 07:07:36 +02:00
|
|
|
if (ds->ambiguous)
|
|
|
|
return SHORT_NAME_AMBIGUOUS;
|
2005-10-03 06:40:51 +02:00
|
|
|
|
2012-06-21 07:07:36 +02:00
|
|
|
if (!ds->candidate_exists)
|
2019-01-18 05:19:43 +01:00
|
|
|
return MISSING_OBJECT;
|
2012-06-21 07:07:36 +02:00
|
|
|
|
|
|
|
if (!ds->candidate_checked)
|
|
|
|
/*
|
|
|
|
* If this is the only candidate, there is no point
|
|
|
|
* calling the disambiguation hint callback.
|
|
|
|
*
|
|
|
|
* On the other hand, if the current candidate
|
|
|
|
* replaced an earlier candidate that did _not_ pass
|
|
|
|
* the disambiguation hint callback, then we do have
|
|
|
|
* more than one objects that match the short name
|
|
|
|
* given, so we should make sure this one matches;
|
|
|
|
* otherwise, if we discovered this one and the one
|
|
|
|
* that we previously discarded in the reverse order,
|
|
|
|
* we would end up showing different results in the
|
|
|
|
* same repository!
|
|
|
|
*/
|
|
|
|
ds->candidate_ok = (!ds->disambiguate_fn_used ||
|
2019-04-16 11:33:23 +02:00
|
|
|
ds->fn(ds->repo, &ds->candidate, ds->cb_data));
|
2012-06-21 07:07:36 +02:00
|
|
|
|
|
|
|
if (!ds->candidate_ok)
|
2005-10-12 00:22:48 +02:00
|
|
|
return SHORT_NAME_AMBIGUOUS;
|
2012-06-21 07:07:36 +02:00
|
|
|
|
sha1_name: convert get_sha1* to get_oid*
Now that all the callers of get_sha1 directly or indirectly use struct
object_id, rename the functions starting with get_sha1 to start with
get_oid. Convert the internals in sha1_name.c to use struct object_id
as well, and eliminate explicit length checks where possible. Convert a
use of 40 in get_oid_basic to GIT_SHA1_HEXSZ.
Outside of sha1_name.c and cache.h, this transition was made with the
following semantic patch:
@@
expression E1, E2;
@@
- get_sha1(E1, E2.hash)
+ get_oid(E1, &E2)
@@
expression E1, E2;
@@
- get_sha1(E1, E2->hash)
+ get_oid(E1, E2)
@@
expression E1, E2;
@@
- get_sha1_committish(E1, E2.hash)
+ get_oid_committish(E1, &E2)
@@
expression E1, E2;
@@
- get_sha1_committish(E1, E2->hash)
+ get_oid_committish(E1, E2)
@@
expression E1, E2;
@@
- get_sha1_treeish(E1, E2.hash)
+ get_oid_treeish(E1, &E2)
@@
expression E1, E2;
@@
- get_sha1_treeish(E1, E2->hash)
+ get_oid_treeish(E1, E2)
@@
expression E1, E2;
@@
- get_sha1_commit(E1, E2.hash)
+ get_oid_commit(E1, &E2)
@@
expression E1, E2;
@@
- get_sha1_commit(E1, E2->hash)
+ get_oid_commit(E1, E2)
@@
expression E1, E2;
@@
- get_sha1_tree(E1, E2.hash)
+ get_oid_tree(E1, &E2)
@@
expression E1, E2;
@@
- get_sha1_tree(E1, E2->hash)
+ get_oid_tree(E1, E2)
@@
expression E1, E2;
@@
- get_sha1_blob(E1, E2.hash)
+ get_oid_blob(E1, &E2)
@@
expression E1, E2;
@@
- get_sha1_blob(E1, E2->hash)
+ get_oid_blob(E1, E2)
@@
expression E1, E2, E3, E4;
@@
- get_sha1_with_context(E1, E2, E3.hash, E4)
+ get_oid_with_context(E1, E2, &E3, E4)
@@
expression E1, E2, E3, E4;
@@
- get_sha1_with_context(E1, E2, E3->hash, E4)
+ get_oid_with_context(E1, E2, E3, E4)
Signed-off-by: brian m. carlson <sandals@crustytoothpaste.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-07-14 01:49:28 +02:00
|
|
|
oidcpy(oid, &ds->candidate);
|
2005-08-04 07:15:49 +02:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2019-04-16 11:33:23 +02:00
|
|
|
static int disambiguate_commit_only(struct repository *r,
|
|
|
|
const struct object_id *oid,
|
2023-02-24 07:38:30 +01:00
|
|
|
void *cb_data UNUSED)
|
2012-06-21 08:03:09 +02:00
|
|
|
{
|
2019-04-16 11:33:23 +02:00
|
|
|
int kind = oid_object_info(r, oid, NULL);
|
2012-06-21 08:03:09 +02:00
|
|
|
return kind == OBJ_COMMIT;
|
|
|
|
}
|
|
|
|
|
2019-04-16 11:33:23 +02:00
|
|
|
static int disambiguate_committish_only(struct repository *r,
|
|
|
|
const struct object_id *oid,
|
2023-02-24 07:38:30 +01:00
|
|
|
void *cb_data UNUSED)
|
2012-07-02 19:00:40 +02:00
|
|
|
{
|
|
|
|
struct object *obj;
|
|
|
|
int kind;
|
|
|
|
|
2019-04-16 11:33:23 +02:00
|
|
|
kind = oid_object_info(r, oid, NULL);
|
2012-07-02 19:00:40 +02:00
|
|
|
if (kind == OBJ_COMMIT)
|
|
|
|
return 1;
|
|
|
|
if (kind != OBJ_TAG)
|
2005-10-03 06:40:51 +02:00
|
|
|
return 0;
|
2012-07-02 19:00:40 +02:00
|
|
|
|
|
|
|
/* We need to do this the hard way... */
|
2019-04-16 11:33:23 +02:00
|
|
|
obj = deref_tag(r, parse_object(r, oid), NULL, 0);
|
2012-07-02 19:00:40 +02:00
|
|
|
if (obj && obj->type == OBJ_COMMIT)
|
|
|
|
return 1;
|
2005-08-04 07:15:49 +02:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2019-04-16 11:33:23 +02:00
|
|
|
static int disambiguate_tree_only(struct repository *r,
|
|
|
|
const struct object_id *oid,
|
2023-02-24 07:38:30 +01:00
|
|
|
void *cb_data UNUSED)
|
2005-08-04 07:15:49 +02:00
|
|
|
{
|
2019-04-16 11:33:23 +02:00
|
|
|
int kind = oid_object_info(r, oid, NULL);
|
2012-07-03 08:35:05 +02:00
|
|
|
return kind == OBJ_TREE;
|
|
|
|
}
|
2005-08-04 07:15:49 +02:00
|
|
|
|
2019-04-16 11:33:23 +02:00
|
|
|
static int disambiguate_treeish_only(struct repository *r,
|
|
|
|
const struct object_id *oid,
|
2023-02-24 07:38:30 +01:00
|
|
|
void *cb_data UNUSED)
|
2012-07-03 08:35:05 +02:00
|
|
|
{
|
|
|
|
struct object *obj;
|
|
|
|
int kind;
|
|
|
|
|
2019-04-16 11:33:23 +02:00
|
|
|
kind = oid_object_info(r, oid, NULL);
|
2012-07-03 08:35:05 +02:00
|
|
|
if (kind == OBJ_TREE || kind == OBJ_COMMIT)
|
|
|
|
return 1;
|
|
|
|
if (kind != OBJ_TAG)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
/* We need to do this the hard way... */
|
2019-04-16 11:33:23 +02:00
|
|
|
obj = deref_tag(r, parse_object(r, oid), NULL, 0);
|
2012-07-03 08:35:05 +02:00
|
|
|
if (obj && (obj->type == OBJ_TREE || obj->type == OBJ_COMMIT))
|
|
|
|
return 1;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2019-04-16 11:33:23 +02:00
|
|
|
static int disambiguate_blob_only(struct repository *r,
|
|
|
|
const struct object_id *oid,
|
2023-02-24 07:38:30 +01:00
|
|
|
void *cb_data UNUSED)
|
2012-07-03 08:35:05 +02:00
|
|
|
{
|
2019-04-16 11:33:23 +02:00
|
|
|
int kind = oid_object_info(r, oid, NULL);
|
2012-07-03 08:35:05 +02:00
|
|
|
return kind == OBJ_BLOB;
|
|
|
|
}
|
|
|
|
|
2016-09-27 14:38:01 +02:00
|
|
|
static disambiguate_hint_fn default_disambiguate_hint;
|
|
|
|
|
|
|
|
int set_disambiguate_hint_config(const char *var, const char *value)
|
|
|
|
{
|
|
|
|
static const struct {
|
|
|
|
const char *name;
|
|
|
|
disambiguate_hint_fn fn;
|
|
|
|
} hints[] = {
|
|
|
|
{ "none", NULL },
|
|
|
|
{ "commit", disambiguate_commit_only },
|
|
|
|
{ "committish", disambiguate_committish_only },
|
|
|
|
{ "tree", disambiguate_tree_only },
|
|
|
|
{ "treeish", disambiguate_treeish_only },
|
|
|
|
{ "blob", disambiguate_blob_only }
|
|
|
|
};
|
|
|
|
int i;
|
|
|
|
|
|
|
|
if (!value)
|
|
|
|
return config_error_nonbool(var);
|
|
|
|
|
|
|
|
for (i = 0; i < ARRAY_SIZE(hints); i++) {
|
|
|
|
if (!strcasecmp(value, hints[i].name)) {
|
|
|
|
default_disambiguate_hint = hints[i].fn;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return error("unknown hint type for '%s': %s", var, value);
|
|
|
|
}
|
|
|
|
|
2019-04-16 11:33:23 +02:00
|
|
|
static int init_object_disambiguation(struct repository *r,
|
|
|
|
const char *name, int len,
|
2016-09-26 14:00:04 +02:00
|
|
|
struct disambiguate_state *ds)
|
2005-08-04 07:15:49 +02:00
|
|
|
{
|
2012-07-03 23:21:59 +02:00
|
|
|
int i;
|
2005-08-04 07:15:49 +02:00
|
|
|
|
2018-07-16 03:27:58 +02:00
|
|
|
if (len < MINIMUM_ABBREV || len > the_hash_algo->hexsz)
|
2016-09-26 14:00:04 +02:00
|
|
|
return -1;
|
|
|
|
|
|
|
|
memset(ds, 0, sizeof(*ds));
|
|
|
|
|
2005-09-20 00:16:03 +02:00
|
|
|
for (i = 0; i < len ;i++) {
|
2005-08-04 07:15:49 +02:00
|
|
|
unsigned char c = name[i];
|
|
|
|
unsigned char val;
|
|
|
|
if (c >= '0' && c <= '9')
|
|
|
|
val = c - '0';
|
|
|
|
else if (c >= 'a' && c <= 'f')
|
|
|
|
val = c - 'a' + 10;
|
|
|
|
else if (c >= 'A' && c <='F') {
|
|
|
|
val = c - 'A' + 10;
|
|
|
|
c -= 'A' - 'a';
|
|
|
|
}
|
|
|
|
else
|
|
|
|
return -1;
|
2016-09-26 14:00:04 +02:00
|
|
|
ds->hex_pfx[i] = c;
|
2005-08-04 07:15:49 +02:00
|
|
|
if (!(i & 1))
|
|
|
|
val <<= 4;
|
2017-03-26 18:01:33 +02:00
|
|
|
ds->bin_pfx.hash[i >> 1] |= val;
|
2005-08-04 07:15:49 +02:00
|
|
|
}
|
2016-09-26 14:00:04 +02:00
|
|
|
|
|
|
|
ds->len = len;
|
2016-09-26 14:00:07 +02:00
|
|
|
ds->hex_pfx[len] = '\0';
|
2019-04-16 11:33:23 +02:00
|
|
|
ds->repo = r;
|
|
|
|
prepare_alt_odb(r);
|
2012-07-03 23:21:59 +02:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2022-01-27 06:26:48 +01:00
|
|
|
struct ambiguous_output {
|
|
|
|
const struct disambiguate_state *ds;
|
|
|
|
struct strbuf advice;
|
2022-01-27 06:26:49 +01:00
|
|
|
struct strbuf sb;
|
2022-01-27 06:26:48 +01:00
|
|
|
};
|
|
|
|
|
2017-03-31 03:39:59 +02:00
|
|
|
static int show_ambiguous_object(const struct object_id *oid, void *data)
|
get_short_sha1: list ambiguous objects on error
When the user gives us an ambiguous short sha1, we print an
error and refuse to resolve it. In some cases, the next step
is for them to feed us more characters (e.g., if they were
retyping or cut-and-pasting from a full sha1). But in other
cases, that might be all they have. For example, an old
commit message may have used a 7-character hex that was
unique at the time, but is now ambiguous. Git doesn't
provide any information about the ambiguous objects it
found, so it's hard for the user to find out which one they
probably meant.
This patch teaches get_short_sha1() to list the sha1s of the
objects it found, along with a few bits of information that
may help the user decide which one they meant. Here's what
it looks like on git.git:
$ git rev-parse b2e1
error: short SHA1 b2e1 is ambiguous
hint: The candidates are:
hint: b2e1196 tag v2.8.0-rc1
hint: b2e11d1 tree
hint: b2e1632 commit 2007-11-14 - Merge branch 'bs/maint-commit-options'
hint: b2e1759 blob
hint: b2e18954 blob
hint: b2e1895c blob
fatal: ambiguous argument 'b2e1': unknown revision or path not in the working tree.
Use '--' to separate paths from revisions, like this:
'git <command> [<revision>...] -- [<file>...]'
We show the tagname for tags, and the date and subject for
commits. For trees and blobs, in theory we could dig in the
history to find the paths at which they were present. But
that's very expensive (on the order of 30s for the kernel),
and it's not likely to be all that helpful. Most short
references are to commits, so the useful information is
typically going to be that the object in question _isn't_ a
commit. So it's silly to spend a lot of CPU preemptively
digging up the path; the user can do it themselves if they
really need to.
And of course it's somewhat ironic that we abbreviate the
sha1s in the disambiguation hint. But full sha1s would cause
annoying line wrapping for the commit lines, and presumably
the user is going to just re-issue their command immediately
with the corrected sha1.
We also restrict the list to those that match any
disambiguation hint. E.g.:
$ git rev-parse b2e1:foo
error: short SHA1 b2e1 is ambiguous
hint: The candidates are:
hint: b2e1196 tag v2.8.0-rc1
hint: b2e11d1 tree
hint: b2e1632 commit 2007-11-14 - Merge branch 'bs/maint-commit-options'
fatal: Invalid object name 'b2e1'.
does not bother reporting the blobs, because they cannot
work as a treeish.
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2016-09-26 14:00:36 +02:00
|
|
|
{
|
2022-01-27 06:26:48 +01:00
|
|
|
struct ambiguous_output *state = data;
|
|
|
|
const struct disambiguate_state *ds = state->ds;
|
|
|
|
struct strbuf *advice = &state->advice;
|
2022-01-27 06:26:49 +01:00
|
|
|
struct strbuf *sb = &state->sb;
|
get_short_sha1: list ambiguous objects on error
When the user gives us an ambiguous short sha1, we print an
error and refuse to resolve it. In some cases, the next step
is for them to feed us more characters (e.g., if they were
retyping or cut-and-pasting from a full sha1). But in other
cases, that might be all they have. For example, an old
commit message may have used a 7-character hex that was
unique at the time, but is now ambiguous. Git doesn't
provide any information about the ambiguous objects it
found, so it's hard for the user to find out which one they
probably meant.
This patch teaches get_short_sha1() to list the sha1s of the
objects it found, along with a few bits of information that
may help the user decide which one they meant. Here's what
it looks like on git.git:
$ git rev-parse b2e1
error: short SHA1 b2e1 is ambiguous
hint: The candidates are:
hint: b2e1196 tag v2.8.0-rc1
hint: b2e11d1 tree
hint: b2e1632 commit 2007-11-14 - Merge branch 'bs/maint-commit-options'
hint: b2e1759 blob
hint: b2e18954 blob
hint: b2e1895c blob
fatal: ambiguous argument 'b2e1': unknown revision or path not in the working tree.
Use '--' to separate paths from revisions, like this:
'git <command> [<revision>...] -- [<file>...]'
We show the tagname for tags, and the date and subject for
commits. For trees and blobs, in theory we could dig in the
history to find the paths at which they were present. But
that's very expensive (on the order of 30s for the kernel),
and it's not likely to be all that helpful. Most short
references are to commits, so the useful information is
typically going to be that the object in question _isn't_ a
commit. So it's silly to spend a lot of CPU preemptively
digging up the path; the user can do it themselves if they
really need to.
And of course it's somewhat ironic that we abbreviate the
sha1s in the disambiguation hint. But full sha1s would cause
annoying line wrapping for the commit lines, and presumably
the user is going to just re-issue their command immediately
with the corrected sha1.
We also restrict the list to those that match any
disambiguation hint. E.g.:
$ git rev-parse b2e1:foo
error: short SHA1 b2e1 is ambiguous
hint: The candidates are:
hint: b2e1196 tag v2.8.0-rc1
hint: b2e11d1 tree
hint: b2e1632 commit 2007-11-14 - Merge branch 'bs/maint-commit-options'
fatal: Invalid object name 'b2e1'.
does not bother reporting the blobs, because they cannot
work as a treeish.
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2016-09-26 14:00:36 +02:00
|
|
|
int type;
|
2022-01-27 06:26:46 +01:00
|
|
|
const char *hash;
|
get_short_sha1: list ambiguous objects on error
When the user gives us an ambiguous short sha1, we print an
error and refuse to resolve it. In some cases, the next step
is for them to feed us more characters (e.g., if they were
retyping or cut-and-pasting from a full sha1). But in other
cases, that might be all they have. For example, an old
commit message may have used a 7-character hex that was
unique at the time, but is now ambiguous. Git doesn't
provide any information about the ambiguous objects it
found, so it's hard for the user to find out which one they
probably meant.
This patch teaches get_short_sha1() to list the sha1s of the
objects it found, along with a few bits of information that
may help the user decide which one they meant. Here's what
it looks like on git.git:
$ git rev-parse b2e1
error: short SHA1 b2e1 is ambiguous
hint: The candidates are:
hint: b2e1196 tag v2.8.0-rc1
hint: b2e11d1 tree
hint: b2e1632 commit 2007-11-14 - Merge branch 'bs/maint-commit-options'
hint: b2e1759 blob
hint: b2e18954 blob
hint: b2e1895c blob
fatal: ambiguous argument 'b2e1': unknown revision or path not in the working tree.
Use '--' to separate paths from revisions, like this:
'git <command> [<revision>...] -- [<file>...]'
We show the tagname for tags, and the date and subject for
commits. For trees and blobs, in theory we could dig in the
history to find the paths at which they were present. But
that's very expensive (on the order of 30s for the kernel),
and it's not likely to be all that helpful. Most short
references are to commits, so the useful information is
typically going to be that the object in question _isn't_ a
commit. So it's silly to spend a lot of CPU preemptively
digging up the path; the user can do it themselves if they
really need to.
And of course it's somewhat ironic that we abbreviate the
sha1s in the disambiguation hint. But full sha1s would cause
annoying line wrapping for the commit lines, and presumably
the user is going to just re-issue their command immediately
with the corrected sha1.
We also restrict the list to those that match any
disambiguation hint. E.g.:
$ git rev-parse b2e1:foo
error: short SHA1 b2e1 is ambiguous
hint: The candidates are:
hint: b2e1196 tag v2.8.0-rc1
hint: b2e11d1 tree
hint: b2e1632 commit 2007-11-14 - Merge branch 'bs/maint-commit-options'
fatal: Invalid object name 'b2e1'.
does not bother reporting the blobs, because they cannot
work as a treeish.
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2016-09-26 14:00:36 +02:00
|
|
|
|
2019-04-16 11:33:23 +02:00
|
|
|
if (ds->fn && !ds->fn(ds->repo, oid, ds->cb_data))
|
get_short_sha1: list ambiguous objects on error
When the user gives us an ambiguous short sha1, we print an
error and refuse to resolve it. In some cases, the next step
is for them to feed us more characters (e.g., if they were
retyping or cut-and-pasting from a full sha1). But in other
cases, that might be all they have. For example, an old
commit message may have used a 7-character hex that was
unique at the time, but is now ambiguous. Git doesn't
provide any information about the ambiguous objects it
found, so it's hard for the user to find out which one they
probably meant.
This patch teaches get_short_sha1() to list the sha1s of the
objects it found, along with a few bits of information that
may help the user decide which one they meant. Here's what
it looks like on git.git:
$ git rev-parse b2e1
error: short SHA1 b2e1 is ambiguous
hint: The candidates are:
hint: b2e1196 tag v2.8.0-rc1
hint: b2e11d1 tree
hint: b2e1632 commit 2007-11-14 - Merge branch 'bs/maint-commit-options'
hint: b2e1759 blob
hint: b2e18954 blob
hint: b2e1895c blob
fatal: ambiguous argument 'b2e1': unknown revision or path not in the working tree.
Use '--' to separate paths from revisions, like this:
'git <command> [<revision>...] -- [<file>...]'
We show the tagname for tags, and the date and subject for
commits. For trees and blobs, in theory we could dig in the
history to find the paths at which they were present. But
that's very expensive (on the order of 30s for the kernel),
and it's not likely to be all that helpful. Most short
references are to commits, so the useful information is
typically going to be that the object in question _isn't_ a
commit. So it's silly to spend a lot of CPU preemptively
digging up the path; the user can do it themselves if they
really need to.
And of course it's somewhat ironic that we abbreviate the
sha1s in the disambiguation hint. But full sha1s would cause
annoying line wrapping for the commit lines, and presumably
the user is going to just re-issue their command immediately
with the corrected sha1.
We also restrict the list to those that match any
disambiguation hint. E.g.:
$ git rev-parse b2e1:foo
error: short SHA1 b2e1 is ambiguous
hint: The candidates are:
hint: b2e1196 tag v2.8.0-rc1
hint: b2e11d1 tree
hint: b2e1632 commit 2007-11-14 - Merge branch 'bs/maint-commit-options'
fatal: Invalid object name 'b2e1'.
does not bother reporting the blobs, because they cannot
work as a treeish.
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2016-09-26 14:00:36 +02:00
|
|
|
return 0;
|
|
|
|
|
2022-01-27 06:26:46 +01:00
|
|
|
hash = repo_find_unique_abbrev(ds->repo, oid, DEFAULT_ABBREV);
|
2019-04-16 11:33:23 +02:00
|
|
|
type = oid_object_info(ds->repo, oid, NULL);
|
object-name: explicitly handle OBJ_BAD in show_ambiguous_object()
Amend the "unknown type" handling in the code that displays the
ambiguous object list to assert() that we're either going to get the
"real" object types we can pass to type_name(), or a -1 (OBJ_BAD)
return value from oid_object_info().
See [1] for the current output, and [1] for the commit that added the
"unknown type" handling.
We are never going to get an "unknown type" in the sense of custom
types crafted with "hash-object --literally", since we're not using
the OBJECT_INFO_ALLOW_UNKNOWN_TYPE flag.
If we manage to otherwise unpack such an object without errors we'll
die() in parse_loose_header_extended() called by sort_ambiguous()
before we get to show_ambiguous_object(), as is asserted by the test
added in the preceding commit.
So saying "unknown type" here was always misleading, we really meant
to say that we had a failure parsing the object at all, i.e. that we
had repository corruption. If the problem is only that it's type is
unknown we won't reach this code.
So let's emit a generic "[bad object]" instead. As our tests added in
the preceding commit show, we'll have emitted various "error" output
already in those cases.
We should do better in the truly "unknown type" cases, which we'd need
to handle if we were passing down the OBJECT_INFO_ALLOW_UNKNOWN_TYPE
flag. But let's leave that for some future improvement. In a
subsequent commit I'll improve the output we do show, and not having
to handle the "unknown type" (as in OBJECT_INFO_ALLOW_UNKNOWN_TYPE)
simplifies that change.
1. 5cc044e0257 (get_short_oid: sort ambiguous objects by type,
then SHA-1, 2018-05-10)
2. 1ffa26c461 (get_short_sha1: list ambiguous objects on error,
2016-09-26)
Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2022-01-27 06:26:44 +01:00
|
|
|
|
|
|
|
if (type < 0) {
|
2022-01-27 06:26:46 +01:00
|
|
|
/*
|
|
|
|
* TRANSLATORS: This is a line of ambiguous object
|
|
|
|
* output shown when we cannot look up or parse the
|
|
|
|
* object in question. E.g. "deadbeef [bad object]".
|
|
|
|
*/
|
2022-01-27 06:26:49 +01:00
|
|
|
strbuf_addf(sb, _("%s [bad object]"), hash);
|
object-name: explicitly handle OBJ_BAD in show_ambiguous_object()
Amend the "unknown type" handling in the code that displays the
ambiguous object list to assert() that we're either going to get the
"real" object types we can pass to type_name(), or a -1 (OBJ_BAD)
return value from oid_object_info().
See [1] for the current output, and [1] for the commit that added the
"unknown type" handling.
We are never going to get an "unknown type" in the sense of custom
types crafted with "hash-object --literally", since we're not using
the OBJECT_INFO_ALLOW_UNKNOWN_TYPE flag.
If we manage to otherwise unpack such an object without errors we'll
die() in parse_loose_header_extended() called by sort_ambiguous()
before we get to show_ambiguous_object(), as is asserted by the test
added in the preceding commit.
So saying "unknown type" here was always misleading, we really meant
to say that we had a failure parsing the object at all, i.e. that we
had repository corruption. If the problem is only that it's type is
unknown we won't reach this code.
So let's emit a generic "[bad object]" instead. As our tests added in
the preceding commit show, we'll have emitted various "error" output
already in those cases.
We should do better in the truly "unknown type" cases, which we'd need
to handle if we were passing down the OBJECT_INFO_ALLOW_UNKNOWN_TYPE
flag. But let's leave that for some future improvement. In a
subsequent commit I'll improve the output we do show, and not having
to handle the "unknown type" (as in OBJECT_INFO_ALLOW_UNKNOWN_TYPE)
simplifies that change.
1. 5cc044e0257 (get_short_oid: sort ambiguous objects by type,
then SHA-1, 2018-05-10)
2. 1ffa26c461 (get_short_sha1: list ambiguous objects on error,
2016-09-26)
Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2022-01-27 06:26:44 +01:00
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
|
|
|
|
assert(type == OBJ_TREE || type == OBJ_COMMIT ||
|
|
|
|
type == OBJ_BLOB || type == OBJ_TAG);
|
|
|
|
|
get_short_sha1: list ambiguous objects on error
When the user gives us an ambiguous short sha1, we print an
error and refuse to resolve it. In some cases, the next step
is for them to feed us more characters (e.g., if they were
retyping or cut-and-pasting from a full sha1). But in other
cases, that might be all they have. For example, an old
commit message may have used a 7-character hex that was
unique at the time, but is now ambiguous. Git doesn't
provide any information about the ambiguous objects it
found, so it's hard for the user to find out which one they
probably meant.
This patch teaches get_short_sha1() to list the sha1s of the
objects it found, along with a few bits of information that
may help the user decide which one they meant. Here's what
it looks like on git.git:
$ git rev-parse b2e1
error: short SHA1 b2e1 is ambiguous
hint: The candidates are:
hint: b2e1196 tag v2.8.0-rc1
hint: b2e11d1 tree
hint: b2e1632 commit 2007-11-14 - Merge branch 'bs/maint-commit-options'
hint: b2e1759 blob
hint: b2e18954 blob
hint: b2e1895c blob
fatal: ambiguous argument 'b2e1': unknown revision or path not in the working tree.
Use '--' to separate paths from revisions, like this:
'git <command> [<revision>...] -- [<file>...]'
We show the tagname for tags, and the date and subject for
commits. For trees and blobs, in theory we could dig in the
history to find the paths at which they were present. But
that's very expensive (on the order of 30s for the kernel),
and it's not likely to be all that helpful. Most short
references are to commits, so the useful information is
typically going to be that the object in question _isn't_ a
commit. So it's silly to spend a lot of CPU preemptively
digging up the path; the user can do it themselves if they
really need to.
And of course it's somewhat ironic that we abbreviate the
sha1s in the disambiguation hint. But full sha1s would cause
annoying line wrapping for the commit lines, and presumably
the user is going to just re-issue their command immediately
with the corrected sha1.
We also restrict the list to those that match any
disambiguation hint. E.g.:
$ git rev-parse b2e1:foo
error: short SHA1 b2e1 is ambiguous
hint: The candidates are:
hint: b2e1196 tag v2.8.0-rc1
hint: b2e11d1 tree
hint: b2e1632 commit 2007-11-14 - Merge branch 'bs/maint-commit-options'
fatal: Invalid object name 'b2e1'.
does not bother reporting the blobs, because they cannot
work as a treeish.
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2016-09-26 14:00:36 +02:00
|
|
|
if (type == OBJ_COMMIT) {
|
2022-01-27 06:26:46 +01:00
|
|
|
struct strbuf date = STRBUF_INIT;
|
|
|
|
struct strbuf msg = STRBUF_INIT;
|
2019-04-16 11:33:23 +02:00
|
|
|
struct commit *commit = lookup_commit(ds->repo, oid);
|
2022-01-27 06:26:46 +01:00
|
|
|
|
get_short_sha1: list ambiguous objects on error
When the user gives us an ambiguous short sha1, we print an
error and refuse to resolve it. In some cases, the next step
is for them to feed us more characters (e.g., if they were
retyping or cut-and-pasting from a full sha1). But in other
cases, that might be all they have. For example, an old
commit message may have used a 7-character hex that was
unique at the time, but is now ambiguous. Git doesn't
provide any information about the ambiguous objects it
found, so it's hard for the user to find out which one they
probably meant.
This patch teaches get_short_sha1() to list the sha1s of the
objects it found, along with a few bits of information that
may help the user decide which one they meant. Here's what
it looks like on git.git:
$ git rev-parse b2e1
error: short SHA1 b2e1 is ambiguous
hint: The candidates are:
hint: b2e1196 tag v2.8.0-rc1
hint: b2e11d1 tree
hint: b2e1632 commit 2007-11-14 - Merge branch 'bs/maint-commit-options'
hint: b2e1759 blob
hint: b2e18954 blob
hint: b2e1895c blob
fatal: ambiguous argument 'b2e1': unknown revision or path not in the working tree.
Use '--' to separate paths from revisions, like this:
'git <command> [<revision>...] -- [<file>...]'
We show the tagname for tags, and the date and subject for
commits. For trees and blobs, in theory we could dig in the
history to find the paths at which they were present. But
that's very expensive (on the order of 30s for the kernel),
and it's not likely to be all that helpful. Most short
references are to commits, so the useful information is
typically going to be that the object in question _isn't_ a
commit. So it's silly to spend a lot of CPU preemptively
digging up the path; the user can do it themselves if they
really need to.
And of course it's somewhat ironic that we abbreviate the
sha1s in the disambiguation hint. But full sha1s would cause
annoying line wrapping for the commit lines, and presumably
the user is going to just re-issue their command immediately
with the corrected sha1.
We also restrict the list to those that match any
disambiguation hint. E.g.:
$ git rev-parse b2e1:foo
error: short SHA1 b2e1 is ambiguous
hint: The candidates are:
hint: b2e1196 tag v2.8.0-rc1
hint: b2e11d1 tree
hint: b2e1632 commit 2007-11-14 - Merge branch 'bs/maint-commit-options'
fatal: Invalid object name 'b2e1'.
does not bother reporting the blobs, because they cannot
work as a treeish.
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2016-09-26 14:00:36 +02:00
|
|
|
if (commit) {
|
|
|
|
struct pretty_print_context pp = {0};
|
|
|
|
pp.date_mode.type = DATE_SHORT;
|
2023-03-28 15:58:51 +02:00
|
|
|
repo_format_commit_message(the_repository, commit,
|
|
|
|
"%ad", &date, &pp);
|
|
|
|
repo_format_commit_message(the_repository, commit,
|
|
|
|
"%s", &msg, &pp);
|
get_short_sha1: list ambiguous objects on error
When the user gives us an ambiguous short sha1, we print an
error and refuse to resolve it. In some cases, the next step
is for them to feed us more characters (e.g., if they were
retyping or cut-and-pasting from a full sha1). But in other
cases, that might be all they have. For example, an old
commit message may have used a 7-character hex that was
unique at the time, but is now ambiguous. Git doesn't
provide any information about the ambiguous objects it
found, so it's hard for the user to find out which one they
probably meant.
This patch teaches get_short_sha1() to list the sha1s of the
objects it found, along with a few bits of information that
may help the user decide which one they meant. Here's what
it looks like on git.git:
$ git rev-parse b2e1
error: short SHA1 b2e1 is ambiguous
hint: The candidates are:
hint: b2e1196 tag v2.8.0-rc1
hint: b2e11d1 tree
hint: b2e1632 commit 2007-11-14 - Merge branch 'bs/maint-commit-options'
hint: b2e1759 blob
hint: b2e18954 blob
hint: b2e1895c blob
fatal: ambiguous argument 'b2e1': unknown revision or path not in the working tree.
Use '--' to separate paths from revisions, like this:
'git <command> [<revision>...] -- [<file>...]'
We show the tagname for tags, and the date and subject for
commits. For trees and blobs, in theory we could dig in the
history to find the paths at which they were present. But
that's very expensive (on the order of 30s for the kernel),
and it's not likely to be all that helpful. Most short
references are to commits, so the useful information is
typically going to be that the object in question _isn't_ a
commit. So it's silly to spend a lot of CPU preemptively
digging up the path; the user can do it themselves if they
really need to.
And of course it's somewhat ironic that we abbreviate the
sha1s in the disambiguation hint. But full sha1s would cause
annoying line wrapping for the commit lines, and presumably
the user is going to just re-issue their command immediately
with the corrected sha1.
We also restrict the list to those that match any
disambiguation hint. E.g.:
$ git rev-parse b2e1:foo
error: short SHA1 b2e1 is ambiguous
hint: The candidates are:
hint: b2e1196 tag v2.8.0-rc1
hint: b2e11d1 tree
hint: b2e1632 commit 2007-11-14 - Merge branch 'bs/maint-commit-options'
fatal: Invalid object name 'b2e1'.
does not bother reporting the blobs, because they cannot
work as a treeish.
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2016-09-26 14:00:36 +02:00
|
|
|
}
|
2022-01-27 06:26:46 +01:00
|
|
|
|
|
|
|
/*
|
|
|
|
* TRANSLATORS: This is a line of ambiguous commit
|
|
|
|
* object output. E.g.:
|
|
|
|
*
|
|
|
|
* "deadbeef commit 2021-01-01 - Some Commit Message"
|
|
|
|
*/
|
2022-01-27 06:26:49 +01:00
|
|
|
strbuf_addf(sb, _("%s commit %s - %s"), hash, date.buf,
|
|
|
|
msg.buf);
|
2022-01-27 06:26:46 +01:00
|
|
|
|
|
|
|
strbuf_release(&date);
|
|
|
|
strbuf_release(&msg);
|
get_short_sha1: list ambiguous objects on error
When the user gives us an ambiguous short sha1, we print an
error and refuse to resolve it. In some cases, the next step
is for them to feed us more characters (e.g., if they were
retyping or cut-and-pasting from a full sha1). But in other
cases, that might be all they have. For example, an old
commit message may have used a 7-character hex that was
unique at the time, but is now ambiguous. Git doesn't
provide any information about the ambiguous objects it
found, so it's hard for the user to find out which one they
probably meant.
This patch teaches get_short_sha1() to list the sha1s of the
objects it found, along with a few bits of information that
may help the user decide which one they meant. Here's what
it looks like on git.git:
$ git rev-parse b2e1
error: short SHA1 b2e1 is ambiguous
hint: The candidates are:
hint: b2e1196 tag v2.8.0-rc1
hint: b2e11d1 tree
hint: b2e1632 commit 2007-11-14 - Merge branch 'bs/maint-commit-options'
hint: b2e1759 blob
hint: b2e18954 blob
hint: b2e1895c blob
fatal: ambiguous argument 'b2e1': unknown revision or path not in the working tree.
Use '--' to separate paths from revisions, like this:
'git <command> [<revision>...] -- [<file>...]'
We show the tagname for tags, and the date and subject for
commits. For trees and blobs, in theory we could dig in the
history to find the paths at which they were present. But
that's very expensive (on the order of 30s for the kernel),
and it's not likely to be all that helpful. Most short
references are to commits, so the useful information is
typically going to be that the object in question _isn't_ a
commit. So it's silly to spend a lot of CPU preemptively
digging up the path; the user can do it themselves if they
really need to.
And of course it's somewhat ironic that we abbreviate the
sha1s in the disambiguation hint. But full sha1s would cause
annoying line wrapping for the commit lines, and presumably
the user is going to just re-issue their command immediately
with the corrected sha1.
We also restrict the list to those that match any
disambiguation hint. E.g.:
$ git rev-parse b2e1:foo
error: short SHA1 b2e1 is ambiguous
hint: The candidates are:
hint: b2e1196 tag v2.8.0-rc1
hint: b2e11d1 tree
hint: b2e1632 commit 2007-11-14 - Merge branch 'bs/maint-commit-options'
fatal: Invalid object name 'b2e1'.
does not bother reporting the blobs, because they cannot
work as a treeish.
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2016-09-26 14:00:36 +02:00
|
|
|
} else if (type == OBJ_TAG) {
|
2019-04-16 11:33:23 +02:00
|
|
|
struct tag *tag = lookup_tag(ds->repo, oid);
|
2022-01-27 06:26:46 +01:00
|
|
|
|
|
|
|
if (!parse_tag(tag) && tag->tag) {
|
|
|
|
/*
|
|
|
|
* TRANSLATORS: This is a line of ambiguous
|
|
|
|
* tag object output. E.g.:
|
|
|
|
*
|
2022-01-27 06:26:47 +01:00
|
|
|
* "deadbeef tag 2022-01-01 - Some Tag Message"
|
2022-01-27 06:26:46 +01:00
|
|
|
*
|
2022-01-27 06:26:47 +01:00
|
|
|
* The second argument is the YYYY-MM-DD found
|
|
|
|
* in the tag.
|
|
|
|
*
|
|
|
|
* The third argument is the "tag" string
|
2022-01-27 06:26:46 +01:00
|
|
|
* from object.c.
|
|
|
|
*/
|
2022-01-27 06:26:49 +01:00
|
|
|
strbuf_addf(sb, _("%s tag %s - %s"), hash,
|
2022-01-27 06:26:47 +01:00
|
|
|
show_date(tag->date, 0, DATE_MODE(SHORT)),
|
|
|
|
tag->tag);
|
2022-01-27 06:26:46 +01:00
|
|
|
} else {
|
|
|
|
/*
|
|
|
|
* TRANSLATORS: This is a line of ambiguous
|
|
|
|
* tag object output where we couldn't parse
|
|
|
|
* the tag itself. E.g.:
|
|
|
|
*
|
2022-01-27 06:26:47 +01:00
|
|
|
* "deadbeef [bad tag, could not parse it]"
|
2022-01-27 06:26:46 +01:00
|
|
|
*/
|
2022-01-27 06:26:49 +01:00
|
|
|
strbuf_addf(sb, _("%s [bad tag, could not parse it]"),
|
2022-01-27 06:26:46 +01:00
|
|
|
hash);
|
|
|
|
}
|
|
|
|
} else if (type == OBJ_TREE) {
|
|
|
|
/*
|
|
|
|
* TRANSLATORS: This is a line of ambiguous <type>
|
|
|
|
* object output. E.g. "deadbeef tree".
|
|
|
|
*/
|
2022-01-27 06:26:49 +01:00
|
|
|
strbuf_addf(sb, _("%s tree"), hash);
|
2022-01-27 06:26:46 +01:00
|
|
|
} else if (type == OBJ_BLOB) {
|
|
|
|
/*
|
|
|
|
* TRANSLATORS: This is a line of ambiguous <type>
|
|
|
|
* object output. E.g. "deadbeef blob".
|
|
|
|
*/
|
2022-01-27 06:26:49 +01:00
|
|
|
strbuf_addf(sb, _("%s blob"), hash);
|
get_short_sha1: list ambiguous objects on error
When the user gives us an ambiguous short sha1, we print an
error and refuse to resolve it. In some cases, the next step
is for them to feed us more characters (e.g., if they were
retyping or cut-and-pasting from a full sha1). But in other
cases, that might be all they have. For example, an old
commit message may have used a 7-character hex that was
unique at the time, but is now ambiguous. Git doesn't
provide any information about the ambiguous objects it
found, so it's hard for the user to find out which one they
probably meant.
This patch teaches get_short_sha1() to list the sha1s of the
objects it found, along with a few bits of information that
may help the user decide which one they meant. Here's what
it looks like on git.git:
$ git rev-parse b2e1
error: short SHA1 b2e1 is ambiguous
hint: The candidates are:
hint: b2e1196 tag v2.8.0-rc1
hint: b2e11d1 tree
hint: b2e1632 commit 2007-11-14 - Merge branch 'bs/maint-commit-options'
hint: b2e1759 blob
hint: b2e18954 blob
hint: b2e1895c blob
fatal: ambiguous argument 'b2e1': unknown revision or path not in the working tree.
Use '--' to separate paths from revisions, like this:
'git <command> [<revision>...] -- [<file>...]'
We show the tagname for tags, and the date and subject for
commits. For trees and blobs, in theory we could dig in the
history to find the paths at which they were present. But
that's very expensive (on the order of 30s for the kernel),
and it's not likely to be all that helpful. Most short
references are to commits, so the useful information is
typically going to be that the object in question _isn't_ a
commit. So it's silly to spend a lot of CPU preemptively
digging up the path; the user can do it themselves if they
really need to.
And of course it's somewhat ironic that we abbreviate the
sha1s in the disambiguation hint. But full sha1s would cause
annoying line wrapping for the commit lines, and presumably
the user is going to just re-issue their command immediately
with the corrected sha1.
We also restrict the list to those that match any
disambiguation hint. E.g.:
$ git rev-parse b2e1:foo
error: short SHA1 b2e1 is ambiguous
hint: The candidates are:
hint: b2e1196 tag v2.8.0-rc1
hint: b2e11d1 tree
hint: b2e1632 commit 2007-11-14 - Merge branch 'bs/maint-commit-options'
fatal: Invalid object name 'b2e1'.
does not bother reporting the blobs, because they cannot
work as a treeish.
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2016-09-26 14:00:36 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
object-name: explicitly handle OBJ_BAD in show_ambiguous_object()
Amend the "unknown type" handling in the code that displays the
ambiguous object list to assert() that we're either going to get the
"real" object types we can pass to type_name(), or a -1 (OBJ_BAD)
return value from oid_object_info().
See [1] for the current output, and [1] for the commit that added the
"unknown type" handling.
We are never going to get an "unknown type" in the sense of custom
types crafted with "hash-object --literally", since we're not using
the OBJECT_INFO_ALLOW_UNKNOWN_TYPE flag.
If we manage to otherwise unpack such an object without errors we'll
die() in parse_loose_header_extended() called by sort_ambiguous()
before we get to show_ambiguous_object(), as is asserted by the test
added in the preceding commit.
So saying "unknown type" here was always misleading, we really meant
to say that we had a failure parsing the object at all, i.e. that we
had repository corruption. If the problem is only that it's type is
unknown we won't reach this code.
So let's emit a generic "[bad object]" instead. As our tests added in
the preceding commit show, we'll have emitted various "error" output
already in those cases.
We should do better in the truly "unknown type" cases, which we'd need
to handle if we were passing down the OBJECT_INFO_ALLOW_UNKNOWN_TYPE
flag. But let's leave that for some future improvement. In a
subsequent commit I'll improve the output we do show, and not having
to handle the "unknown type" (as in OBJECT_INFO_ALLOW_UNKNOWN_TYPE)
simplifies that change.
1. 5cc044e0257 (get_short_oid: sort ambiguous objects by type,
then SHA-1, 2018-05-10)
2. 1ffa26c461 (get_short_sha1: list ambiguous objects on error,
2016-09-26)
Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2022-01-27 06:26:44 +01:00
|
|
|
out:
|
2022-01-27 06:26:46 +01:00
|
|
|
/*
|
|
|
|
* TRANSLATORS: This is line item of ambiguous object output
|
|
|
|
* from describe_ambiguous_object() above. For RTL languages
|
|
|
|
* you'll probably want to swap the "%s" and leading " " space
|
|
|
|
* around.
|
|
|
|
*/
|
2022-01-27 06:26:49 +01:00
|
|
|
strbuf_addf(advice, _(" %s\n"), sb->buf);
|
get_short_sha1: list ambiguous objects on error
When the user gives us an ambiguous short sha1, we print an
error and refuse to resolve it. In some cases, the next step
is for them to feed us more characters (e.g., if they were
retyping or cut-and-pasting from a full sha1). But in other
cases, that might be all they have. For example, an old
commit message may have used a 7-character hex that was
unique at the time, but is now ambiguous. Git doesn't
provide any information about the ambiguous objects it
found, so it's hard for the user to find out which one they
probably meant.
This patch teaches get_short_sha1() to list the sha1s of the
objects it found, along with a few bits of information that
may help the user decide which one they meant. Here's what
it looks like on git.git:
$ git rev-parse b2e1
error: short SHA1 b2e1 is ambiguous
hint: The candidates are:
hint: b2e1196 tag v2.8.0-rc1
hint: b2e11d1 tree
hint: b2e1632 commit 2007-11-14 - Merge branch 'bs/maint-commit-options'
hint: b2e1759 blob
hint: b2e18954 blob
hint: b2e1895c blob
fatal: ambiguous argument 'b2e1': unknown revision or path not in the working tree.
Use '--' to separate paths from revisions, like this:
'git <command> [<revision>...] -- [<file>...]'
We show the tagname for tags, and the date and subject for
commits. For trees and blobs, in theory we could dig in the
history to find the paths at which they were present. But
that's very expensive (on the order of 30s for the kernel),
and it's not likely to be all that helpful. Most short
references are to commits, so the useful information is
typically going to be that the object in question _isn't_ a
commit. So it's silly to spend a lot of CPU preemptively
digging up the path; the user can do it themselves if they
really need to.
And of course it's somewhat ironic that we abbreviate the
sha1s in the disambiguation hint. But full sha1s would cause
annoying line wrapping for the commit lines, and presumably
the user is going to just re-issue their command immediately
with the corrected sha1.
We also restrict the list to those that match any
disambiguation hint. E.g.:
$ git rev-parse b2e1:foo
error: short SHA1 b2e1 is ambiguous
hint: The candidates are:
hint: b2e1196 tag v2.8.0-rc1
hint: b2e11d1 tree
hint: b2e1632 commit 2007-11-14 - Merge branch 'bs/maint-commit-options'
fatal: Invalid object name 'b2e1'.
does not bother reporting the blobs, because they cannot
work as a treeish.
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2016-09-26 14:00:36 +02:00
|
|
|
|
2022-01-27 06:26:49 +01:00
|
|
|
strbuf_reset(sb);
|
get_short_sha1: list ambiguous objects on error
When the user gives us an ambiguous short sha1, we print an
error and refuse to resolve it. In some cases, the next step
is for them to feed us more characters (e.g., if they were
retyping or cut-and-pasting from a full sha1). But in other
cases, that might be all they have. For example, an old
commit message may have used a 7-character hex that was
unique at the time, but is now ambiguous. Git doesn't
provide any information about the ambiguous objects it
found, so it's hard for the user to find out which one they
probably meant.
This patch teaches get_short_sha1() to list the sha1s of the
objects it found, along with a few bits of information that
may help the user decide which one they meant. Here's what
it looks like on git.git:
$ git rev-parse b2e1
error: short SHA1 b2e1 is ambiguous
hint: The candidates are:
hint: b2e1196 tag v2.8.0-rc1
hint: b2e11d1 tree
hint: b2e1632 commit 2007-11-14 - Merge branch 'bs/maint-commit-options'
hint: b2e1759 blob
hint: b2e18954 blob
hint: b2e1895c blob
fatal: ambiguous argument 'b2e1': unknown revision or path not in the working tree.
Use '--' to separate paths from revisions, like this:
'git <command> [<revision>...] -- [<file>...]'
We show the tagname for tags, and the date and subject for
commits. For trees and blobs, in theory we could dig in the
history to find the paths at which they were present. But
that's very expensive (on the order of 30s for the kernel),
and it's not likely to be all that helpful. Most short
references are to commits, so the useful information is
typically going to be that the object in question _isn't_ a
commit. So it's silly to spend a lot of CPU preemptively
digging up the path; the user can do it themselves if they
really need to.
And of course it's somewhat ironic that we abbreviate the
sha1s in the disambiguation hint. But full sha1s would cause
annoying line wrapping for the commit lines, and presumably
the user is going to just re-issue their command immediately
with the corrected sha1.
We also restrict the list to those that match any
disambiguation hint. E.g.:
$ git rev-parse b2e1:foo
error: short SHA1 b2e1 is ambiguous
hint: The candidates are:
hint: b2e1196 tag v2.8.0-rc1
hint: b2e11d1 tree
hint: b2e1632 commit 2007-11-14 - Merge branch 'bs/maint-commit-options'
fatal: Invalid object name 'b2e1'.
does not bother reporting the blobs, because they cannot
work as a treeish.
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2016-09-26 14:00:36 +02:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2018-05-10 14:43:01 +02:00
|
|
|
static int collect_ambiguous(const struct object_id *oid, void *data)
|
|
|
|
{
|
|
|
|
oid_array_append(data, oid);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2023-02-24 07:38:30 +01:00
|
|
|
static int repo_collect_ambiguous(struct repository *r UNUSED,
|
2019-04-16 11:33:23 +02:00
|
|
|
const struct object_id *oid,
|
|
|
|
void *data)
|
|
|
|
{
|
|
|
|
return collect_ambiguous(oid, data);
|
|
|
|
}
|
|
|
|
|
2019-08-20 20:49:12 +02:00
|
|
|
static int sort_ambiguous(const void *a, const void *b, void *ctx)
|
get_short_oid: sort ambiguous objects by type, then SHA-1
Change the output emitted when an ambiguous object is encountered so
that we show tags first, then commits, followed by trees, and finally
blobs. Within each type we show objects in hashcmp() order. Before
this change the objects were only ordered by hashcmp().
The reason for doing this is that the output looks better as a result,
e.g. the v2.17.0 tag before this change on "git show e8f2" would
display:
hint: The candidates are:
hint: e8f2093055 tree
hint: e8f21caf94 commit 2013-06-24 - bash prompt: print unique detached HEAD abbreviated object name
hint: e8f21d02f7 blob
hint: e8f21d577c blob
hint: e8f25a3a50 tree
hint: e8f26250fa commit 2017-02-03 - Merge pull request #996 from jeffhostetler/jeffhostetler/register_rename_src
hint: e8f2650052 tag v2.17.0
hint: e8f2867228 blob
hint: e8f28d537c tree
hint: e8f2a35526 blob
hint: e8f2bc0c06 commit 2015-05-10 - Documentation: note behavior for multiple remote.url entries
hint: e8f2cf6ec0 tree
Now we'll instead show:
hint: e8f2650052 tag v2.17.0
hint: e8f21caf94 commit 2013-06-24 - bash prompt: print unique detached HEAD abbreviated object name
hint: e8f26250fa commit 2017-02-03 - Merge pull request #996 from jeffhostetler/jeffhostetler/register_rename_src
hint: e8f2bc0c06 commit 2015-05-10 - Documentation: note behavior for multiple remote.url entries
hint: e8f2093055 tree
hint: e8f25a3a50 tree
hint: e8f28d537c tree
hint: e8f2cf6ec0 tree
hint: e8f21d02f7 blob
hint: e8f21d577c blob
hint: e8f2867228 blob
hint: e8f2a35526 blob
Since we show the commit data in the output that's nicely aligned once
we sort by object type. The decision to show tags before commits is
pretty arbitrary. I don't want to order by object_type since there
tags come last after blobs, which doesn't make sense if we want to
show the most important things first.
I could display them after commits, but it's much less likely that
we'll display a tag, so if there is one it makes sense to show it
prominently at the top.
A note on the implementation: Derrick rightly pointed out[1] that
we're bending over backwards here in get_short_oid() to first
de-duplicate the list, and then emit it, but could simply do it in one
step.
The reason for that is that oid_array_for_each_unique() doesn't
actually require that the array be sorted by oid_array_sort(), it just
needs to be sorted in some order that guarantees that all objects with
the same ID are adjacent to one another, which (barring a hash
collision, which'll be someone else's problem) the sort_ambiguous()
function does.
I agree that would be simpler for this code, and had forgotten why I
initially wrote it like this[2]. But on further reflection I think
it's better to do more work here just so we're not underhandedly using
the oid-array API where we lie about the list being sorted. That would
break any subsequent use of oid_array_lookup() in subtle ways.
I could get around that by hacking the API itself to support this
use-case and documenting it, which I did as a WIP patch in [3], but I
think it's too much code smell just for this one call site. It's
simpler for the API to just introduce a oid_array_for_each() function
to eagerly spew out the list without sorting or de-duplication, and
then do the de-duplication and sorting in two passes.
1. https://public-inbox.org/git/20180501130318.58251-1-dstolee@microsoft.com/
2. https://public-inbox.org/git/876047ze9v.fsf@evledraar.gmail.com/
3. https://public-inbox.org/git/874ljrzctc.fsf@evledraar.gmail.com/
Helped-by: Derrick Stolee <dstolee@microsoft.com>
Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2018-05-10 14:43:02 +02:00
|
|
|
{
|
2019-08-20 20:49:12 +02:00
|
|
|
struct repository *sort_ambiguous_repo = ctx;
|
2019-04-16 11:33:20 +02:00
|
|
|
int a_type = oid_object_info(sort_ambiguous_repo, a, NULL);
|
|
|
|
int b_type = oid_object_info(sort_ambiguous_repo, b, NULL);
|
get_short_oid: sort ambiguous objects by type, then SHA-1
Change the output emitted when an ambiguous object is encountered so
that we show tags first, then commits, followed by trees, and finally
blobs. Within each type we show objects in hashcmp() order. Before
this change the objects were only ordered by hashcmp().
The reason for doing this is that the output looks better as a result,
e.g. the v2.17.0 tag before this change on "git show e8f2" would
display:
hint: The candidates are:
hint: e8f2093055 tree
hint: e8f21caf94 commit 2013-06-24 - bash prompt: print unique detached HEAD abbreviated object name
hint: e8f21d02f7 blob
hint: e8f21d577c blob
hint: e8f25a3a50 tree
hint: e8f26250fa commit 2017-02-03 - Merge pull request #996 from jeffhostetler/jeffhostetler/register_rename_src
hint: e8f2650052 tag v2.17.0
hint: e8f2867228 blob
hint: e8f28d537c tree
hint: e8f2a35526 blob
hint: e8f2bc0c06 commit 2015-05-10 - Documentation: note behavior for multiple remote.url entries
hint: e8f2cf6ec0 tree
Now we'll instead show:
hint: e8f2650052 tag v2.17.0
hint: e8f21caf94 commit 2013-06-24 - bash prompt: print unique detached HEAD abbreviated object name
hint: e8f26250fa commit 2017-02-03 - Merge pull request #996 from jeffhostetler/jeffhostetler/register_rename_src
hint: e8f2bc0c06 commit 2015-05-10 - Documentation: note behavior for multiple remote.url entries
hint: e8f2093055 tree
hint: e8f25a3a50 tree
hint: e8f28d537c tree
hint: e8f2cf6ec0 tree
hint: e8f21d02f7 blob
hint: e8f21d577c blob
hint: e8f2867228 blob
hint: e8f2a35526 blob
Since we show the commit data in the output that's nicely aligned once
we sort by object type. The decision to show tags before commits is
pretty arbitrary. I don't want to order by object_type since there
tags come last after blobs, which doesn't make sense if we want to
show the most important things first.
I could display them after commits, but it's much less likely that
we'll display a tag, so if there is one it makes sense to show it
prominently at the top.
A note on the implementation: Derrick rightly pointed out[1] that
we're bending over backwards here in get_short_oid() to first
de-duplicate the list, and then emit it, but could simply do it in one
step.
The reason for that is that oid_array_for_each_unique() doesn't
actually require that the array be sorted by oid_array_sort(), it just
needs to be sorted in some order that guarantees that all objects with
the same ID are adjacent to one another, which (barring a hash
collision, which'll be someone else's problem) the sort_ambiguous()
function does.
I agree that would be simpler for this code, and had forgotten why I
initially wrote it like this[2]. But on further reflection I think
it's better to do more work here just so we're not underhandedly using
the oid-array API where we lie about the list being sorted. That would
break any subsequent use of oid_array_lookup() in subtle ways.
I could get around that by hacking the API itself to support this
use-case and documenting it, which I did as a WIP patch in [3], but I
think it's too much code smell just for this one call site. It's
simpler for the API to just introduce a oid_array_for_each() function
to eagerly spew out the list without sorting or de-duplication, and
then do the de-duplication and sorting in two passes.
1. https://public-inbox.org/git/20180501130318.58251-1-dstolee@microsoft.com/
2. https://public-inbox.org/git/876047ze9v.fsf@evledraar.gmail.com/
3. https://public-inbox.org/git/874ljrzctc.fsf@evledraar.gmail.com/
Helped-by: Derrick Stolee <dstolee@microsoft.com>
Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2018-05-10 14:43:02 +02:00
|
|
|
int a_type_sort;
|
|
|
|
int b_type_sort;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Sorts by hash within the same object type, just as
|
|
|
|
* oid_array_for_each_unique() would do.
|
|
|
|
*/
|
|
|
|
if (a_type == b_type)
|
|
|
|
return oidcmp(a, b);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Between object types show tags, then commits, and finally
|
|
|
|
* trees and blobs.
|
|
|
|
*
|
|
|
|
* The object_type enum is commit, tree, blob, tag, but we
|
|
|
|
* want tag, commit, tree blob. Cleverly (perhaps too
|
|
|
|
* cleverly) do that with modulus, since the enum assigns 1 to
|
|
|
|
* commit, so tag becomes 0.
|
|
|
|
*/
|
|
|
|
a_type_sort = a_type % 4;
|
|
|
|
b_type_sort = b_type % 4;
|
|
|
|
return a_type_sort > b_type_sort ? 1 : -1;
|
|
|
|
}
|
|
|
|
|
2019-04-16 11:33:20 +02:00
|
|
|
static void sort_ambiguous_oid_array(struct repository *r, struct oid_array *a)
|
|
|
|
{
|
2019-08-20 20:49:12 +02:00
|
|
|
QSORT_S(a->oid, a->nr, sort_ambiguous, r);
|
2019-04-16 11:33:20 +02:00
|
|
|
}
|
|
|
|
|
2019-04-16 11:33:25 +02:00
|
|
|
static enum get_oid_result get_short_oid(struct repository *r,
|
|
|
|
const char *name, int len,
|
2019-01-18 05:19:43 +01:00
|
|
|
struct object_id *oid,
|
|
|
|
unsigned flags)
|
2012-07-03 23:21:59 +02:00
|
|
|
{
|
|
|
|
int status;
|
|
|
|
struct disambiguate_state ds;
|
2017-07-14 01:49:29 +02:00
|
|
|
int quietly = !!(flags & GET_OID_QUIETLY);
|
2012-07-03 23:21:59 +02:00
|
|
|
|
2019-04-16 11:33:25 +02:00
|
|
|
if (init_object_disambiguation(r, name, len, &ds) < 0)
|
2012-07-03 23:21:59 +02:00
|
|
|
return -1;
|
2005-10-03 06:40:51 +02:00
|
|
|
|
2017-07-14 01:49:29 +02:00
|
|
|
if (HAS_MULTI_BITS(flags & GET_OID_DISAMBIGUATORS))
|
2018-05-02 11:38:39 +02:00
|
|
|
BUG("multiple get_short_oid disambiguator flags");
|
2016-09-26 13:59:01 +02:00
|
|
|
|
2017-07-14 01:49:29 +02:00
|
|
|
if (flags & GET_OID_COMMIT)
|
2012-06-21 08:03:09 +02:00
|
|
|
ds.fn = disambiguate_commit_only;
|
2017-07-14 01:49:29 +02:00
|
|
|
else if (flags & GET_OID_COMMITTISH)
|
2012-07-02 19:00:40 +02:00
|
|
|
ds.fn = disambiguate_committish_only;
|
2017-07-14 01:49:29 +02:00
|
|
|
else if (flags & GET_OID_TREE)
|
2012-07-03 08:35:05 +02:00
|
|
|
ds.fn = disambiguate_tree_only;
|
2017-07-14 01:49:29 +02:00
|
|
|
else if (flags & GET_OID_TREEISH)
|
2012-07-03 08:35:05 +02:00
|
|
|
ds.fn = disambiguate_treeish_only;
|
2017-07-14 01:49:29 +02:00
|
|
|
else if (flags & GET_OID_BLOB)
|
2012-07-03 08:35:05 +02:00
|
|
|
ds.fn = disambiguate_blob_only;
|
2016-09-27 14:38:01 +02:00
|
|
|
else
|
|
|
|
ds.fn = default_disambiguate_hint;
|
2012-06-21 08:03:09 +02:00
|
|
|
|
2016-09-26 14:00:04 +02:00
|
|
|
find_short_object_filename(&ds);
|
|
|
|
find_short_packed_object(&ds);
|
sha1_name: convert get_sha1* to get_oid*
Now that all the callers of get_sha1 directly or indirectly use struct
object_id, rename the functions starting with get_sha1 to start with
get_oid. Convert the internals in sha1_name.c to use struct object_id
as well, and eliminate explicit length checks where possible. Convert a
use of 40 in get_oid_basic to GIT_SHA1_HEXSZ.
Outside of sha1_name.c and cache.h, this transition was made with the
following semantic patch:
@@
expression E1, E2;
@@
- get_sha1(E1, E2.hash)
+ get_oid(E1, &E2)
@@
expression E1, E2;
@@
- get_sha1(E1, E2->hash)
+ get_oid(E1, E2)
@@
expression E1, E2;
@@
- get_sha1_committish(E1, E2.hash)
+ get_oid_committish(E1, &E2)
@@
expression E1, E2;
@@
- get_sha1_committish(E1, E2->hash)
+ get_oid_committish(E1, E2)
@@
expression E1, E2;
@@
- get_sha1_treeish(E1, E2.hash)
+ get_oid_treeish(E1, &E2)
@@
expression E1, E2;
@@
- get_sha1_treeish(E1, E2->hash)
+ get_oid_treeish(E1, E2)
@@
expression E1, E2;
@@
- get_sha1_commit(E1, E2.hash)
|