From: Junio C Hamano Date: Sat, 4 Dec 2010 00:13:06 +0000 (-0800) Subject: Merge branch 'jn/thinner-wrapper' X-Git-Tag: v1.7.4-rc0~89 X-Git-Url: https://git.lorimer.id.au/gitweb.git/diff_plain/39f04dbaacbb21864547c8cf087697469666d21e?ds=inline;hp=-c Merge branch 'jn/thinner-wrapper' * jn/thinner-wrapper: Remove pack file handling dependency from wrapper.o pack-objects: mark file-local variable static wrapper: give zlib wrappers their own translation unit strbuf: move strbuf_branchname to sha1_name.c path helpers: move git_mkstemp* to wrapper.c wrapper: move odb_* to environment.c wrapper: move xmmap() to sha1_file.c --- 39f04dbaacbb21864547c8cf087697469666d21e diff --combined Makefile index 29ebe70599,a8ba33635d..7a5fb699d1 --- a/Makefile +++ b/Makefile @@@ -70,11 -70,6 +70,11 @@@ all: # # Define NO_STRTOK_R if you don't have strtok_r in the C library. # +# Define NO_FNMATCH if you don't have fnmatch in the C library. +# +# Define NO_FNMATCH_CASEFOLD if your fnmatch function doesn't have the +# FNM_CASEFOLD GNU extension. +# # Define NO_LIBGEN_H if you don't have libgen.h. # # Define NEEDS_LIBGEN if your libgen needs -lgen when linking @@@ -406,7 -401,6 +406,7 @@@ EXTRA_PROGRAMS # ... and all the rest that could be moved out of bindir to gitexecdir PROGRAMS += $(EXTRA_PROGRAMS) +PROGRAM_OBJS += daemon.o PROGRAM_OBJS += fast-import.o PROGRAM_OBJS += imap-send.o PROGRAM_OBJS += shell.o @@@ -502,8 -496,6 +502,8 @@@ LIB_H += compat/bswap. LIB_H += compat/cygwin.h LIB_H += compat/mingw.h LIB_H += compat/win32/pthread.h +LIB_H += compat/win32/syslog.h +LIB_H += compat/win32/sys/poll.h LIB_H += csum-file.h LIB_H += decorate.h LIB_H += delta.h @@@ -670,6 -662,7 +670,7 @@@ LIB_OBJS += write_or_die. LIB_OBJS += ws.o LIB_OBJS += wt-status.o LIB_OBJS += xdiff-interface.o + LIB_OBJS += zlib.o BUILTIN_OBJS += builtin/add.o BUILTIN_OBJS += builtin/annotate.o @@@ -854,7 -847,6 +855,7 @@@ ifeq ($(uname_S),SunOS NO_MKDTEMP = YesPlease NO_MKSTEMPS = YesPlease NO_REGEX = YesPlease + NO_FNMATCH_CASEFOLD = YesPlease ifeq ($(uname_R),5.6) SOCKLEN_T = int NO_HSTRERROR = YesPlease @@@ -1061,7 -1053,6 +1062,7 @@@ ifeq ($(uname_S),Windows NO_STRCASESTR = YesPlease NO_STRLCPY = YesPlease NO_STRTOK_R = YesPlease + NO_FNMATCH = YesPlease NO_MEMMEM = YesPlease # NEEDS_LIBICONV = YesPlease NO_ICONV = YesPlease @@@ -1074,6 -1065,7 +1075,6 @@@ NO_SVN_TESTS = YesPlease NO_PERL_MAKEMAKER = YesPlease RUNTIME_PREFIX = YesPlease - NO_POSIX_ONLY_PROGRAMS = YesPlease NO_ST_BLOCKS_IN_STRUCT_STAT = YesPlease NO_NSEC = YesPlease USE_WIN32_MMAP = YesPlease @@@ -1084,15 -1076,14 +1085,15 @@@ NO_CURL = YesPlease NO_PYTHON = YesPlease BLK_SHA1 = YesPlease + NO_POSIX_GOODIES = UnfortunatelyYes NATIVE_CRLF = YesPlease CC = compat/vcbuild/scripts/clink.pl AR = compat/vcbuild/scripts/lib.pl CFLAGS = BASIC_CFLAGS = -nologo -I. -I../zlib -Icompat/vcbuild -Icompat/vcbuild/include -DWIN32 -D_CONSOLE -DHAVE_STRING_H -D_CRT_SECURE_NO_WARNINGS -D_CRT_NONSTDC_NO_DEPRECATE - COMPAT_OBJS = compat/msvc.o compat/fnmatch/fnmatch.o compat/winansi.o compat/win32/pthread.o - COMPAT_CFLAGS = -D__USE_MINGW_ACCESS -DNOGDI -DHAVE_STRING_H -DHAVE_ALLOCA_H -Icompat -Icompat/fnmatch -Icompat/regex -Icompat/fnmatch -Icompat/win32 -DSTRIP_EXTENSION=\".exe\" + COMPAT_OBJS = compat/msvc.o compat/winansi.o compat/win32/pthread.o compat/win32/syslog.o compat/win32/sys/poll.o + COMPAT_CFLAGS = -D__USE_MINGW_ACCESS -DNOGDI -DHAVE_STRING_H -DHAVE_ALLOCA_H -Icompat -Icompat/regex -Icompat/win32 -DSTRIP_EXTENSION=\".exe\" BASIC_LDFLAGS = -IGNORE:4217 -IGNORE:4049 -NOLOGO -SUBSYSTEM:CONSOLE -NODEFAULTLIB:MSVCRT.lib EXTLIBS = advapi32.lib shell32.lib wininet.lib ws2_32.lib PTHREAD_LIBS = @@@ -1106,25 -1097,6 +1107,25 @@@ els endif X = .exe endif +ifeq ($(uname_S),Interix) + NO_SYS_POLL_H = YesPlease + NO_INTTYPES_H = YesPlease + NO_INITGROUPS = YesPlease + NO_IPV6 = YesPlease + NO_MEMMEM = YesPlease + NO_MKDTEMP = YesPlease + NO_STRTOUMAX = YesPlease + NO_NSEC = YesPlease + NO_MKSTEMPS = YesPlease + ifeq ($(uname_R),3.5) + NO_INET_NTOP = YesPlease + NO_INET_PTON = YesPlease + endif + ifeq ($(uname_R),5.2) + NO_INET_NTOP = YesPlease + NO_INET_PTON = YesPlease + endif +endif ifneq (,$(findstring MINGW,$(uname_S))) pathsep = ; NO_PREAD = YesPlease @@@ -1136,7 -1108,6 +1137,7 @@@ NO_STRCASESTR = YesPlease NO_STRLCPY = YesPlease NO_STRTOK_R = YesPlease + NO_FNMATCH = YesPlease NO_MEMMEM = YesPlease NEEDS_LIBICONV = YesPlease OLD_ICONV = YesPlease @@@ -1147,6 -1118,7 +1148,6 @@@ NO_SVN_TESTS = YesPlease NO_PERL_MAKEMAKER = YesPlease RUNTIME_PREFIX = YesPlease - NO_POSIX_ONLY_PROGRAMS = YesPlease NO_ST_BLOCKS_IN_STRUCT_STAT = YesPlease NO_NSEC = YesPlease USE_WIN32_MMAP = YesPlease @@@ -1157,14 -1129,10 +1158,14 @@@ NO_PYTHON = YesPlease BLK_SHA1 = YesPlease ETAGS_TARGET = ETAGS - COMPAT_CFLAGS += -D__USE_MINGW_ACCESS -DNOGDI -Icompat -Icompat/fnmatch -Icompat/win32 + NO_INET_PTON = YesPlease + NO_INET_NTOP = YesPlease + NO_POSIX_GOODIES = UnfortunatelyYes + COMPAT_CFLAGS += -D__USE_MINGW_ACCESS -DNOGDI -Icompat -Icompat/win32 COMPAT_CFLAGS += -DSTRIP_EXTENSION=\".exe\" - COMPAT_OBJS += compat/mingw.o compat/fnmatch/fnmatch.o compat/winansi.o \ - compat/win32/pthread.o + COMPAT_OBJS += compat/mingw.o compat/winansi.o \ + compat/win32/pthread.o compat/win32/syslog.o \ + compat/win32/sys/poll.o EXTLIBS += -lws2_32 PTHREAD_LIBS = X = .exe @@@ -1279,6 -1247,9 +1280,6 @@@ ifdef ZLIB_PAT endif EXTLIBS += -lz -ifndef NO_POSIX_ONLY_PROGRAMS - PROGRAM_OBJS += daemon.o -endif ifndef NO_OPENSSL OPENSSL_LIBSSL = -lssl ifdef OPENSSLDIR @@@ -1372,17 -1343,6 +1373,17 @@@ ifdef NO_STRTOK_ COMPAT_CFLAGS += -DNO_STRTOK_R COMPAT_OBJS += compat/strtok_r.o endif +ifdef NO_FNMATCH + COMPAT_CFLAGS += -Icompat/fnmatch + COMPAT_CFLAGS += -DNO_FNMATCH + COMPAT_OBJS += compat/fnmatch/fnmatch.o +else +ifdef NO_FNMATCH_CASEFOLD + COMPAT_CFLAGS += -Icompat/fnmatch + COMPAT_CFLAGS += -DNO_FNMATCH_CASEFOLD + COMPAT_OBJS += compat/fnmatch/fnmatch.o +endif +endif ifdef NO_SETENV COMPAT_CFLAGS += -DNO_SETENV COMPAT_OBJS += compat/setenv.o @@@ -1401,15 -1361,6 +1402,15 @@@ endi ifdef NO_SYS_SELECT_H BASIC_CFLAGS += -DNO_SYS_SELECT_H endif +ifdef NO_SYS_POLL_H + BASIC_CFLAGS += -DNO_SYS_POLL_H +endif +ifdef NO_INTTYPES_H + BASIC_CFLAGS += -DNO_INTTYPES_H +endif +ifdef NO_INITGROUPS + BASIC_CFLAGS += -DNO_INITGROUPS +endif ifdef NO_MMAP COMPAT_CFLAGS += -DNO_MMAP COMPAT_OBJS += compat/mmap.o @@@ -1447,11 -1398,9 +1448,11 @@@ endi endif ifdef NO_INET_NTOP LIB_OBJS += compat/inet_ntop.o + BASIC_CFLAGS += -DNO_INET_NTOP endif ifdef NO_INET_PTON LIB_OBJS += compat/inet_pton.o + BASIC_CFLAGS += -DNO_INET_PTON endif ifdef NO_ICONV @@@ -1466,10 -1415,6 +1467,10 @@@ ifdef NO_DEFLATE_BOUN BASIC_CFLAGS += -DNO_DEFLATE_BOUND endif +ifdef NO_POSIX_GOODIES + BASIC_CFLAGS += -DNO_POSIX_GOODIES +endif + ifdef BLK_SHA1 SHA1_HEADER = "block-sha1/sha1.h" LIB_OBJS += block-sha1/sha1.o @@@ -1983,7 -1928,7 +1984,7 @@@ git-%$X: %.o $(GITLIBS git-imap-send$X: imap-send.o $(GITLIBS) $(QUIET_LINK)$(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) $(filter %.o,$^) \ - $(LIBS) $(OPENSSL_LINK) $(OPENSSL_LIBSSL) + $(LIBS) $(OPENSSL_LINK) $(OPENSSL_LIBSSL) $(LIB_4_CRYPTO) git-http-fetch$X: revision.o http.o http-walker.o http-fetch.o $(GITLIBS) $(QUIET_LINK)$(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) $(filter %.o,$^) \ diff --combined builtin/pack-objects.c index 3cbeb299d1,7471c92b93..f027b3abb4 --- a/builtin/pack-objects.c +++ b/builtin/pack-objects.c @@@ -1298,23 -1298,9 +1298,23 @@@ static int try_delta(struct unpacked *t read_lock(); src->data = read_sha1_file(src_entry->idx.sha1, &type, &sz); read_unlock(); - if (!src->data) + if (!src->data) { + if (src_entry->preferred_base) { + static int warned = 0; + if (!warned++) + warning("object %s cannot be read", + sha1_to_hex(src_entry->idx.sha1)); + /* + * Those objects are not included in the + * resulting pack. Be resilient and ignore + * them if they can't be read, in case the + * pack could be created nevertheless. + */ + return 0; + } die("object %s cannot be read", sha1_to_hex(src_entry->idx.sha1)); + } if (sz != src_size) die("object %s inconsistent object length (%lu vs %lu)", sha1_to_hex(src_entry->idx.sha1), sz, src_size); @@@ -1543,7 -1529,7 +1543,7 @@@ static void try_to_free_from_threads(si read_unlock(); } - try_to_free_t old_try_to_free_routine; + static try_to_free_t old_try_to_free_routine; /* * The main thread waits on the condition that (at least) one of the workers diff --combined environment.c index 76e4dee273,95777f4c7f..913b0580af --- a/environment.c +++ b/environment.c @@@ -21,7 -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; @@@ -172,6 -171,43 +172,43 @@@ char *get_object_directory(void return git_object_dir; } + int odb_mkstemp(char *template, size_t limit, const char *pattern) + { + int fd; + /* + * we let the umask do its job, don't try to be more + * restrictive except to remove write permission. + */ + int mode = 0444; + snprintf(template, limit, "%s/%s", + get_object_directory(), pattern); + fd = git_mkstemp_mode(template, mode); + if (0 <= fd) + return fd; + + /* slow path */ + /* some mkstemp implementations erase template on failure */ + snprintf(template, limit, "%s/%s", + get_object_directory(), pattern); + safe_create_leading_directories(template); + return xmkstemp_mode(template, mode); + } + + int odb_pack_keep(char *name, size_t namesz, unsigned char *sha1) + { + int fd; + + snprintf(name, namesz, "%s/pack/pack-%s.keep", + get_object_directory(), sha1_to_hex(sha1)); + fd = open(name, O_RDWR|O_CREAT|O_EXCL, 0600); + if (0 <= fd) + return fd; + + /* slow path */ + safe_create_leading_directories(name); + return open(name, O_RDWR|O_CREAT|O_EXCL, 0600); + } + char *get_index_file(void) { if (!git_index_file) @@@ -193,14 -229,3 +230,14 @@@ int set_git_dir(const char *path setup_git_env(); return 0; } + +const char *get_log_output_encoding(void) +{ + return git_log_output_encoding ? git_log_output_encoding + : get_commit_output_encoding(); +} + +const char *get_commit_output_encoding(void) +{ + return git_commit_encoding ? git_commit_encoding : "UTF-8"; +} diff --combined git-compat-util.h index 490f969744,029162eccc..d6d269f138 --- a/git-compat-util.h +++ b/git-compat-util.h @@@ -104,14 -104,9 +104,14 @@@ #include #include #include +#include +#ifndef NO_SYS_POLL_H +#include +#else +#include +#endif #ifndef __MINGW32__ #include -#include #include #include #include @@@ -123,11 -118,7 +123,11 @@@ #include #include #include +#ifndef NO_INTTYPES_H #include +#else +#include +#endif #if defined(__CYGWIN__) #undef _XOPEN_SOURCE #include @@@ -395,14 -386,6 +395,14 @@@ static inline void *gitmempcpy(void *de } #endif +#ifdef NO_INET_PTON +int inet_pton(int af, const char *src, void *dst); +#endif + +#ifdef NO_INET_NTOP +const char *inet_ntop(int af, const void *src, char *dst, size_t size); +#endif + extern void release_pack_memory(size_t, int); typedef void (*try_to_free_t)(size_t); @@@ -421,6 -404,7 +421,7 @@@ extern ssize_t xwrite(int fd, const voi extern int xdup(int fd); extern FILE *xfdopen(int fd, const char *mode); extern int xmkstemp(char *template); + extern int xmkstemp_mode(char *template, int mode); extern int odb_mkstemp(char *template, size_t limit, const char *pattern); extern int odb_pack_keep(char *name, size_t namesz, unsigned char *sha1); diff --combined sha1_file.c index c5023703c9,e0d2496bcd..1cafdfa617 --- a/sha1_file.c +++ b/sha1_file.c @@@ -35,8 -35,6 +35,8 @@@ static size_t sz_fmt(size_t s) { retur const unsigned char null_sha1[20]; +static int git_open_noatime(const char *name, struct packed_git *p); + int safe_create_leading_directories(char *path) { char *pos = path + offset_1st_component(path); @@@ -300,7 -298,7 +300,7 @@@ static void read_info_alternates(const int fd; sprintf(path, "%s/%s", relative_base, alt_file_name); - fd = open(path, O_RDONLY); + fd = git_open_noatime(path, NULL); if (fd < 0) return; if (fstat(fd, &st) || (st.st_size == 0)) { @@@ -413,7 -411,7 +413,7 @@@ static int check_packed_git_idx(const c struct pack_idx_header *hdr; size_t idx_size; uint32_t version, nr, i, *index; - int fd = open(path, O_RDONLY); + int fd = git_open_noatime(path, p); struct stat st; if (fd < 0) @@@ -578,6 -576,21 +578,21 @@@ void release_pack_memory(size_t need, i ; /* nothing */ } + void *xmmap(void *start, size_t length, + int prot, int flags, int fd, off_t offset) + { + void *ret = mmap(start, length, prot, flags, fd, offset); + if (ret == MAP_FAILED) { + if (!length) + return NULL; + release_pack_memory(length, fd); + ret = mmap(start, length, prot, flags, fd, offset); + if (ret == MAP_FAILED) + die_errno("Out of memory? mmap failed"); + } + return ret; + } + void close_pack_windows(struct packed_git *p) { while (p->windows) { @@@ -657,7 -670,9 +672,7 @@@ static int open_packed_git_1(struct pac if (!p->index_data && open_pack_index(p)) return error("packfile %s index unavailable", p->pack_name); - p->pack_fd = open(p->pack_name, O_RDONLY); - while (p->pack_fd < 0 && errno == EMFILE && unuse_one_window(p, -1)) - p->pack_fd = open(p->pack_name, O_RDONLY); + p->pack_fd = git_open_noatime(p->pack_name, p); if (p->pack_fd < 0 || fstat(p->pack_fd, &st)) return -1; @@@ -803,11 -818,22 +818,22 @@@ static struct packed_git *alloc_packed_ return p; } + static void try_to_free_pack_memory(size_t size) + { + release_pack_memory(size, -1); + } + struct packed_git *add_packed_git(const char *path, int path_len, int local) { + static int have_set_try_to_free_routine; struct stat st; struct packed_git *p = alloc_packed_git(path_len + 2); + if (!have_set_try_to_free_routine) { + have_set_try_to_free_routine = 1; + set_try_to_free_routine(try_to_free_pack_memory); + } + /* * Make sure a corresponding .pack file exists and that * the index looks sane. @@@ -874,7 -900,7 +900,7 @@@ static void prepare_packed_git_one(cha sprintf(path, "%s/pack", objdir); len = strlen(path); dir = opendir(path); - while (!dir && errno == EMFILE && unuse_one_window(packed_git, -1)) + while (!dir && errno == EMFILE && unuse_one_window(NULL, -1)) dir = opendir(path); if (!dir) { if (errno != ENOENT) @@@ -1003,7 -1029,7 +1029,7 @@@ static void mark_bad_packed_object(stru p->num_bad_objects++; } -static int has_packed_and_bad(const unsigned char *sha1) +static const struct packed_git *has_packed_and_bad(const unsigned char *sha1) { struct packed_git *p; unsigned i; @@@ -1011,8 -1037,8 +1037,8 @@@ for (p = packed_git; p; p = p->next) for (i = 0; i < p->num_bad_objects; i++) if (!hashcmp(sha1, p->bad_object_sha1 + 20 * i)) - return 1; - return 0; + return p; + return NULL; } int check_sha1_signature(const unsigned char *sha1, void *map, unsigned long size, const char *type) @@@ -1022,31 -1048,18 +1048,31 @@@ return hashcmp(sha1, real_sha1) ? -1 : 0; } -static int git_open_noatime(const char *name) +static int git_open_noatime(const char *name, struct packed_git *p) { static int sha1_file_open_flag = O_NOATIME; - int fd = open(name, O_RDONLY | sha1_file_open_flag); - /* Might the failure be due to O_NOATIME? */ - if (fd < 0 && errno != ENOENT && sha1_file_open_flag) { - fd = open(name, O_RDONLY); + for (;;) { + int fd = open(name, O_RDONLY | sha1_file_open_flag); if (fd >= 0) + return fd; + + /* Might the failure be insufficient file descriptors? */ + if (errno == EMFILE) { + if (unuse_one_window(p, -1)) + continue; + else + return -1; + } + + /* Might the failure be due to O_NOATIME? */ + if (errno != ENOENT && sha1_file_open_flag) { sha1_file_open_flag = 0; + continue; + } + + return -1; } - return fd; } static int open_sha1_file(const unsigned char *sha1) @@@ -1055,7 -1068,7 +1081,7 @@@ char *name = sha1_file_name(sha1); struct alternate_object_database *alt; - fd = git_open_noatime(name); + fd = git_open_noatime(name, NULL); if (fd >= 0) return fd; @@@ -1064,7 -1077,7 +1090,7 @@@ for (alt = alt_odb_list; alt; alt = alt->next) { name = alt->name; fill_sha1_path(name, sha1); - fd = git_open_noatime(alt->base); + fd = git_open_noatime(alt->base, NULL); if (fd >= 0) return fd; } @@@ -2092,48 -2105,36 +2118,48 @@@ static void *read_object(const unsigne return read_packed_sha1(sha1, type, size); } +/* + * This function dies on corrupt objects; the callers who want to + * deal with them should arrange to call read_object() and give error + * messages themselves. + */ void *read_sha1_file_repl(const unsigned char *sha1, enum object_type *type, unsigned long *size, const unsigned char **replacement) { const unsigned char *repl = lookup_replace_object(sha1); - void *data = read_object(repl, type, size); + void *data; char *path; + const struct packed_git *p; + + errno = 0; + data = read_object(repl, type, size); + if (data) { + if (replacement) + *replacement = repl; + return data; + } + + if (errno != ENOENT) + die_errno("failed to read object %s", sha1_to_hex(sha1)); /* die if we replaced an object with one that does not exist */ - if (!data && repl != sha1) + if (repl != sha1) die("replacement %s not found for %s", sha1_to_hex(repl), sha1_to_hex(sha1)); - /* legacy behavior is to die on corrupted objects */ - if (!data) { - if (has_loose_object(repl)) { - path = sha1_file_name(sha1); - die("loose object %s (stored in %s) is corrupted", sha1_to_hex(repl), path); - } - if (has_packed_and_bad(repl)) { - path = sha1_pack_name(sha1); - die("packed object %s (stored in %s) is corrupted", sha1_to_hex(repl), path); - } + if (has_loose_object(repl)) { + path = sha1_file_name(sha1); + die("loose object %s (stored in %s) is corrupt", + sha1_to_hex(repl), path); } - if (replacement) - *replacement = repl; + if ((p = has_packed_and_bad(repl)) != NULL) + die("packed object %s (stored in %s) is corrupt", + sha1_to_hex(repl), p->pack_name); - return data; + return NULL; } void *read_object_with_reference(const unsigned char *sha1, @@@ -2325,7 -2326,7 +2351,7 @@@ static int write_loose_object(const uns filename = sha1_file_name(sha1); fd = create_tmpfile(tmpfile, sizeof(tmpfile), filename); - while (fd < 0 && errno == EMFILE && unuse_one_window(packed_git, -1)) + while (fd < 0 && errno == EMFILE && unuse_one_window(NULL, -1)) fd = create_tmpfile(tmpfile, sizeof(tmpfile), filename); if (fd < 0) { if (errno == EACCES) diff --combined sha1_name.c index b48b91c507,32522c0fe5..2c3a5fb363 --- a/sha1_name.c +++ b/sha1_name.c @@@ -206,9 -206,7 +206,9 @@@ const char *find_unique_abbrev(const un 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++; @@@ -936,6 -934,24 +936,24 @@@ int interpret_branch_name(const char *n return len; } + int strbuf_branchname(struct strbuf *sb, const char *name) + { + int len = strlen(name); + if (interpret_branch_name(name, sb) == len) + return 0; + strbuf_add(sb, name, len); + return len; + } + + int strbuf_check_branch_ref(struct strbuf *sb, const char *name) + { + strbuf_branchname(sb, name); + if (name[0] == '-') + return CHECK_REF_FORMAT_ERROR; + strbuf_splice(sb, 0, 0, "refs/heads/", 11); + return check_ref_format(sb->buf); + } + /* * This is like "get_sha1_basic()", except it allows "sha1 expressions", * notably "xyz^" for "parent of xyz" @@@ -1071,7 -1087,6 +1089,7 @@@ int get_sha1_with_context_1(const char struct cache_entry *ce; int pos; if (namelen > 2 && name[1] == '/') + /* don't need mode for commit */ return get_sha1_oneline(name + 2, sha1); if (namelen < 3 || name[2] != ':' || @@@ -1099,7 -1114,6 +1117,7 @@@ break; if (ce_stage(ce) == stage) { hashcpy(sha1, ce->sha1); + oc->mode = ce->ce_mode; return 0; } pos++;