expose a helper function peel_to_type().
[gitweb.git] / cache.h
diff --git a/cache.h b/cache.h
index e5ea637c2941550624ac49a12a7ea64e44b3c2d3..4bfb1ba4999be5e8cf92dcf5ec585528088b8c56 100644 (file)
--- a/cache.h
+++ b/cache.h
@@ -3,6 +3,7 @@
 
 #include "git-compat-util.h"
 #include "strbuf.h"
+#include "hash.h"
 
 #include SHA1_HEADER
 #include <zlib.h>
@@ -94,66 +95,116 @@ struct cache_time {
  * We save the fields in big-endian order to allow using the
  * index file over NFS transparently.
  */
+struct ondisk_cache_entry {
+       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;
+       char name[FLEX_ARRAY]; /* more */
+};
+
 struct cache_entry {
-       struct cache_time ce_ctime;
-       struct cache_time ce_mtime;
+       struct cache_entry *next;
+       unsigned int ce_ctime;
+       unsigned int ce_mtime;
        unsigned int ce_dev;
        unsigned int ce_ino;
        unsigned int ce_mode;
        unsigned int ce_uid;
        unsigned int ce_gid;
        unsigned int ce_size;
+       unsigned int ce_flags;
        unsigned char sha1[20];
-       unsigned short ce_flags;
        char name[FLEX_ARRAY]; /* more */
 };
 
 #define CE_NAMEMASK  (0x0fff)
 #define CE_STAGEMASK (0x3000)
-#define CE_UPDATE    (0x4000)
 #define CE_VALID     (0x8000)
 #define CE_STAGESHIFT 12
 
-#define create_ce_flags(len, stage) htons((len) | ((stage) << CE_STAGESHIFT))
-#define ce_namelen(ce) (CE_NAMEMASK & ntohs((ce)->ce_flags))
+/* In-memory only */
+#define CE_UPDATE    (0x10000)
+#define CE_REMOVE    (0x20000)
+#define CE_UPTODATE  (0x40000)
+#define CE_UNHASHED  (0x80000)
+
+static inline unsigned create_ce_flags(size_t len, unsigned stage)
+{
+       if (len >= CE_NAMEMASK)
+               len = CE_NAMEMASK;
+       return (len | (stage << CE_STAGESHIFT));
+}
+
+static inline size_t ce_namelen(const struct cache_entry *ce)
+{
+       size_t len = ce->ce_flags & CE_NAMEMASK;
+       if (len < CE_NAMEMASK)
+               return len;
+       return strlen(ce->name + CE_NAMEMASK) + CE_NAMEMASK;
+}
+
 #define ce_size(ce) cache_entry_size(ce_namelen(ce))
-#define ce_stage(ce) ((CE_STAGEMASK & ntohs((ce)->ce_flags)) >> CE_STAGESHIFT)
+#define ondisk_ce_size(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)
 
 #define ce_permissions(mode) (((mode) & 0100) ? 0755 : 0644)
 static inline unsigned int create_ce_mode(unsigned int mode)
 {
        if (S_ISLNK(mode))
-               return htonl(S_IFLNK);
+               return S_IFLNK;
        if (S_ISDIR(mode) || S_ISGITLINK(mode))
-               return htonl(S_IFGITLINK);
-       return htonl(S_IFREG | ce_permissions(mode));
+               return S_IFGITLINK;
+       return S_IFREG | ce_permissions(mode);
 }
 static inline unsigned int ce_mode_from_stat(struct cache_entry *ce, unsigned int mode)
 {
        extern int trust_executable_bit, has_symlinks;
        if (!has_symlinks && S_ISREG(mode) &&
-           ce && S_ISLNK(ntohl(ce->ce_mode)))
+           ce && S_ISLNK(ce->ce_mode))
                return ce->ce_mode;
        if (!trust_executable_bit && S_ISREG(mode)) {
-               if (ce && S_ISREG(ntohl(ce->ce_mode)))
+               if (ce && S_ISREG(ce->ce_mode))
                        return ce->ce_mode;
                return create_ce_mode(0666);
        }
        return create_ce_mode(mode);
 }
+static inline int ce_to_dtype(const struct cache_entry *ce)
+{
+       unsigned ce_mode = ntohl(ce->ce_mode);
+       if (S_ISREG(ce_mode))
+               return DT_REG;
+       else if (S_ISDIR(ce_mode) || S_ISGITLINK(ce_mode))
+               return DT_DIR;
+       else if (S_ISLNK(ce_mode))
+               return DT_LNK;
+       else
+               return DT_UNKNOWN;
+}
 #define canon_mode(mode) \
        (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)
 
 struct index_state {
        struct cache_entry **cache;
        unsigned int cache_nr, cache_alloc, cache_changed;
        struct cache_tree *cache_tree;
        time_t timestamp;
-       void *mmap;
-       size_t mmap_size;
+       void *alloc;
+       unsigned name_hash_initialized : 1;
+       struct hash_table name_hash;
 };
 
 extern struct index_state the_index;
@@ -175,8 +226,9 @@ extern struct index_state the_index;
 #define remove_file_from_cache(path) remove_file_from_index(&the_index, (path))
 #define add_file_to_cache(path, verbose) add_file_to_index(&the_index, (path), (verbose))
 #define refresh_cache(flags) refresh_index(&the_index, (flags), NULL, NULL)
-#define ce_match_stat(ce, st, really) ie_match_stat(&the_index, (ce), (st), (really))
-#define ce_modified(ce, st, really) ie_modified(&the_index, (ce), (st), (really))
+#define ce_match_stat(ce, st, options) ie_match_stat(&the_index, (ce), (st), (options))
+#define ce_modified(ce, st, options) ie_modified(&the_index, (ce), (st), (options))
+#define cache_name_exists(name, namelen) index_name_exists(&the_index, (name), (namelen))
 #endif
 
 enum object_type {
@@ -192,6 +244,13 @@ enum object_type {
        OBJ_MAX,
 };
 
+static inline enum object_type object_type(unsigned int mode)
+{
+       return S_ISDIR(mode) ? OBJ_TREE :
+               S_ISGITLINK(mode) ? OBJ_COMMIT :
+               OBJ_BLOB;
+}
+
 #define GIT_DIR_ENVIRONMENT "GIT_DIR"
 #define GIT_WORK_TREE_ENVIRONMENT "GIT_WORK_TREE"
 #define DEFAULT_GIT_DIR_ENVIRONMENT ".git"
@@ -256,6 +315,7 @@ extern int read_index_from(struct index_state *, const char *path);
 extern int write_index(struct index_state *, int newfd);
 extern int discard_index(struct index_state *);
 extern int verify_path(const char *path);
+extern int index_name_exists(struct index_state *istate, const char *name, int namelen);
 extern int index_name_pos(struct index_state *, const char *name, int namelen);
 #define ADD_CACHE_OK_TO_ADD 1          /* Ok to add */
 #define ADD_CACHE_OK_TO_REPLACE 2      /* Ok to replace file/directory */
@@ -268,8 +328,14 @@ extern int remove_file_from_index(struct index_state *, const char *path);
 extern int add_file_to_index(struct index_state *, const char *path, int verbose);
 extern struct cache_entry *make_cache_entry(unsigned int mode, const unsigned char *sha1, const char *path, int stage, int refresh);
 extern int ce_same_name(struct cache_entry *a, struct cache_entry *b);
-extern int ie_match_stat(struct index_state *, struct cache_entry *, struct stat *, int);
-extern int ie_modified(struct index_state *, struct cache_entry *, struct stat *, int);
+
+/* do stat comparison even if CE_VALID is true */
+#define CE_MATCH_IGNORE_VALID          01
+/* do not check the contents but report dirty on racily-clean entries */
+#define CE_MATCH_RACY_IS_DIRTY 02
+extern int ie_match_stat(struct index_state *, struct cache_entry *, struct stat *, unsigned int);
+extern int ie_modified(struct index_state *, struct cache_entry *, struct stat *, unsigned int);
+
 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);
@@ -284,6 +350,7 @@ extern int refresh_index(struct index_state *, unsigned int flags, const char **
 
 struct lock_file {
        struct lock_file *next;
+       int fd;
        pid_t owner;
        char on_list;
        char filename[PATH_MAX];
@@ -294,7 +361,7 @@ extern int commit_lock_file(struct lock_file *);
 extern int hold_locked_index(struct lock_file *, int);
 extern int commit_locked_index(struct lock_file *);
 extern void set_alternate_index_output(const char *);
-
+extern int close_lock_file(struct lock_file *);
 extern void rollback_lock_file(struct lock_file *);
 extern int delete_ref(const char *, const unsigned char *sha1);
 
@@ -316,6 +383,14 @@ extern size_t packed_git_limit;
 extern size_t delta_base_cache_limit;
 extern int auto_crlf;
 
+enum safe_crlf {
+       SAFE_CRLF_FALSE = 0,
+       SAFE_CRLF_FAIL = 1,
+       SAFE_CRLF_WARN = 2,
+};
+
+extern enum safe_crlf safe_crlf;
+
 #define GIT_REPO_VERSION 0
 extern int repository_format_version;
 extern int check_repository_format(void);
@@ -409,6 +484,10 @@ 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 refname_match(const char *abbrev_name, const char *full_name, const char **rules);
+extern const char *ref_rev_parse_rules[];
+extern const char *ref_fetch_rules[];
+
 extern int create_symref(const char *ref, const char *refs_heads_master, const char *logmsg);
 extern int validate_headref(const char *ref);
 
@@ -420,6 +499,9 @@ extern void *read_object_with_reference(const unsigned char *sha1,
                                        unsigned long *size,
                                        unsigned char *sha1_ret);
 
+extern struct object *peel_to_type(const char *name, int namelen,
+                                  struct object *o, enum object_type);
+
 enum date_mode {
        DATE_NORMAL = 0,
        DATE_RELATIVE,
@@ -435,9 +517,13 @@ void datestamp(char *buf, int bufsize);
 unsigned long approxidate(const char *);
 enum date_mode parse_date_format(const char *format);
 
+#define IDENT_WARN_ON_NO_NAME  1
+#define IDENT_ERROR_ON_NO_NAME 2
+#define IDENT_NO_DATE         4
 extern const char *git_author_info(int);
 extern const char *git_committer_info(int);
 extern const char *fmt_ident(const char *name, const char *email, const char *date_str, int);
+extern const char *fmt_name(const char *name, const char *email);
 
 struct checkout {
        const char *base_dir;
@@ -493,8 +579,20 @@ struct ref {
        struct ref *next;
        unsigned char old_sha1[20];
        unsigned char new_sha1[20];
-       unsigned char force;
-       unsigned char merge;
+       unsigned int force:1,
+               merge:1,
+               nonfastforward:1,
+               deletion:1;
+       enum {
+               REF_STATUS_NONE = 0,
+               REF_STATUS_OK,
+               REF_STATUS_REJECT_NONFASTFORWARD,
+               REF_STATUS_REJECT_NODELETE,
+               REF_STATUS_UPTODATE,
+               REF_STATUS_REMOTE_REJECT,
+               REF_STATUS_EXPECTING_REPORT,
+       } status;
+       char *remote_status;
        struct ref *peer_ref; /* when renaming */
        char name[FLEX_ARRAY]; /* more */
 };
@@ -503,6 +601,8 @@ 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);
+
 #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);
@@ -525,6 +625,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 void close_pack_windows(struct packed_git *);
 extern void unuse_pack(struct pack_window **);
 extern struct packed_git *add_packed_git(const char *, int, int);
 extern const unsigned char *nth_packed_object_sha1(struct packed_git *, uint32_t);
@@ -547,10 +648,16 @@ 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 *);
 extern int git_config_bool(const char *, const char *);
+extern int git_config_string(const char **, const char *, const char *);
 extern int git_config_set(const char *, const char *);
 extern int git_config_set_multivar(const char *, const char *, const char *, int);
 extern int git_config_rename_section(const char *, const char *);
+extern const char *git_etc_gitconfig(void);
 extern int check_repository_format_version(const char *var, const char *value);
+extern int git_env_bool(const char *, int);
+extern int git_config_system(void);
+extern int git_config_global(void);
+extern int config_error_nonbool(const char *);
 
 #define MAX_GITNAME (1000)
 extern char git_default_email[MAX_GITNAME];
@@ -570,11 +677,12 @@ extern int write_or_whine_pipe(int fd, const void *buf, size_t count, const char
 
 /* pager.c */
 extern void setup_pager(void);
-extern char *pager_program;
-extern int pager_in_use;
+extern const char *pager_program;
+extern int pager_in_use(void);
 extern int pager_use_color;
 
-extern char *editor_program;
+extern const char *editor_program;
+extern const char *excludes_file;
 
 /* base85 */
 int decode_85(char *dst, const char *line, int linelen);
@@ -590,17 +698,42 @@ extern void alloc_report(void);
 
 /* trace.c */
 extern void trace_printf(const char *format, ...);
-extern void trace_argv_printf(const char **argv, int count, const char *format, ...);
+extern void trace_argv_printf(const char **argv, const char *format, ...);
 
 /* 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);
+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);
 
+/* add */
+void add_files_to_cache(int verbose, const char *prefix, const char **pathspec);
+
 /* diff.c */
 extern int diff_auto_refresh_index;
 
 /* match-trees.c */
 void shift_tree(const unsigned char *, const unsigned char *, unsigned char *, int);
 
+/*
+ * whitespace rules.
+ * used by both diff and apply
+ */
+#define WS_TRAILING_SPACE      01
+#define WS_SPACE_BEFORE_TAB    02
+#define WS_INDENT_WITH_NON_TAB 04
+#define WS_DEFAULT_RULE (WS_TRAILING_SPACE|WS_SPACE_BEFORE_TAB)
+extern unsigned whitespace_rule_cfg;
+extern unsigned whitespace_rule(const char *);
+extern unsigned parse_whitespace_rule(const char *);
+extern unsigned check_and_emit_line(const char *line, int len, unsigned ws_rule,
+    FILE *stream, const char *set,
+    const char *reset, const char *ws);
+extern char *whitespace_error_string(unsigned ws);
+
+/* 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);
+
 #endif /* CACHE_H */