diff --git a/archive-tar.c b/archive-tar.c
index f2a0ed7752..8ae30125f8 100644
--- a/archive-tar.c
+++ b/archive-tar.c
@@ -365,7 +365,7 @@ static struct archiver *find_tar_filter(const char *name, size_t len)
 	int i;
 	for (i = 0; i < nr_tar_filters; i++) {
 		struct archiver *ar = tar_filters[i];
-		if (!strncmp(ar->name, name, len) && !ar->name[len])
+		if (!xstrncmpz(ar->name, name, len))
 			return ar;
 	}
 	return NULL;
diff --git a/builtin/fast-export.c b/builtin/fast-export.c
index f18f0809f9..4693d18cc9 100644
--- a/builtin/fast-export.c
+++ b/builtin/fast-export.c
@@ -136,8 +136,7 @@ static int anonymized_entry_cmp(const void *cmp_data UNUSED,
 	a = container_of(eptr, const struct anonymized_entry, hash);
 	if (keydata) {
 		const struct anonymized_entry_key *key = keydata;
-		int equal = !strncmp(a->orig, key->orig, key->orig_len) &&
-			    !a->orig[key->orig_len];
+		int equal = !xstrncmpz(a->orig, key->orig, key->orig_len);
 		return !equal;
 	}

diff --git a/builtin/merge.c b/builtin/merge.c
index 8f819781cc..935c8a57dd 100644
--- a/builtin/merge.c
+++ b/builtin/merge.c
@@ -192,8 +192,7 @@ static struct strategy *get_strategy(const char *name)
 			int j, found = 0;
 			struct cmdname *ent = main_cmds.names[i];
 			for (j = 0; !found && j < ARRAY_SIZE(all_strategy); j++)
-				if (!strncmp(ent->name, all_strategy[j].name, ent->len)
-						&& !all_strategy[j].name[ent->len])
+				if (!xstrncmpz(all_strategy[j].name, ent->name, ent->len))
 					found = 1;
 			if (!found)
 				add_cmdname(&not_strategies, ent->name, ent->len);
diff --git a/builtin/reflog.c b/builtin/reflog.c
index a5a4099f61..2c3369fca5 100644
--- a/builtin/reflog.c
+++ b/builtin/reflog.c
@@ -96,8 +96,7 @@ static struct reflog_expire_cfg *find_cfg_ent(const char *pattern, size_t len)
 		reflog_expire_cfg_tail = &reflog_expire_cfg;

 	for (ent = reflog_expire_cfg; ent; ent = ent->next)
-		if (!strncmp(ent->pattern, pattern, len) &&
-		    ent->pattern[len] == '\0')
+		if (!xstrncmpz(ent->pattern, pattern, len))
 			return ent;

 	FLEX_ALLOC_MEM(ent, pattern, pattern, len);
diff --git a/contrib/coccinelle/xstrncmpz.cocci b/contrib/coccinelle/xstrncmpz.cocci
new file mode 100644
index 0000000000..ccb39e2bc0
--- /dev/null
+++ b/contrib/coccinelle/xstrncmpz.cocci
@@ -0,0 +1,28 @@
+@@
+expression S, T, L;
+@@
+(
+- strncmp(S, T, L) || S[L]
++ !!xstrncmpz(S, T, L)
+|
+- strncmp(S, T, L) || S[L] != '\0'
++ !!xstrncmpz(S, T, L)
+|
+- strncmp(S, T, L) || T[L]
++ !!xstrncmpz(T, S, L)
+|
+- strncmp(S, T, L) || T[L] != '\0'
++ !!xstrncmpz(T, S, L)
+|
+- !strncmp(S, T, L) && !S[L]
++ !xstrncmpz(S, T, L)
+|
+- !strncmp(S, T, L) && S[L] == '\0'
++ !xstrncmpz(S, T, L)
+|
+- !strncmp(S, T, L) && !T[L]
++ !xstrncmpz(T, S, L)
+|
+- !strncmp(S, T, L) && T[L] == '\0'
++ !xstrncmpz(T, S, L)
+)
diff --git a/convert.c b/convert.c
index a8870baff3..35b25eb3cb 100644
--- a/convert.c
+++ b/convert.c
@@ -1028,7 +1028,7 @@ static int read_convert_config(const char *var, const char *value,
 	if (parse_config_key(var, "filter", &name, &namelen, &key) < 0 || !name)
 		return 0;
 	for (drv = user_convert; drv; drv = drv->next)
-		if (!strncmp(drv->name, name, namelen) && !drv->name[namelen])
+		if (!xstrncmpz(drv->name, name, namelen))
 			break;
 	if (!drv) {
 		CALLOC_ARRAY(drv, 1);
diff --git a/merge-ll.c b/merge-ll.c
index 5ffb045efb..61e0ae5398 100644
--- a/merge-ll.c
+++ b/merge-ll.c
@@ -292,7 +292,7 @@ static int read_merge_config(const char *var, const char *value,
 	 * after seeing merge.<name>.var1.
 	 */
 	for (fn = ll_user_merge; fn; fn = fn->next)
-		if (!strncmp(fn->name, name, namelen) && !fn->name[namelen])
+		if (!xstrncmpz(fn->name, name, namelen))
 			break;
 	if (!fn) {
 		CALLOC_ARRAY(fn, 1);
diff --git a/object.c b/object.c
index 2c61e4c862..e6a1c4d905 100644
--- a/object.c
+++ b/object.c
@@ -47,8 +47,7 @@ int type_from_string_gently(const char *str, ssize_t len, int gentle)
 		len = strlen(str);

 	for (i = 1; i < ARRAY_SIZE(object_type_strings); i++)
-		if (!strncmp(str, object_type_strings[i], len) &&
-		    object_type_strings[i][len] == '\0')
+		if (!xstrncmpz(object_type_strings[i], str, len))
 			return i;

 	if (gentle)
diff --git a/remote.c b/remote.c
index e07b316eac..9090632e96 100644
--- a/remote.c
+++ b/remote.c
@@ -105,7 +105,7 @@ static int remotes_hash_cmp(const void *cmp_data UNUSED,
 	b = container_of(entry_or_key, const struct remote, ent);

 	if (key)
-		return strncmp(a->name, key->str, key->len) || a->name[key->len];
+		return !!xstrncmpz(a->name, key->str, key->len);
 	else
 		return strcmp(a->name, b->name);
 }
@@ -189,8 +189,7 @@ static int branches_hash_cmp(const void *cmp_data UNUSED,
 	b = container_of(entry_or_key, const struct branch, ent);

 	if (key)
-		return strncmp(a->name, key->str, key->len) ||
-		       a->name[key->len];
+		return !!xstrncmpz(a->name, key->str, key->len);
 	else
 		return strcmp(a->name, b->name);
 }
diff --git a/userdiff.c b/userdiff.c
index e399543823..2b1dab2649 100644
--- a/userdiff.c
+++ b/userdiff.c
@@ -323,8 +323,7 @@ static int userdiff_find_by_namelen_cb(struct userdiff_driver *driver,
 {
 	struct find_by_namelen_data *cb_data = priv;

-	if (!strncmp(driver->name, cb_data->name, cb_data->len) &&
-	    !driver->name[cb_data->len]) {
+	if (!xstrncmpz(driver->name, cb_data->name, cb_data->len)) {
 		cb_data->driver = driver;
 		return 1; /* tell the caller to stop iterating */
 	}
