core.abbrevguard: Ensure short object names stay unique a bit longer
authorJunio C Hamano <gitster@pobox.com>
Thu, 28 Oct 2010 21:39:13 +0000 (14:39 -0700)
committerJunio C Hamano <gitster@pobox.com>
Fri, 29 Oct 2010 00:37:35 +0000 (17:37 -0700)
Even though git makes sure that it uses enough hexdigits to show an
abbreviated object name unambiguously, as more objects are added to the
repository over time, a short name that used to be unique will stop being
unique.  Git uses this many extra hexdigits that are more than necessary
to make the object name currently unique, in the hope that its output will
stay unique a bit longer.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
Documentation/config.txt
cache.h
config.c
environment.c
sha1_name.c

index 538ebb5e2ecc58f1ddcb7adb44ded3b027555ec2..6994338c905460da63d5266af3a9ea6af60ec636 100644 (file)
@@ -374,6 +374,15 @@ core.warnAmbiguousRefs::
        If true, git will warn you if the ref name you passed it is ambiguous
        and might match multiple refs in the .git/refs/ tree. True by default.
 
+core.abbrevguard::
+       Even though git makes sure that it uses enough hexdigits to show
+       an abbreviated object name unambiguously, as more objects are
+       added to the repository over time, a short name that used to be
+       unique will stop being unique.  Git uses this many extra hexdigits
+       that are more than necessary to make the object name currently
+       unique, in the hope that its output will stay unique a bit longer.
+       Defaults to 0.
+
 core.compression::
        An integer -1..9, indicating a default compression level.
        -1 is the zlib default. 0 means no compression,
diff --git a/cache.h b/cache.h
index 33decd942d4985c8efc1c75fd3fa2f4adf4a56ca..931fb597ee53be6bd8272025988da2be36b62fa3 100644 (file)
--- a/cache.h
+++ b/cache.h
@@ -545,6 +545,7 @@ extern int assume_unchanged;
 extern int prefer_symlink_refs;
 extern int log_all_ref_updates;
 extern int warn_ambiguous_refs;
+extern int unique_abbrev_extra_length;
 extern int shared_repository;
 extern const char *apply_default_whitespace;
 extern const char *apply_default_ignorewhitespace;
index 4b0a82040e7982ab936ed52b2bb3405bc85b80f8..1aa72c2c41719327b62805a38703a124da6d30be 100644 (file)
--- a/config.c
+++ b/config.c
@@ -489,6 +489,13 @@ static int git_default_core_config(const char *var, const char *value)
                return 0;
        }
 
+       if (!strcmp(var, "core.abbrevguard")) {
+               unique_abbrev_extra_length = git_config_int(var, value);
+               if (unique_abbrev_extra_length < 0)
+                       unique_abbrev_extra_length = 0;
+               return 0;
+       }
+
        if (!strcmp(var, "core.bare")) {
                is_bare_repository_cfg = git_config_bool(var, value);
                return 0;
index de5581fe51d532231b0121bd2ef2e46669015bda..92e16b19b22ac6a973b3f7a9eab834a4d596b566 100644 (file)
@@ -21,6 +21,7 @@ int prefer_symlink_refs;
 int is_bare_repository_cfg = -1; /* unspecified */
 int log_all_ref_updates = -1; /* unspecified */
 int warn_ambiguous_refs = 1;
+int unique_abbrev_extra_length;
 int repository_format_version;
 const char *git_commit_encoding;
 const char *git_log_output_encoding;
index 484081de82928108a23a714a76ea88693e56bdd1..4a226adeceaff62f8d10e905149a05ef3c2d894c 100644 (file)
@@ -206,7 +206,9 @@ const char *find_unique_abbrev(const unsigned char *sha1, int len)
                if (exists
                    ? !status
                    : status == SHORT_NAME_NOT_FOUND) {
-                       hex[len] = 0;
+                       int cut_at = len + unique_abbrev_extra_length;
+                       cut_at = (cut_at < 40) ? cut_at : 40;
+                       hex[cut_at] = 0;
                        return hex;
                }
                len++;