#include "hash.h"
#include "advice.h"
#include "gettext.h"
+#include "convert.h"
#include SHA1_HEADER
#ifndef git_SHA_CTX
#endif
#include <zlib.h>
-#if defined(NO_DEFLATE_BOUND) || ZLIB_VERNUM < 0x1200
-#define deflateBound(c,s) ((s) + (((s) + 7) >> 3) + (((s) + 63) >> 6) + 11)
-#endif
-
-void git_inflate_init(z_streamp strm);
-void git_inflate_end(z_streamp strm);
-int git_inflate(z_streamp strm, int flush);
+typedef struct git_zstream {
+ z_stream z;
+ unsigned long avail_in;
+ unsigned long avail_out;
+ unsigned long total_in;
+ unsigned long total_out;
+ unsigned char *next_in;
+ unsigned char *next_out;
+} git_zstream;
+
+void git_inflate_init(git_zstream *);
+void git_inflate_init_gzip_only(git_zstream *);
+void git_inflate_end(git_zstream *);
+int git_inflate(git_zstream *, int flush);
+
+void git_deflate_init(git_zstream *, int level);
+void git_deflate_init_gzip(git_zstream *, int level);
+void git_deflate_end(git_zstream *);
+int git_deflate_end_gently(git_zstream *);
+int git_deflate(git_zstream *, int flush);
+unsigned long git_deflate_bound(git_zstream *, unsigned long);
#if defined(DT_UNKNOWN) && !defined(NO_D_TYPE_IN_DIRENT)
#define DTYPE(de) ((de)->d_type)
struct pathspec_item {
const char *match;
int len;
- unsigned int has_wildcard:1;
+ unsigned int use_wildcard:1;
} *items;
};
extern int init_pathspec(struct pathspec *, const char **);
extern void free_pathspec(struct pathspec *);
extern int ce_path_match(const struct cache_entry *ce, const struct pathspec *pathspec);
-extern int index_fd(unsigned char *sha1, int fd, struct stat *st, int write_object, enum object_type type, const char *path, int format_check);
-extern int index_path(unsigned char *sha1, const char *path, struct stat *st, int write_object);
+
+#define HASH_WRITE_OBJECT 1
+#define HASH_FORMAT_CHECK 2
+extern int index_fd(unsigned char *sha1, int fd, struct stat *st, enum object_type type, const char *path, unsigned flags);
+extern int index_path(unsigned char *sha1, const char *path, struct stat *st, unsigned flags);
extern void fill_stat_cache_info(struct cache_entry *ce, struct stat *st);
#define REFRESH_REALLY 0x0001 /* ignore_valid */
extern int core_preload_index;
extern int core_apply_sparse_checkout;
-enum safe_crlf {
- SAFE_CRLF_FALSE = 0,
- SAFE_CRLF_FAIL = 1,
- SAFE_CRLF_WARN = 2
-};
-
-extern enum safe_crlf safe_crlf;
-
-enum auto_crlf {
- AUTO_CRLF_FALSE = 0,
- AUTO_CRLF_TRUE = 1,
- AUTO_CRLF_INPUT = -1
-};
-
-extern enum auto_crlf auto_crlf;
-
-enum eol {
- EOL_UNSET,
- EOL_CRLF,
- EOL_LF,
-#ifdef NATIVE_CRLF
- EOL_NATIVE = EOL_CRLF
-#else
- EOL_NATIVE = EOL_LF
-#endif
-};
-
-extern enum eol eol;
-
enum branch_track {
BRANCH_TRACK_UNSPECIFIED = -1,
BRANCH_TRACK_NEVER = 0,
extern char *sha1_pack_index_name(const unsigned char *sha1);
extern const char *find_unique_abbrev(const unsigned char *sha1, int);
extern const unsigned char null_sha1[20];
-static inline int is_null_sha1(const unsigned char *sha1)
+
+static inline int hashcmp(const unsigned char *sha1, const unsigned char *sha2)
{
- return !memcmp(sha1, null_sha1, 20);
+ int i;
+
+ for (i = 0; i < 20; i++, sha1++, sha2++) {
+ if (*sha1 != *sha2)
+ return *sha1 - *sha2;
+ }
+
+ return 0;
}
-static inline int hashcmp(const unsigned char *sha1, const unsigned char *sha2)
+
+static inline int is_null_sha1(const unsigned char *sha1)
{
- return memcmp(sha1, sha2, 20);
+ return !hashcmp(sha1, null_sha1);
}
+
static inline void hashcpy(unsigned char *sha_dst, const unsigned char *sha_src)
{
memcpy(sha_dst, sha_src, 20);
char *enter_repo(char *path, int strict);
static inline int is_absolute_path(const char *path)
{
- return path[0] == '/' || has_dos_drive_prefix(path);
+ return is_dir_sep(path[0]) || has_dos_drive_prefix(path);
}
int is_directory(const char *);
const char *real_path(const char *path);
int daemon_avoid_alias(const char *path);
int offset_1st_component(const char *path);
-/* Read and unpack a sha1 file into memory, write memory to a sha1 file */
-extern int sha1_object_info(const unsigned char *, unsigned long *);
-extern void *read_sha1_file_repl(const unsigned char *sha1, enum object_type *type, unsigned long *size, const unsigned char **replacement);
+/* object replacement */
+#define READ_SHA1_FILE_REPLACE 1
+extern void *read_sha1_file_extended(const unsigned char *sha1, enum object_type *type, unsigned long *size, unsigned flag);
static inline void *read_sha1_file(const unsigned char *sha1, enum object_type *type, unsigned long *size)
{
- return read_sha1_file_repl(sha1, type, size, NULL);
+ return read_sha1_file_extended(sha1, type, size, READ_SHA1_FILE_REPLACE);
+}
+extern const unsigned char *do_lookup_replace_object(const unsigned char *sha1);
+static inline const unsigned char *lookup_replace_object(const unsigned char *sha1)
+{
+ if (!read_replace_refs)
+ return sha1;
+ return do_lookup_replace_object(sha1);
}
+
+/* Read and unpack a sha1 file into memory, write memory to a sha1 file */
+extern int sha1_object_info(const unsigned char *, unsigned long *);
extern int hash_sha1_file(const void *buf, unsigned long len, const char *type, unsigned char *sha1);
extern int write_sha1_file(const void *buf, unsigned long len, const char *type, unsigned char *return_sha1);
extern int pretend_sha1_file(void *, unsigned long, enum object_type, unsigned char *);
extern int force_object_loose(const unsigned char *sha1, time_t mtime);
+extern void *map_sha1_file(const unsigned char *sha1, unsigned long *size);
+extern int unpack_sha1_header(git_zstream *stream, unsigned char *map, unsigned long mapsize, void *buffer, unsigned long bufsiz);
+extern int parse_sha1_header(const char *hdr, unsigned long *sizep);
/* global flag to enable extra checks when accessing packed objects */
extern int do_check_packed_object_crc;
};
extern int get_sha1(const char *str, unsigned char *sha1);
-extern int get_sha1_with_mode_1(const char *str, unsigned char *sha1, unsigned *mode, int gently, const char *prefix);
+extern int get_sha1_with_mode_1(const char *str, unsigned char *sha1, unsigned *mode, int only_to_die, const char *prefix);
static inline int get_sha1_with_mode(const char *str, unsigned char *sha1, unsigned *mode)
{
- return get_sha1_with_mode_1(str, sha1, mode, 1, NULL);
+ return get_sha1_with_mode_1(str, sha1, mode, 0, NULL);
}
-extern int get_sha1_with_context_1(const char *name, unsigned char *sha1, struct object_context *orc, int gently, const char *prefix);
+extern int get_sha1_with_context_1(const char *name, unsigned char *sha1, struct object_context *orc, int only_to_die, const char *prefix);
static inline int get_sha1_with_context(const char *str, unsigned char *sha1, struct object_context *orc)
{
- return get_sha1_with_context_1(str, sha1, orc, 1, NULL);
+ return get_sha1_with_context_1(str, sha1, orc, 0, NULL);
}
extern int get_sha1_hex(const char *hex, unsigned char *sha1);
extern char *sha1_to_hex(const unsigned char *sha1); /* static buffer result! */
extern void pack_report(void);
extern int open_pack_index(struct packed_git *);
extern void close_pack_index(struct packed_git *);
-extern unsigned char *use_pack(struct packed_git *, struct pack_window **, off_t, unsigned int *);
+extern unsigned char *use_pack(struct packed_git *, struct pack_window **, off_t, unsigned long *);
extern void close_pack_windows(struct packed_git *);
extern void unuse_pack(struct pack_window **);
extern void free_pack_by_name(const char *);
extern void *unpack_entry(struct packed_git *, off_t, enum object_type *, unsigned long *);
extern unsigned long unpack_object_header_buffer(const unsigned char *buf, unsigned long len, enum object_type *type, unsigned long *sizep);
extern unsigned long get_size_from_delta(struct packed_git *, struct pack_window **, off_t);
-extern const char *packed_object_info_detail(struct packed_git *, off_t, unsigned long *, unsigned long *, unsigned int *, unsigned char *);
+extern int packed_object_info_detail(struct packed_git *, off_t, unsigned long *, unsigned long *, unsigned int *, unsigned char *);
+extern int unpack_object_header(struct packed_git *, struct pack_window **, off_t *, unsigned long *);
+
+struct object_info {
+ /* Request */
+ unsigned long *sizep;
+
+ /* Response */
+ enum {
+ OI_CACHED,
+ OI_LOOSE,
+ OI_PACKED,
+ OI_DBCACHED
+ } whence;
+ union {
+ /*
+ * struct {
+ * ... Nothing to expose in this case
+ * } cached;
+ * struct {
+ * ... Nothing to expose in this case
+ * } loose;
+ */
+ struct {
+ struct packed_git *pack;
+ off_t offset;
+ unsigned int is_delta;
+ } packed;
+ } u;
+};
+extern int sha1_object_info_extended(const unsigned char *, struct object_info *);
/* Dumb servers support */
extern int update_server_info(int);
+/* git_config_parse_key() returns these negated: */
+#define CONFIG_INVALID_KEY 1
+#define CONFIG_NO_SECTION_OR_NAME 2
+/* git_config_set(), git_config_set_multivar() return the above or these: */
+#define CONFIG_NO_LOCK -1
+#define CONFIG_INVALID_FILE 3
+#define CONFIG_NO_WRITE 4
+#define CONFIG_NOTHING_SET 5
+#define CONFIG_INVALID_PATTERN 6
+
typedef int (*config_fn_t)(const char *, const char *, void *);
extern int git_default_config(const char *, const char *, void *);
extern int git_config_from_file(config_fn_t fn, const char *, void *);
extern const char *get_log_output_encoding(void);
extern const char *get_commit_output_encoding(void);
+ extern int git_config_parse_parameter(const char *, config_fn_t fn, void *data);
+
extern const char *config_exclusive_filename;
#define MAX_GITNAME (1000)
void packet_trace_identity(const char *prog);
-/* convert.c */
-/* returns 1 if *dst was used */
-extern int convert_to_git(const char *path, const char *src, size_t len,
- struct strbuf *dst, enum safe_crlf checksafe);
-extern int convert_to_working_tree(const char *path, const char *src, size_t len, struct strbuf *dst);
-extern int renormalize_buffer(const char *path, const char *src, size_t len, struct strbuf *dst);
-
/* add */
/*
* return 0 if success, 1 - if addition of a file failed and
#define MAXNAME (256)
-static FILE *config_file;
-static const char *config_file_name;
-static int config_linenr;
-static int config_file_eof;
+typedef struct config_file {
+ struct config_file *prev;
+ FILE *f;
+ const char *name;
+ int linenr;
+ int eof;
+ struct strbuf value;
+ char var[MAXNAME];
+} config_file;
+
+static config_file *cf;
+
static int zlib_compression_seen;
const char *config_exclusive_filename = NULL;
strbuf_release(&env);
}
- static int git_config_parse_parameter(const char *text,
- config_fn_t fn, void *data)
+ int git_config_parse_parameter(const char *text,
+ config_fn_t fn, void *data)
{
struct strbuf **pair;
pair = strbuf_split_str(text, '=', 2);
FILE *f;
c = '\n';
- if ((f = config_file) != NULL) {
+ if (cf && ((f = cf->f) != NULL)) {
c = fgetc(f);
if (c == '\r') {
/* DOS like systems */
}
}
if (c == '\n')
- config_linenr++;
+ cf->linenr++;
if (c == EOF) {
- config_file_eof = 1;
+ cf->eof = 1;
c = '\n';
}
}
static char *parse_value(void)
{
- static char value[1024];
- int quote = 0, comment = 0, len = 0, space = 0;
+ int quote = 0, comment = 0, space = 0;
+ strbuf_reset(&cf->value);
for (;;) {
int c = get_next_char();
- if (len >= sizeof(value) - 1)
- return NULL;
if (c == '\n') {
if (quote)
return NULL;
- value[len] = 0;
- return value;
+ return cf->value.buf;
}
if (comment)
continue;
if (isspace(c) && !quote) {
- if (len)
+ if (cf->value.len)
space++;
continue;
}
}
}
for (; space; space--)
- value[len++] = ' ';
+ strbuf_addch(&cf->value, ' ');
if (c == '\\') {
c = get_next_char();
switch (c) {
default:
return NULL;
}
- value[len++] = c;
+ strbuf_addch(&cf->value, c);
continue;
}
if (c == '"') {
quote = 1-quote;
continue;
}
- value[len++] = c;
+ strbuf_addch(&cf->value, c);
}
}
/* Get the full name */
for (;;) {
c = get_next_char();
- if (config_file_eof)
+ if (cf->eof)
break;
if (!iskeychar(c))
break;
for (;;) {
int c = get_next_char();
- if (config_file_eof)
+ if (cf->eof)
return -1;
if (c == ']')
return baselen;
{
int comment = 0;
int baselen = 0;
- static char var[MAXNAME];
+ char *var = cf->var;
/* U+FEFF Byte Order Mark in UTF8 */
static const unsigned char *utf8_bom = (unsigned char *) "\xef\xbb\xbf";
}
}
if (c == '\n') {
- if (config_file_eof)
+ if (cf->eof)
return 0;
comment = 0;
continue;
if (get_value(fn, data, var, baselen+1) < 0)
break;
}
- die("bad config file line %d in %s", config_linenr, config_file_name);
+ die("bad config file line %d in %s", cf->linenr, cf->name);
}
static int parse_unit_factor(const char *end, unsigned long *val)
static void die_bad_config(const char *name)
{
- if (config_file_name)
- die("bad config value for '%s' in %s", name, config_file_name);
+ if (cf && cf->name)
+ die("bad config value for '%s' in %s", name, cf->name);
die("bad config value for '%s'", name);
}
if (!strcmp(var, "core.autocrlf")) {
if (value && !strcasecmp(value, "input")) {
- if (eol == EOL_CRLF)
+ if (core_eol == EOL_CRLF)
return error("core.autocrlf=input conflicts with core.eol=crlf");
auto_crlf = AUTO_CRLF_INPUT;
return 0;
if (!strcmp(var, "core.eol")) {
if (value && !strcasecmp(value, "lf"))
- eol = EOL_LF;
+ core_eol = EOL_LF;
else if (value && !strcasecmp(value, "crlf"))
- eol = EOL_CRLF;
+ core_eol = EOL_CRLF;
else if (value && !strcasecmp(value, "native"))
- eol = EOL_NATIVE;
+ core_eol = EOL_NATIVE;
else
- eol = EOL_UNSET;
- if (eol == EOL_CRLF && auto_crlf == AUTO_CRLF_INPUT)
+ core_eol = EOL_UNSET;
+ if (core_eol == EOL_CRLF && auto_crlf == AUTO_CRLF_INPUT)
return error("core.autocrlf=input conflicts with core.eol=crlf");
return 0;
}
ret = -1;
if (f) {
- config_file = f;
- config_file_name = filename;
- config_linenr = 1;
- config_file_eof = 0;
+ config_file top;
+
+ /* push config-file parsing state stack */
+ top.prev = cf;
+ top.f = f;
+ top.name = filename;
+ top.linenr = 1;
+ top.eof = 0;
+ strbuf_init(&top.value, 1024);
+ cf = ⊤
+
ret = git_parse_file(fn, data);
+
+ /* pop config-file parsing state stack */
+ strbuf_release(&top.value);
+ cf = top.prev;
+
fclose(f);
- config_file_name = NULL;
}
return ret;
}
{
const char *ep;
size_t section_len;
+ FILE *f = cf->f;
switch (store.state) {
case KEY_SEEN:
return 1;
}
- store.offset[store.seen] = ftell(config_file);
+ store.offset[store.seen] = ftell(f);
store.seen++;
}
break;
* Do not increment matches: this is no match, but we
* just made sure we are in the desired section.
*/
- store.offset[store.seen] = ftell(config_file);
+ store.offset[store.seen] = ftell(f);
/* fallthru */
case SECTION_END_SEEN:
case START:
if (matches(key, value)) {
- store.offset[store.seen] = ftell(config_file);
+ store.offset[store.seen] = ftell(f);
store.state = KEY_SEEN;
store.seen++;
} else {
if (strrchr(key, '.') - key == store.baselen &&
!strncmp(key, store.key, store.baselen)) {
store.state = SECTION_SEEN;
- store.offset[store.seen] = ftell(config_file);
+ store.offset[store.seen] = ftell(f);
}
}
}
if (last_dot == NULL || last_dot == key) {
error("key does not contain a section: %s", key);
- return -2;
+ return -CONFIG_NO_SECTION_OR_NAME;
}
if (!last_dot[1]) {
error("key does not contain variable name: %s", key);
- return -2;
+ return -CONFIG_NO_SECTION_OR_NAME;
}
baselen = last_dot - key;
out_free_ret_1:
free(*store_key);
- return -1;
+ return -CONFIG_INVALID_KEY;
}
/*
if (fd < 0) {
error("could not lock config file %s: %s", config_filename, strerror(errno));
free(store.key);
- ret = -1;
+ ret = CONFIG_NO_LOCK;
goto out_free;
}
if ( ENOENT != errno ) {
error("opening %s: %s", config_filename,
strerror(errno));
- ret = 3; /* same as "invalid config file" */
+ ret = CONFIG_INVALID_FILE; /* same as "invalid config file" */
goto out_free;
}
/* if nothing to unset, error out */
if (value == NULL) {
- ret = 5;
+ ret = CONFIG_NOTHING_SET;
goto out_free;
}
REG_EXTENDED)) {
error("invalid pattern: %s", value_regex);
free(store.value_regex);
- ret = 6;
+ ret = CONFIG_INVALID_PATTERN;
goto out_free;
}
}
regfree(store.value_regex);
free(store.value_regex);
}
- ret = 3;
+ ret = CONFIG_INVALID_FILE;
goto out_free;
}
/* if nothing to unset, or too many matches, error out */
if ((store.seen == 0 && value == NULL) ||
(store.seen > 1 && multi_replace == 0)) {
- ret = 5;
+ ret = CONFIG_NOTHING_SET;
goto out_free;
}
if (commit_lock_file(lock) < 0) {
error("could not commit config file %s", config_filename);
- ret = 4;
+ ret = CONFIG_NO_WRITE;
goto out_free;
}
struct lock_file *lock = xcalloc(sizeof(struct lock_file), 1);
int out_fd;
char buf[1024];
+ FILE *config_file;
if (config_exclusive_filename)
config_filename = xstrdup(config_exclusive_filename);