Merge branch 'jk/gc-pre-detach-under-hook' into maint
authorJunio C Hamano <gitster@pobox.com>
Mon, 31 Jul 2017 20:51:05 +0000 (13:51 -0700)
committerJunio C Hamano <gitster@pobox.com>
Mon, 31 Jul 2017 20:51:05 +0000 (13:51 -0700)
We run an early part of "git gc" that deals with refs before
daemonising (and not under lock) even when running a background
auto-gc, which caused multiple gc processes attempting to run the
early part at the same time. This is now prevented by running the
early part also under the GC lock.

* jk/gc-pre-detach-under-hook:
gc: run pre-detach operations under lock

24 files changed:
Documentation/RelNotes/2.13.3.txt
Documentation/RelNotes/2.13.4.txt [new file with mode: 0644]
Documentation/git-rebase.txt
GIT-VERSION-GEN
RelNotes
alias.c
apply.c
builtin/branch.c
builtin/commit.c
compat/cygwin.c [new file with mode: 0644]
compat/cygwin.h [new file with mode: 0644]
config.mak.uname
git-compat-util.h
progress.c
ref-filter.c
reflog-walk.c
sha1_file.c
t/t0060-path-utils.sh
t/t1300-repo-config.sh
t/t1411-reflog-show.sh
t/t3200-branch.sh
t/t3205-branch-color.sh [new file with mode: 0755]
templates/hooks--pre-rebase.sample
unicode_width.h
index 44d9108ce462aa06ed79d7415ff1ecc6580fddde..5d76ad53106b35fb650f2deec6f10edaeb9e2ef6 100644 (file)
@@ -50,4 +50,13 @@ Fixes since v2.13.2
    did not use 'git rev-parse' to formulate the line to look for in
    the certificate correctly.
 
+ * After "git branch --move" of the currently checked out branch, the
+   code to walk the reflog of HEAD via "log -g" and friends
+   incorrectly stopped at the reflog entry that records the renaming
+   of the branch.
+
+ * The rewrite of "git branch --list" using for-each-ref's internals
+   that happened in v2.13 regressed its handling of color.branch.local;
+   this has been fixed.
+
 Also contains various documentation updates and code clean-ups.
diff --git a/Documentation/RelNotes/2.13.4.txt b/Documentation/RelNotes/2.13.4.txt
new file mode 100644 (file)
index 0000000..4f46ef6
--- /dev/null
@@ -0,0 +1,10 @@
+Git v2.13.4 Release Notes
+=========================
+
+Fixes since v2.13.3
+-------------------
+
+ * Update the character width tables.
+
+ * A recent update broke an alias that contained an uppercase letter,
+   which has been fixed.
index 53f4e144444ae7b30ce2634c0f364400927b27d2..652a99062c8820352593f3461f0975cb10f3d6c2 100644 (file)
@@ -675,7 +675,7 @@ on this 'subsystem'.  You might end up with a history like the
 following:
 
 ------------
-    o---o---o---o---o---o---o---o---o  master
+    o---o---o---o---o---o---o---o  master
         \
          o---o---o---o---o  subsystem
                           \
index c26b01f60bf23a3d9c9bae5d40c0abc0d985ccb0..7ba5c25c24211bf5c6f40186dfd523b3fb5ff3c8 100755 (executable)
@@ -1,7 +1,7 @@
 #!/bin/sh
 
 GVF=GIT-VERSION-FILE
-DEF_VER=v2.13.2
+DEF_VER=v2.13.3
 
 LF='
 '
index 6740545fc8d9bf35ce1a6489ce45863800bc3cd9..c5702b3d7b9b72b5e7bf9e2115470307d33da83b 120000 (symlink)
--- a/RelNotes
+++ b/RelNotes
@@ -1 +1 @@
-Documentation/RelNotes/2.13.3.txt
\ No newline at end of file
+Documentation/RelNotes/2.13.4.txt
\ No newline at end of file
diff --git a/alias.c b/alias.c
index 05263046614e10945cb8d81ef3e42e0d5f2c9a2e..caa88e047c3ee1b9fbfdb7bf16bc9e5c74623a6f 100644 (file)
--- a/alias.c
+++ b/alias.c
@@ -10,7 +10,7 @@ static int config_alias_cb(const char *key, const char *value, void *d)
        struct config_alias_data *data = d;
        const char *p;
 
-       if (skip_prefix(key, "alias.", &p) && !strcmp(p, data->alias))
+       if (skip_prefix(key, "alias.", &p) && !strcasecmp(p, data->alias))
                return git_config_string((const char **)&data->v, key, value);
 
        return 0;
diff --git a/apply.c b/apply.c
index 7a9f4c8e0b47437cae25a51b56b08374c55d7255..f8bf0bd9323d1155e9b382eacc8bdae18eb0d2b2 100644 (file)
--- a/apply.c
+++ b/apply.c
@@ -972,13 +972,12 @@ static int gitdiff_verify_name(struct apply_state *state,
        }
 
        if (*name) {
-               int len = strlen(*name);
                char *another;
                if (isnull)
                        return error(_("git apply: bad git-diff - expected /dev/null, got %s on line %d"),
                                     *name, state->linenr);
                another = find_name(state, line, NULL, state->p_value, TERM_TAB);
-               if (!another || memcmp(another, *name, len + 1)) {
+               if (!another || strcmp(another, *name)) {
                        free(another);
                        return error((side == DIFF_NEW_NAME) ?
                            _("git apply: bad git-diff - inconsistent new filename on line %d") :
@@ -986,8 +985,7 @@ static int gitdiff_verify_name(struct apply_state *state,
                }
                free(another);
        } else {
-               /* expect "/dev/null" */
-               if (memcmp("/dev/null", line, 9) || line[9] != '\n')
+               if (!starts_with(line, "/dev/null\n"))
                        return error(_("git apply: bad git-diff - expected /dev/null on line %d"), state->linenr);
        }
 
index 48a513a84dbf6cf2516a10cbcced267369bc747c..a3bd2262b33672d7277553d77a0ac0e1830395d5 100644 (file)
@@ -334,8 +334,11 @@ static char *build_format(struct ref_filter *filter, int maxwidth, const char *r
        struct strbuf local = STRBUF_INIT;
        struct strbuf remote = STRBUF_INIT;
 
-       strbuf_addf(&fmt, "%%(if)%%(HEAD)%%(then)* %s%%(else)  %%(end)",
-                   branch_get_color(BRANCH_COLOR_CURRENT));
+       strbuf_addf(&local, "%%(if)%%(HEAD)%%(then)* %s%%(else)  %s%%(end)",
+                   branch_get_color(BRANCH_COLOR_CURRENT),
+                   branch_get_color(BRANCH_COLOR_LOCAL));
+       strbuf_addf(&remote, "  %s",
+                   branch_get_color(BRANCH_COLOR_REMOTE));
 
        if (filter->verbose) {
                struct strbuf obname = STRBUF_INIT;
@@ -358,17 +361,17 @@ static char *build_format(struct ref_filter *filter, int maxwidth, const char *r
                else
                        strbuf_addf(&local, "%%(if)%%(upstream:track)%%(then)%%(upstream:track) %%(end)%%(contents:subject)");
 
-               strbuf_addf(&remote, "%s%%(align:%d,left)%s%%(refname:lstrip=2)%%(end)%s"
+               strbuf_addf(&remote, "%%(align:%d,left)%s%%(refname:lstrip=2)%%(end)%s"
                            "%%(if)%%(symref)%%(then) -> %%(symref:short)"
                            "%%(else) %s %%(contents:subject)%%(end)",
-                           branch_get_color(BRANCH_COLOR_REMOTE), maxwidth, quote_literal_for_format(remote_prefix),
+                           maxwidth, quote_literal_for_format(remote_prefix),
                            branch_get_color(BRANCH_COLOR_RESET), obname.buf);
                strbuf_release(&obname);
        } else {
                strbuf_addf(&local, "%%(refname:lstrip=2)%s%%(if)%%(symref)%%(then) -> %%(symref:short)%%(end)",
                            branch_get_color(BRANCH_COLOR_RESET));
-               strbuf_addf(&remote, "%s%s%%(refname:lstrip=2)%s%%(if)%%(symref)%%(then) -> %%(symref:short)%%(end)",
-                           branch_get_color(BRANCH_COLOR_REMOTE), quote_literal_for_format(remote_prefix),
+               strbuf_addf(&remote, "%s%%(refname:lstrip=2)%s%%(if)%%(symref)%%(then) -> %%(symref:short)%%(end)",
+                           quote_literal_for_format(remote_prefix),
                            branch_get_color(BRANCH_COLOR_RESET));
        }
 
index 8d1cac0629e7079daeef57ac049c0c7d7549e6d0..aff6bf7aadc6f5209d5f8fc22dfde055a96214c4 100644 (file)
@@ -984,7 +984,7 @@ static int rest_is_empty(struct strbuf *sb, int start)
        int i, eol;
        const char *nl;
 
-       /* Check if the rest is just whitespace and Signed-of-by's. */
+       /* Check if the rest is just whitespace and Signed-off-by's. */
        for (i = start; i < sb->len; i++) {
                nl = memchr(sb->buf + i, '\n', sb->len - i);
                if (nl)
diff --git a/compat/cygwin.c b/compat/cygwin.c
new file mode 100644 (file)
index 0000000..b9862d6
--- /dev/null
@@ -0,0 +1,19 @@
+#include "../git-compat-util.h"
+#include "../cache.h"
+
+int cygwin_offset_1st_component(const char *path)
+{
+       const char *pos = path;
+       /* unc paths */
+       if (is_dir_sep(pos[0]) && is_dir_sep(pos[1])) {
+               /* skip server name */
+               pos = strchr(pos + 2, '/');
+               if (!pos)
+                       return 0; /* Error: malformed unc path */
+
+               do {
+                       pos++;
+               } while (*pos && pos[0] != '/');
+       }
+       return pos + is_dir_sep(*pos) - path;
+}
diff --git a/compat/cygwin.h b/compat/cygwin.h
new file mode 100644 (file)
index 0000000..8e52de4
--- /dev/null
@@ -0,0 +1,2 @@
+int cygwin_offset_1st_component(const char *path);
+#define offset_1st_component cygwin_offset_1st_component
index 192629f1431072f242f10a8528f1853b8bbaddeb..6367cc023d313d50d5c39217cb6858be80a0bae3 100644 (file)
@@ -181,6 +181,7 @@ ifeq ($(uname_O),Cygwin)
        UNRELIABLE_FSTAT = UnfortunatelyYes
        SPARSE_FLAGS = -isystem /usr/include/w32api -Wno-one-bit-signed-bitfield
        OBJECT_CREATION_USES_RENAMES = UnfortunatelyNeedsTo
+       COMPAT_OBJS += compat/cygwin.o
 endif
 ifeq ($(uname_S),FreeBSD)
        NEEDS_LIBICONV = YesPlease
index 199042ac91466783201bdd483bad9f89c78db122..59866d72fa3bb5aff109632b42c7178b24f528bc 100644 (file)
 #include <sys/sysctl.h>
 #endif
 
+#if defined(__CYGWIN__)
+#include "compat/cygwin.h"
+#endif
 #if defined(__MINGW32__)
 /* pull in Windows compatibility stuff */
 #include "compat/mingw.h"
index 29378caa05336efe15cdf2a9473ca6cbe2bcfa14..73e36d4a423067756ccd52af8cdb4cf0f762684b 100644 (file)
@@ -36,6 +36,7 @@ struct progress {
        unsigned delay;
        unsigned delayed_percent_treshold;
        struct throughput *throughput;
+       uint64_t start_ns;
 };
 
 static volatile sig_atomic_t progress_update;
@@ -221,6 +222,7 @@ struct progress *start_progress_delay(const char *title, unsigned total,
        progress->delayed_percent_treshold = percent_treshold;
        progress->delay = delay;
        progress->throughput = NULL;
+       progress->start_ns = getnanotime();
        set_progress_signal();
        return progress;
 }
@@ -247,8 +249,10 @@ void stop_progress_msg(struct progress **p_progress, const char *msg)
                struct throughput *tp = progress->throughput;
 
                if (tp) {
-                       unsigned int rate = !tp->avg_misecs ? 0 :
-                                       tp->avg_bytes / tp->avg_misecs;
+                       uint64_t now_ns = getnanotime();
+                       unsigned int misecs, rate;
+                       misecs = ((now_ns - progress->start_ns) * 4398) >> 32;
+                       rate = tp->curr_total / (misecs ? misecs : 1);
                        throughput_string(&tp->display, tp->curr_total, rate);
                }
                progress_update = 1;
index 2cc7b01277ca8565302eb1648c065ecbb1a25f47..467c0279c9b6370b57080b5f1fcf20bdfd7e451e 100644 (file)
@@ -221,7 +221,7 @@ static void objectname_atom_parser(struct used_atom *atom, const char *arg)
 
 static void refname_atom_parser(struct used_atom *atom, const char *arg)
 {
-       return refname_atom_parser_internal(&atom->u.refname, arg, atom->name);
+       refname_atom_parser_internal(&atom->u.refname, arg, atom->name);
 }
 
 static align_type parse_align_position(const char *s)
index c63eb1a3fd7fa1d6bdca8bacc1781bbf65f41593..ba72020fc349d4ea9f9366ced9af43372980e988 100644 (file)
@@ -38,6 +38,22 @@ static int read_one_reflog(struct object_id *ooid, struct object_id *noid,
        return 0;
 }
 
+static void free_complete_reflog(struct complete_reflogs *array)
+{
+       int i;
+
+       if (!array)
+               return;
+
+       for (i = 0; i < array->nr; i++) {
+               free(array->items[i].email);
+               free(array->items[i].message);
+       }
+       free(array->items);
+       free(array->ref);
+       free(array);
+}
+
 static struct complete_reflogs *read_complete_reflog(const char *ref)
 {
        struct complete_reflogs *reflogs =
@@ -136,6 +152,7 @@ struct reflog_walk_info {
 void init_reflog_walk(struct reflog_walk_info **info)
 {
        *info = xcalloc(1, sizeof(struct reflog_walk_info));
+       (*info)->complete_reflogs.strdup_strings = 1;
 }
 
 int add_reflog_for_walk(struct reflog_walk_info *info,
@@ -188,20 +205,14 @@ int add_reflog_for_walk(struct reflog_walk_info *info,
                        if (ret > 1)
                                free(b);
                        else if (ret == 1) {
-                               if (reflogs) {
-                                       free(reflogs->ref);
-                                       free(reflogs);
-                               }
+                               free_complete_reflog(reflogs);
                                free(branch);
                                branch = b;
                                reflogs = read_complete_reflog(branch);
                        }
                }
                if (!reflogs || reflogs->nr == 0) {
-                       if (reflogs) {
-                               free(reflogs->ref);
-                               free(reflogs);
-                       }
+                       free_complete_reflog(reflogs);
                        free(branch);
                        return -1;
                }
@@ -214,10 +225,6 @@ int add_reflog_for_walk(struct reflog_walk_info *info,
        if (recno < 0) {
                commit_reflog->recno = get_reflog_recno_by_time(reflogs, timestamp);
                if (commit_reflog->recno < 0) {
-                       if (reflogs) {
-                               free(reflogs->ref);
-                               free(reflogs);
-                       }
                        free(commit_reflog);
                        return -1;
                }
@@ -259,6 +266,8 @@ void fake_reflog_parent(struct reflog_walk_info *info, struct commit *commit)
                /* a root commit, but there are still more entries to show */
                reflog = &commit_reflog->reflogs->items[commit_reflog->recno];
                logobj = parse_object(reflog->noid.hash);
+               if (!logobj)
+                       logobj = parse_object(reflog->ooid.hash);
        }
 
        if (!logobj || logobj->type != OBJ_COMMIT) {
index 59a4ed2ed32336b41ab8f3b1d4aca30f045aa084..dd90a785419b851adf97643db9b291ab23b01224 100644 (file)
@@ -1684,14 +1684,14 @@ int git_open_cloexec(const char *name, int flags)
                fd = open(name, flags | o_cloexec);
        }
 
-#if defined(F_GETFL) && defined(F_SETFL) && defined(FD_CLOEXEC)
+#if defined(F_GETFD) && defined(F_SETFD) && defined(FD_CLOEXEC)
        {
                static int fd_cloexec = FD_CLOEXEC;
 
                if (!o_cloexec && 0 <= fd && fd_cloexec) {
                        /* Opened w/o O_CLOEXEC?  try with fcntl(2) to add it */
-                       int flags = fcntl(fd, F_GETFL);
-                       if (fcntl(fd, F_SETFL, flags | fd_cloexec))
+                       int flags = fcntl(fd, F_GETFD);
+                       if (fcntl(fd, F_SETFD, flags | fd_cloexec))
                                fd_cloexec = 0;
                }
        }
index 444b5a4df801975cf4f96f8193cb04ac91af3e4d..7ea2bb515bd80cc026a18dbfdf4a66cb77d27f20 100755 (executable)
@@ -70,6 +70,8 @@ ancestor() {
 case $(uname -s) in
 *MINGW*)
        ;;
+*CYGWIN*)
+       ;;
 *)
        test_set_prereq POSIX
        ;;
index a37ef0422212eafdae4b4c0fae9e28d4a183117f..364a537000bbbdd43047bd3f9c52c950a96dcbda 100755 (executable)
@@ -1075,6 +1075,13 @@ test_expect_success 'git -c works with aliases of builtins' '
        test_cmp expect actual
 '
 
+test_expect_success 'aliases can be CamelCased' '
+       test_config alias.CamelCased "rev-parse HEAD" &&
+       git CamelCased >out &&
+       git rev-parse HEAD >expect &&
+       test_cmp expect out
+'
+
 test_expect_success 'git -c does not split values on equals' '
        echo "value with = in it" >expect &&
        git -c core.foo="value with = in it" config core.foo >actual &&
index 6ac7734d79be21a82feeadff10064bb4ca7ad47b..b9cb76654bd6cf0b7a910ec4c935c38a5f3bf9bc 100755 (executable)
@@ -171,4 +171,14 @@ test_expect_success 'reflog exists works' '
        ! git reflog exists refs/heads/nonexistent
 '
 
+# The behavior with two reflogs is buggy and the output is in flux; for now
+# we're just checking that the program works at all without segfaulting.
+test_expect_success 'showing multiple reflogs works' '
+       git log -g HEAD HEAD >actual
+'
+
+test_expect_success 'showing multiple reflogs with an old date' '
+       git log -g HEAD@{1979-01-01} HEAD >actual
+'
+
 test_done
index 48d152b9a9519e00227a0877631d643ecf38e687..dd37ac47c5e16bc8df39bcc14e1a2861ab556374 100755 (executable)
@@ -162,6 +162,17 @@ test_expect_success 'git branch -M baz bam should add entries to .git/logs/HEAD'
        grep "^0\{40\}.*$msg$" .git/logs/HEAD
 '
 
+test_expect_success 'resulting reflog can be shown by log -g' '
+       oid=$(git rev-parse HEAD) &&
+       cat >expect <<-EOF &&
+       HEAD@{0} $oid $msg
+       HEAD@{1} $oid $msg
+       HEAD@{2} $oid checkout: moving from foo to baz
+       EOF
+       git log -g --format="%gd %H %gs" -3 HEAD >actual &&
+       test_cmp expect actual
+'
+
 test_expect_success 'git branch -M baz bam should succeed when baz is checked out as linked working tree' '
        git checkout master &&
        git worktree add -b baz bazdir &&
diff --git a/t/t3205-branch-color.sh b/t/t3205-branch-color.sh
new file mode 100755 (executable)
index 0000000..9343550
--- /dev/null
@@ -0,0 +1,44 @@
+#!/bin/sh
+
+test_description='basic branch output coloring'
+. ./test-lib.sh
+
+test_expect_success 'set up some sample branches' '
+       test_commit foo &&
+       git update-ref refs/remotes/origin/master HEAD &&
+       git update-ref refs/heads/other HEAD
+'
+
+# choose non-default colors to make sure config
+# is taking effect
+test_expect_success 'set up some color config' '
+       git config color.branch always &&
+       git config color.branch.local blue &&
+       git config color.branch.remote yellow &&
+       git config color.branch.current cyan
+'
+
+test_expect_success 'regular output shows colors' '
+       cat >expect <<-\EOF &&
+       * <CYAN>master<RESET>
+         <BLUE>other<RESET>
+         <YELLOW>remotes/origin/master<RESET>
+       EOF
+       git branch -a >actual.raw &&
+       test_decode_color <actual.raw >actual &&
+       test_cmp expect actual
+'
+
+test_expect_success 'verbose output shows colors' '
+       oid=$(git rev-parse --short HEAD) &&
+       cat >expect <<-EOF &&
+       * <CYAN>master               <RESET> $oid foo
+         <BLUE>other                <RESET> $oid foo
+         <YELLOW>remotes/origin/master<RESET> $oid foo
+       EOF
+       git branch -v -a >actual.raw &&
+       test_decode_color <actual.raw >actual &&
+       test_cmp expect actual
+'
+
+test_done
index 053f1111c0d734c057e895cdc992188104cc4f84..b7f81c198e22e4ce578a6148fa3346becabbfb3b 100755 (executable)
@@ -88,9 +88,7 @@ else
        exit 1
 fi
 
-exit 0
-
-################################################################
+<<\DOC_END
 
 This sample hook safeguards topic branches that have been
 published from being rewound.
@@ -167,3 +165,5 @@ To compute (2):
        git rev-list master..topic
 
        if this is empty, it is fully merged to "master".
+
+DOC_END
index 02207be4fc47537168d1b1a7d1455af7e4c0df60..6dee2c77cebdd93dbc357ab3427175ec291c2310 100644 (file)
@@ -51,6 +51,7 @@ static const struct interval zero_width[] = {
 { 0x0AC7, 0x0AC8 },
 { 0x0ACD, 0x0ACD },
 { 0x0AE2, 0x0AE3 },
+{ 0x0AFA, 0x0AFF },
 { 0x0B01, 0x0B01 },
 { 0x0B3C, 0x0B3C },
 { 0x0B3F, 0x0B3F },
@@ -73,7 +74,8 @@ static const struct interval zero_width[] = {
 { 0x0CC6, 0x0CC6 },
 { 0x0CCC, 0x0CCD },
 { 0x0CE2, 0x0CE3 },
-{ 0x0D01, 0x0D01 },
+{ 0x0D00, 0x0D01 },
+{ 0x0D3B, 0x0D3C },
 { 0x0D41, 0x0D44 },
 { 0x0D4D, 0x0D4D },
 { 0x0D62, 0x0D63 },
@@ -158,7 +160,7 @@ static const struct interval zero_width[] = {
 { 0x1CED, 0x1CED },
 { 0x1CF4, 0x1CF4 },
 { 0x1CF8, 0x1CF9 },
-{ 0x1DC0, 0x1DF5 },
+{ 0x1DC0, 0x1DF9 },
 { 0x1DFB, 0x1DFF },
 { 0x200B, 0x200F },
 { 0x202A, 0x202E },
@@ -262,6 +264,15 @@ static const struct interval zero_width[] = {
 { 0x1171D, 0x1171F },
 { 0x11722, 0x11725 },
 { 0x11727, 0x1172B },
+{ 0x11A01, 0x11A06 },
+{ 0x11A09, 0x11A0A },
+{ 0x11A33, 0x11A38 },
+{ 0x11A3B, 0x11A3E },
+{ 0x11A47, 0x11A47 },
+{ 0x11A51, 0x11A56 },
+{ 0x11A59, 0x11A5B },
+{ 0x11A8A, 0x11A96 },
+{ 0x11A98, 0x11A99 },
 { 0x11C30, 0x11C36 },
 { 0x11C38, 0x11C3D },
 { 0x11C3F, 0x11C3F },
@@ -269,6 +280,11 @@ static const struct interval zero_width[] = {
 { 0x11CAA, 0x11CB0 },
 { 0x11CB2, 0x11CB3 },
 { 0x11CB5, 0x11CB6 },
+{ 0x11D31, 0x11D36 },
+{ 0x11D3A, 0x11D3A },
+{ 0x11D3C, 0x11D3D },
+{ 0x11D3F, 0x11D45 },
+{ 0x11D47, 0x11D47 },
 { 0x16AF0, 0x16AF4 },
 { 0x16B30, 0x16B36 },
 { 0x16F8F, 0x16F92 },
@@ -339,7 +355,7 @@ static const struct interval double_width[] = {
 { 0x3000, 0x303E },
 { 0x3041, 0x3096 },
 { 0x3099, 0x30FF },
-{ 0x3105, 0x312D },
+{ 0x3105, 0x312E },
 { 0x3131, 0x318E },
 { 0x3190, 0x31BA },
 { 0x31C0, 0x31E3 },
@@ -358,10 +374,11 @@ static const struct interval double_width[] = {
 { 0xFE68, 0xFE6B },
 { 0xFF01, 0xFF60 },
 { 0xFFE0, 0xFFE6 },
-{ 0x16FE0, 0x16FE0 },
+{ 0x16FE0, 0x16FE1 },
 { 0x17000, 0x187EC },
 { 0x18800, 0x18AF2 },
-{ 0x1B000, 0x1B001 },
+{ 0x1B000, 0x1B11E },
+{ 0x1B170, 0x1B2FB },
 { 0x1F004, 0x1F004 },
 { 0x1F0CF, 0x1F0CF },
 { 0x1F18E, 0x1F18E },
@@ -370,6 +387,7 @@ static const struct interval double_width[] = {
 { 0x1F210, 0x1F23B },
 { 0x1F240, 0x1F248 },
 { 0x1F250, 0x1F251 },
+{ 0x1F260, 0x1F265 },
 { 0x1F300, 0x1F320 },
 { 0x1F32D, 0x1F335 },
 { 0x1F337, 0x1F37C },
@@ -392,15 +410,13 @@ static const struct interval double_width[] = {
 { 0x1F6CC, 0x1F6CC },
 { 0x1F6D0, 0x1F6D2 },
 { 0x1F6EB, 0x1F6EC },
-{ 0x1F6F4, 0x1F6F6 },
-{ 0x1F910, 0x1F91E },
-{ 0x1F920, 0x1F927 },
-{ 0x1F930, 0x1F930 },
-{ 0x1F933, 0x1F93E },
-{ 0x1F940, 0x1F94B },
-{ 0x1F950, 0x1F95E },
-{ 0x1F980, 0x1F991 },
+{ 0x1F6F4, 0x1F6F8 },
+{ 0x1F910, 0x1F93E },
+{ 0x1F940, 0x1F94C },
+{ 0x1F950, 0x1F96B },
+{ 0x1F980, 0x1F997 },
 { 0x1F9C0, 0x1F9C0 },
+{ 0x1F9D0, 0x1F9E6 },
 { 0x20000, 0x2FFFD },
 { 0x30000, 0x3FFFD }
 };