Hash :
e54343a4
Author :
Date :
2019-06-29T09:17:32
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191
/*
* Copyright (C) the libgit2 contributors. All rights reserved.
*
* This file is part of libgit2, distributed under the GNU GPL v2 with
* a Linking Exception. For full terms see the included COPYING file.
*/
#ifndef INCLUDE_index_h__
#define INCLUDE_index_h__
#include "common.h"
#include "futils.h"
#include "filebuf.h"
#include "vector.h"
#include "idxmap.h"
#include "tree-cache.h"
#include "git2/odb.h"
#include "git2/index.h"
#define GIT_INDEX_FILE "index"
#define GIT_INDEX_FILE_MODE 0666
extern bool git_index__enforce_unsaved_safety;
struct git_index {
git_refcount rc;
char *index_file_path;
git_futils_filestamp stamp;
git_oid checksum; /* checksum at the end of the file */
git_vector entries;
git_idxmap *entries_map;
git_vector deleted; /* deleted entries if readers > 0 */
git_atomic readers; /* number of active iterators */
unsigned int on_disk:1;
unsigned int ignore_case:1;
unsigned int distrust_filemode:1;
unsigned int no_symlinks:1;
unsigned int dirty:1; /* whether we have unsaved changes */
git_tree_cache *tree;
git_pool tree_pool;
git_vector names;
git_vector reuc;
git_vector_cmp entries_cmp_path;
git_vector_cmp entries_search;
git_vector_cmp entries_search_path;
git_vector_cmp reuc_search;
unsigned int version;
};
struct git_index_iterator {
git_index *index;
git_vector snap;
size_t cur;
};
struct git_index_conflict_iterator {
git_index *index;
size_t cur;
};
extern void git_index_entry__init_from_stat(
git_index_entry *entry, struct stat *st, bool trust_mode);
/* Index entry comparison functions for array sorting */
extern int git_index_entry_cmp(const void *a, const void *b);
extern int git_index_entry_icmp(const void *a, const void *b);
/* Index entry search functions for search using a search spec */
extern int git_index_entry_srch(const void *a, const void *b);
extern int git_index_entry_isrch(const void *a, const void *b);
/* Index time handling functions */
GIT_INLINE(bool) git_index_time_eq(const git_index_time *one, const git_index_time *two)
{
if (one->seconds != two->seconds)
return false;
#ifdef GIT_USE_NSEC
if (one->nanoseconds != two->nanoseconds)
return false;
#endif
return true;
}
/*
* Test if the given index time is newer than the given existing index entry.
* If the timestamps are exactly equivalent, then the given index time is
* considered "racily newer" than the existing index entry.
*/
GIT_INLINE(bool) git_index_entry_newer_than_index(
const git_index_entry *entry, git_index *index)
{
/* If we never read the index, we can't have this race either */
if (!index || index->stamp.mtime.tv_sec == 0)
return false;
/* If the timestamp is the same or newer than the index, it's racy */
#if defined(GIT_USE_NSEC)
if ((int32_t)index->stamp.mtime.tv_sec < entry->mtime.seconds)
return true;
else if ((int32_t)index->stamp.mtime.tv_sec > entry->mtime.seconds)
return false;
else
return (uint32_t)index->stamp.mtime.tv_nsec <= entry->mtime.nanoseconds;
#else
return ((int32_t)index->stamp.mtime.tv_sec) <= entry->mtime.seconds;
#endif
}
/* Search index for `path`, returning GIT_ENOTFOUND if it does not exist
* (but not setting an error message).
*
* `at_pos` is set to the position where it is or would be inserted.
* Pass `path_len` as strlen of path or 0 to call strlen internally.
*/
extern int git_index__find_pos(
size_t *at_pos, git_index *index, const char *path, size_t path_len, int stage);
extern int git_index__fill(git_index *index, const git_vector *source_entries);
extern void git_index__set_ignore_case(git_index *index, bool ignore_case);
extern unsigned int git_index__create_mode(unsigned int mode);
GIT_INLINE(const git_futils_filestamp *) git_index__filestamp(git_index *index)
{
return &index->stamp;
}
extern int git_index__changed_relative_to(git_index *index, const git_oid *checksum);
/* Copy the current entries vector *and* increment the index refcount.
* Call `git_index__release_snapshot` when done.
*/
extern int git_index_snapshot_new(git_vector *snap, git_index *index);
extern void git_index_snapshot_release(git_vector *snap, git_index *index);
/* Allow searching in a snapshot; entries must already be sorted! */
extern int git_index_snapshot_find(
size_t *at_pos, git_vector *snap, git_vector_cmp entry_srch,
const char *path, size_t path_len, int stage);
/* Replace an index with a new index */
int git_index_read_index(git_index *index, const git_index *new_index);
GIT_INLINE(int) git_index_is_dirty(git_index *index)
{
return index->dirty;
}
extern int git_index_read_safely(git_index *index);
typedef struct {
git_index *index;
git_filebuf file;
unsigned int should_write:1;
} git_indexwriter;
#define GIT_INDEXWRITER_INIT { NULL, GIT_FILEBUF_INIT }
/* Lock the index for eventual writing. */
extern int git_indexwriter_init(git_indexwriter *writer, git_index *index);
/* Lock the index for eventual writing by a repository operation: a merge,
* revert, cherry-pick or a rebase. Note that the given checkout strategy
* will be updated for the operation's use so that checkout will not write
* the index.
*/
extern int git_indexwriter_init_for_operation(
git_indexwriter *writer,
git_repository *repo,
unsigned int *checkout_strategy);
/* Write the index and unlock it. */
extern int git_indexwriter_commit(git_indexwriter *writer);
/* Cleanup an index writing session, unlocking the file (if it is still
* locked and freeing any data structures.
*/
extern void git_indexwriter_cleanup(git_indexwriter *writer);
#endif