Skip to content

Commit

Permalink
[client] Folder/file sync status for Mac and Linux.
Browse files Browse the repository at this point in the history
  • Loading branch information
killing committed May 19, 2015
1 parent 07c4266 commit 0be2a68
Show file tree
Hide file tree
Showing 6 changed files with 691 additions and 191 deletions.
127 changes: 127 additions & 0 deletions common/index/index.c
Expand Up @@ -1512,6 +1512,133 @@ add_empty_dir_to_index_with_check (struct index_state *istate,
return 0;
}

inline static gboolean
is_duplicate_dirent (GList *dirents, const char *dname)
{
if (!dirents)
return FALSE;

IndexDirent *dent = dirents->data;

return (strcmp(dent->dname, dname) == 0);
}

static IndexDirent *
index_dirent_new (char *dname, gboolean is_dir, struct cache_entry *ce)
{
IndexDirent *dent = g_new0 (IndexDirent, 1);
dent->dname = dname;
dent->is_dir = is_dir;
if (!is_dir)
dent->ce = ce;
return dent;
}

void
index_dirent_free (IndexDirent *dent)
{
if (!dent)
return;

g_free (dent->dname);
g_free (dent);
}

static gint
compare_index_dents (gconstpointer a, gconstpointer b)
{
const IndexDirent *denta = a, *dentb = b;

return (strcmp(denta->dname, dentb->dname));
}

GList *
list_dirents_from_index (struct index_state *istate, const char *dir)
{
char *full_dir;
int pathlen;
int pos;
struct cache_entry *ce;
GList *dirents = NULL;
char *path, *slash, *dname;
gboolean is_dir;
IndexDirent *dirent;

if (dir[0] == 0) {
pos = 0;
full_dir = g_strdup(dir);
pathlen = 0;
goto collect_dents;
} else {
pathlen = strlen(dir);
pos = index_name_pos (istate, dir, pathlen);
}

/* Exact match, it's an empty dir. */
if (pos >= 0) {
return NULL;
}

/* Otherwise it may be a prefix match, there may be dirents under the dir.
*/

/* -pos = (the position this entry *should* be) + 1.
* So -pos-1 is the first entry larger than this entry.
*/
pos = -pos-1;

/* Add '/' to the end of prefix so that we won't match a partial path component.
* e.g. we don't want to match 'abc' with 'abcd/ef'
*/
full_dir = g_strconcat (dir, "/", NULL);
++pathlen;

while (pos < istate->cache_nr) {
ce = istate->cache[pos];
if (strncmp (ce->name, full_dir, pathlen) < 0) {
++pos;
} else
break;
}

/* The dir actually doesn't exist. */
if (pos == istate->cache_nr) {
g_free (full_dir);
return NULL;
}

collect_dents:
for (; pos < istate->cache_nr; ++pos) {
ce = istate->cache[pos];

if (strncmp (full_dir, ce->name, pathlen) != 0)
break;

path = ce->name + pathlen;
slash = strchr(path, '/');
if (slash) {
dname = g_strndup(path, slash - path);
if (is_duplicate_dirent (dirents, dname)) {
g_free (dname);
continue;
}

dirent = index_dirent_new (dname, TRUE, NULL);
dirents = g_list_prepend (dirents, dirent);
} else {
dname = g_strdup(path);
is_dir = S_ISDIR(ce->ce_mode);
dirent = index_dirent_new (dname, is_dir, ce);
dirents = g_list_prepend (dirents, dirent);
}
}

dirents = g_list_sort (dirents, compare_index_dents);

g_free (full_dir);
return dirents;
}

static struct cache_entry *refresh_cache_entry(struct cache_entry *ce,
const char *full_path)
{
Expand Down
13 changes: 13 additions & 0 deletions common/index/index.h
Expand Up @@ -458,6 +458,19 @@ add_empty_dir_to_index_with_check (struct index_state *istate,

void remove_empty_parent_dir_entry (struct index_state *istate, const char *path);

struct _IndexDirent {
char *dname;
gboolean is_dir;
struct cache_entry *ce;
};
typedef struct _IndexDirent IndexDirent;

void
index_dirent_free (IndexDirent *dent);

GList *
list_dirents_from_index (struct index_state *istate, const char *dir);

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, const char *full_path, int stage, int refresh);
extern int ce_same_name(struct cache_entry *a, struct cache_entry *b);
Expand Down

0 comments on commit 0be2a68

Please sign in to comment.