diff options
Diffstat (limited to 'cache.h')
-rw-r--r-- | cache.h | 173 |
1 files changed, 149 insertions, 24 deletions
@@ -6,12 +6,22 @@ #include "hash.h" #include SHA1_HEADER -#include <zlib.h> +#ifndef git_SHA_CTX +#define git_SHA_CTX SHA_CTX +#define git_SHA1_Init SHA1_Init +#define git_SHA1_Update SHA1_Update +#define git_SHA1_Final SHA1_Final +#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); + #if defined(DT_UNKNOWN) && !defined(NO_D_TYPE_IN_DIRENT) #define DTYPE(de) ((de)->d_type) #else @@ -109,9 +119,29 @@ struct ondisk_cache_entry { char name[FLEX_ARRAY]; /* more */ }; +/* + * This struct is used when CE_EXTENDED bit is 1 + * The struct must match ondisk_cache_entry exactly from + * ctime till flags + */ +struct ondisk_cache_entry_extended { + struct cache_time ctime; + struct cache_time mtime; + unsigned int dev; + unsigned int ino; + unsigned int mode; + unsigned int uid; + unsigned int gid; + unsigned int size; + unsigned char sha1[20]; + unsigned short flags; + unsigned short flags2; + char name[FLEX_ARRAY]; /* more */ +}; + struct cache_entry { - unsigned int ce_ctime; - unsigned int ce_mtime; + struct cache_time ce_ctime; + struct cache_time ce_mtime; unsigned int ce_dev; unsigned int ce_ino; unsigned int ce_mode; @@ -126,10 +156,19 @@ struct cache_entry { #define CE_NAMEMASK (0x0fff) #define CE_STAGEMASK (0x3000) +#define CE_EXTENDED (0x4000) #define CE_VALID (0x8000) #define CE_STAGESHIFT 12 -/* In-memory only */ +/* + * Range 0xFFFF0000 in ce_flags is divided into + * two parts: in-memory flags and on-disk ones. + * Flags in CE_EXTENDED_FLAGS will get saved on-disk + * if you want to save a new flag, add it in + * CE_EXTENDED_FLAGS + * + * In-memory only flags + */ #define CE_UPDATE (0x10000) #define CE_REMOVE (0x20000) #define CE_UPTODATE (0x40000) @@ -139,6 +178,25 @@ struct cache_entry { #define CE_UNHASHED (0x200000) /* + * Extended on-disk flags + */ +#define CE_INTENT_TO_ADD 0x20000000 +/* CE_EXTENDED2 is for future extension */ +#define CE_EXTENDED2 0x80000000 + +#define CE_EXTENDED_FLAGS (CE_INTENT_TO_ADD) + +/* + * Safeguard to avoid saving wrong flags: + * - CE_EXTENDED2 won't get saved until its semantic is known + * - Bits in 0x0000FFFF have been saved in ce_flags already + * - Bits in 0x003F0000 are currently in-memory flags + */ +#if CE_EXTENDED_FLAGS & 0x803FFFFF +#error "CE_EXTENDED_FLAGS out of range" +#endif + +/* * Copy the sha1 and stat state of a cache entry from one to * another. But we never change the name, or the hash state! */ @@ -170,7 +228,9 @@ static inline size_t ce_namelen(const struct cache_entry *ce) } #define ce_size(ce) cache_entry_size(ce_namelen(ce)) -#define ondisk_ce_size(ce) ondisk_cache_entry_size(ce_namelen(ce)) +#define ondisk_ce_size(ce) (((ce)->ce_flags & CE_EXTENDED) ? \ + ondisk_cache_entry_extended_size(ce_namelen(ce)) : \ + ondisk_cache_entry_size(ce_namelen(ce))) #define ce_stage(ce) ((CE_STAGEMASK & (ce)->ce_flags) >> CE_STAGESHIFT) #define ce_uptodate(ce) ((ce)->ce_flags & CE_UPTODATE) #define ce_mark_uptodate(ce) ((ce)->ce_flags |= CE_UPTODATE) @@ -213,14 +273,16 @@ static inline int ce_to_dtype(const struct cache_entry *ce) (S_ISREG(mode) ? (S_IFREG | ce_permissions(mode)) : \ S_ISLNK(mode) ? S_IFLNK : S_ISDIR(mode) ? S_IFDIR : S_IFGITLINK) -#define cache_entry_size(len) ((offsetof(struct cache_entry,name) + (len) + 8) & ~7) -#define ondisk_cache_entry_size(len) ((offsetof(struct ondisk_cache_entry,name) + (len) + 8) & ~7) +#define flexible_size(STRUCT,len) ((offsetof(struct STRUCT,name) + (len) + 8) & ~7) +#define cache_entry_size(len) flexible_size(cache_entry,len) +#define ondisk_cache_entry_size(len) flexible_size(ondisk_cache_entry,len) +#define ondisk_cache_entry_extended_size(len) flexible_size(ondisk_cache_entry_extended,len) struct index_state { struct cache_entry **cache; unsigned int cache_nr, cache_alloc, cache_changed; struct cache_tree *cache_tree; - time_t timestamp; + struct cache_time timestamp; void *alloc; unsigned name_hash_initialized : 1, initialized : 1; @@ -255,6 +317,7 @@ static inline void remove_name_hash(struct cache_entry *ce) #define read_cache() read_index(&the_index) #define read_cache_from(path) read_index_from(&the_index, (path)) +#define read_cache_preload(pathspec) read_index_preload(&the_index, (pathspec)) #define is_cache_unborn() is_index_unborn(&the_index) #define read_cache_unmerged() read_index_unmerged(&the_index) #define write_cache(newfd, cache, entries) write_index(&the_index, (newfd)) @@ -314,6 +377,7 @@ extern int is_bare_repository(void); extern int is_inside_git_dir(void); extern char *git_work_tree_cfg; extern int is_inside_work_tree(void); +extern int have_git_dir(void); extern const char *get_git_dir(void); extern char *get_object_directory(void); extern char *get_index_file(void); @@ -360,10 +424,11 @@ extern int init_db(const char *template_dir, unsigned int flags); /* Initialize and use the cache information */ extern int read_index(struct index_state *); +extern int read_index_preload(struct index_state *, const char **pathspec); extern int read_index_from(struct index_state *, const char *path); extern int is_index_unborn(struct index_state *); extern int read_index_unmerged(struct index_state *); -extern int write_index(const struct index_state *, int newfd); +extern int write_index(struct index_state *, int newfd); extern int discard_index(struct index_state *); extern int unmerged_index(const struct index_state *); extern int verify_path(const char *path); @@ -373,14 +438,18 @@ extern int index_name_pos(const struct index_state *, const char *name, int name #define ADD_CACHE_OK_TO_REPLACE 2 /* Ok to replace file/directory */ #define ADD_CACHE_SKIP_DFCHECK 4 /* Ok to skip DF conflict checks */ #define ADD_CACHE_JUST_APPEND 8 /* Append only; tree.c::read_tree() */ +#define ADD_CACHE_NEW_ONLY 16 /* Do not replace existing ones */ extern int add_index_entry(struct index_state *, struct cache_entry *ce, int option); extern struct cache_entry *refresh_cache_entry(struct cache_entry *ce, int really); extern void rename_index_entry_at(struct index_state *, int pos, const char *new_name); extern int remove_index_entry_at(struct index_state *, int pos); +extern void remove_marked_cache_entries(struct index_state *istate); extern int remove_file_from_index(struct index_state *, const char *path); #define ADD_CACHE_VERBOSE 1 #define ADD_CACHE_PRETEND 2 #define ADD_CACHE_IGNORE_ERRORS 4 +#define ADD_CACHE_IGNORE_REMOVAL 8 +#define ADD_CACHE_INTENT 16 extern int add_to_index(struct index_state *, const char *path, struct stat *, int flags); extern int add_file_to_index(struct index_state *, const char *path, int flags); extern struct cache_entry *make_cache_entry(unsigned int mode, const unsigned char *sha1, const char *path, int stage, int refresh); @@ -396,10 +465,12 @@ extern int ie_modified(const struct index_state *, struct cache_entry *, struct extern int ce_path_match(const struct cache_entry *ce, const char **pathspec); extern int index_fd(unsigned char *sha1, int fd, struct stat *st, int write_object, enum object_type type, const char *path); -extern int index_pipe(unsigned char *sha1, int fd, const char *type, int write_object); extern int index_path(unsigned char *sha1, const char *path, struct stat *st, int write_object); extern void fill_stat_cache_info(struct cache_entry *ce, struct stat *st); +/* "careful lstat()" */ +extern int check_path(const char *path, int len, struct stat *st); + #define REFRESH_REALLY 0x0001 /* ignore_valid */ #define REFRESH_UNMERGED 0x0002 /* allow unmerged */ #define REFRESH_QUIET 0x0004 /* be quiet about it */ @@ -417,6 +488,7 @@ struct lock_file { }; #define LOCK_DIE_ON_ERROR 1 #define LOCK_NODEREF 2 +extern NORETURN void unable_to_lock_index_die(const char *path, int err); extern int hold_lock_file_for_update(struct lock_file *, const char *path, int); extern int hold_lock_file_for_append(struct lock_file *, const char *path, int); extern int commit_lock_file(struct lock_file *); @@ -448,6 +520,7 @@ extern size_t packed_git_limit; extern size_t delta_base_cache_limit; extern int auto_crlf; extern int fsync_object_files; +extern int core_preload_index; enum safe_crlf { SAFE_CRLF_FALSE = 0, @@ -458,6 +531,7 @@ enum safe_crlf { extern enum safe_crlf safe_crlf; enum branch_track { + BRANCH_TRACK_UNSPECIFIED = -1, BRANCH_TRACK_NEVER = 0, BRANCH_TRACK_REMOTE, BRANCH_TRACK_ALWAYS, @@ -471,8 +545,25 @@ enum rebase_setup_type { AUTOREBASE_ALWAYS, }; +enum push_default_type { + PUSH_DEFAULT_NOTHING = 0, + PUSH_DEFAULT_MATCHING, + PUSH_DEFAULT_TRACKING, + PUSH_DEFAULT_CURRENT, +}; + extern enum branch_track git_branch_track; extern enum rebase_setup_type autorebase; +extern enum push_default_type push_default; + +enum object_creation_mode { + OBJECT_CREATION_USES_HARDLINKS = 0, + OBJECT_CREATION_USES_RENAMES = 1, +}; + +extern enum object_creation_mode object_creation_mode; + +extern int grafts_replace_parents; #define GIT_REPO_VERSION 0 extern int repository_format_version; @@ -517,9 +608,18 @@ static inline void hashclr(unsigned char *hash) { memset(hash, 0, 20); } +extern int is_empty_blob_sha1(const unsigned char *sha1); + +#define EMPTY_TREE_SHA1_HEX \ + "4b825dc642cb6eb9a060e54bf8d69288fbee4904" +#define EMPTY_TREE_SHA1_BIN \ + "\x4b\x82\x5d\xc6\x42\xcb\x6e\xb9\xa0\x60" \ + "\xe5\x4b\xf8\xd6\x92\x88\xfb\xee\x49\x04" int git_mkstemp(char *path, size_t n, const char *template); +int git_mkstemps(char *path, size_t n, const char *template, int suffix_len); + /* * NOTE NOTE NOTE!! * @@ -536,7 +636,8 @@ enum sharedrepo { PERM_EVERYBODY = 0664, }; int git_config_perm(const char *var, const char *value); -int adjust_shared_perm(const char *path); +int set_shared_perm(const char *path, int mode); +#define adjust_shared_perm(path) set_shared_perm((path), 0) int safe_create_leading_directories(char *path); int safe_create_leading_directories_const(const char *path); char *enter_repo(char *path, int strict); @@ -544,11 +645,13 @@ static inline int is_absolute_path(const char *path) { return path[0] == '/' || has_dos_drive_prefix(path); } +int is_directory(const char *); const char *make_absolute_path(const char *path); const char *make_nonrelative_path(const char *path); const char *make_relative_path(const char *abs, const char *base); -int normalize_absolute_path(char *buf, const char *path); +int normalize_path_copy(char *dst, const char *src); int longest_ancestor_length(const char *path, const char *prefix_list); +char *strip_path_suffix(const char *path, const char *suffix); /* Read and unpack a sha1 file into memory, write memory to a sha1 file */ extern int sha1_object_info(const unsigned char *, unsigned long *); @@ -558,14 +661,14 @@ extern int write_sha1_file(void *buf, unsigned long len, const char *type, unsig 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); -/* just like read_sha1_file(), but non fatal in presence of bad objects */ -extern void *read_object(const unsigned char *sha1, enum object_type *type, unsigned long *size); +/* global flag to enable extra checks when accessing packed objects */ +extern int do_check_packed_object_crc; extern int check_sha1_signature(const unsigned char *sha1, void *buf, unsigned long size, const char *type); extern int move_temp_to_file(const char *tmpfile, const char *filename); -extern int has_sha1_pack(const unsigned char *sha1, const char **ignore); +extern int has_sha1_pack(const unsigned char *sha1); extern int has_sha1_file(const unsigned char *sha1); extern int has_loose_object_nonlocal(const unsigned char *sha1); @@ -590,6 +693,7 @@ extern int read_ref(const char *filename, unsigned char *sha1); extern const char *resolve_ref(const char *path, unsigned char *sha1, int, int *); extern int dwim_ref(const char *str, int len, unsigned char *sha1, char **ref); extern int dwim_log(const char *str, int len, unsigned char *sha1, char **ref); +extern int interpret_branch_name(const char *str, struct strbuf *); extern int refname_match(const char *abbrev_name, const char *full_name, const char **rules); extern const char *ref_rev_parse_rules[]; @@ -616,7 +720,8 @@ enum date_mode { DATE_SHORT, DATE_LOCAL, DATE_ISO8601, - DATE_RFC2822 + DATE_RFC2822, + DATE_RAW }; const char *show_date(unsigned long time, int timezone, enum date_mode mode); @@ -643,7 +748,23 @@ struct checkout { }; extern int checkout_entry(struct cache_entry *ce, const struct checkout *state, char *topath); -extern int has_symlink_leading_path(int len, const char *name); + +struct cache_def { + char path[PATH_MAX + 1]; + int len; + int flags; + int track_flags; + int prefix_len_stat_func; +}; + +extern int has_symlink_leading_path(const char *name, int len); +extern int threaded_has_symlink_leading_path(struct cache_def *, const char *, int); +extern int has_symlink_or_noent_leading_path(const char *name, int len); +extern int has_dirs_only_path(const char *name, int len, int prefix_len); +extern void invalidate_lstat_cache(const char *name, int len); +extern void clear_lstat_cache(void); +extern void schedule_dir_for_removal(const char *name, int len); +extern void remove_scheduled_dirs(void); extern struct alternate_object_database { struct alternate_object_database *next; @@ -652,6 +773,8 @@ extern struct alternate_object_database { } *alt_odb_list; extern void prepare_alt_odb(void); extern void add_to_alternates_file(const char *reference); +typedef int alt_odb_fn(struct alternate_object_database *, void *); +extern void foreach_alt_odb(alt_odb_fn, void*); struct pack_window { struct pack_window *next; @@ -714,14 +837,18 @@ struct ref { #define REF_HEADS (1u << 1) #define REF_TAGS (1u << 2) -extern struct ref *find_ref_by_name(struct ref *list, const char *name); +extern struct ref *find_ref_by_name(const struct ref *list, const char *name); #define CONNECT_VERBOSE (1u << 0) extern struct child_process *git_connect(int fd[2], const char *url, const char *prog, int flags); extern int finish_connect(struct child_process *conn); extern int path_match(const char *path, int nr, char **match); extern int get_ack(int fd, unsigned char *result_sha1); -extern struct ref **get_remote_heads(int in, struct ref **list, int nr_match, char **match, unsigned int flags); +struct extra_have_objects { + int nr, alloc; + unsigned char (*array)[20]; +}; +extern struct ref **get_remote_heads(int in, struct ref **list, int nr_match, char **match, unsigned int flags, struct extra_have_objects *); extern int server_supports(const char *feature); extern struct packed_git *parse_pack_index(unsigned char *sha1); @@ -735,7 +862,7 @@ extern struct packed_git *find_sha1_pack(const unsigned char *sha1, extern void pack_report(void); extern int open_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 int *); extern void close_pack_windows(struct packed_git *); extern void unuse_pack(struct pack_window **); extern void free_pack_by_name(const char *); @@ -745,10 +872,9 @@ extern const unsigned char *nth_packed_object_sha1(struct packed_git *, uint32_t extern off_t nth_packed_object_offset(const struct packed_git *, uint32_t); extern off_t find_pack_entry_one(const unsigned char *, struct packed_git *); extern void *unpack_entry(struct packed_git *, off_t, enum object_type *, unsigned long *); -extern unsigned long unpack_object_header_gently(const unsigned char *buf, unsigned long len, enum object_type *type, unsigned long *sizep); +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 matches_pack_name(struct packed_git *p, const char *name); /* Dumb servers support */ extern int update_server_info(int); @@ -757,7 +883,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 int git_config(config_fn_t fn, void *); -extern int git_parse_long(const char *, long *); extern int git_parse_ulong(const char *, unsigned long *); extern int git_config_int(const char *, const char *); extern unsigned long git_config_ulong(const char *, const char *); @@ -781,6 +906,7 @@ extern int user_ident_explicitly_given; extern const char *git_commit_encoding; extern const char *git_log_output_encoding; +extern const char *git_mailmap_file; /* IO helper functions */ extern void maybe_flush_or_die(FILE *, const char *); @@ -858,7 +984,6 @@ extern int ws_fix_copy(char *, const char *, int, unsigned, int *); extern int ws_blank_line(const char *line, int len, unsigned ws_rule); /* ls-files */ -int pathspec_match(const char **spec, char *matched, const char *filename, int skiplen); int report_path_error(const char *ps_matched, const char **pathspec, int prefix_offset); void overlay_tree_on_cache(const char *tree_name, const char *prefix); |