b7b189cd5a
We had a handful of headers including cache.h that didn't need to anymore. Drop those includes and replace them with includes of smaller files, or forward declarations. However, note that two .c files now need to directly include cache.h, though they should have been including it all along given they are directly using structs defined in it. Signed-off-by: Elijah Newren <newren@gmail.com> Acked-by: Calvin Wan <calvinwan@google.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
97 lines
1.9 KiB
C
97 lines
1.9 KiB
C
#include "git-compat-util.h"
|
|
#include "abspath.h"
|
|
#include "chdir-notify.h"
|
|
#include "list.h"
|
|
#include "path.h"
|
|
#include "strbuf.h"
|
|
#include "trace.h"
|
|
|
|
struct chdir_notify_entry {
|
|
const char *name;
|
|
chdir_notify_callback cb;
|
|
void *data;
|
|
struct list_head list;
|
|
};
|
|
static LIST_HEAD(chdir_notify_entries);
|
|
|
|
void chdir_notify_register(const char *name,
|
|
chdir_notify_callback cb,
|
|
void *data)
|
|
{
|
|
struct chdir_notify_entry *e = xmalloc(sizeof(*e));
|
|
e->name = name;
|
|
e->cb = cb;
|
|
e->data = data;
|
|
list_add_tail(&e->list, &chdir_notify_entries);
|
|
}
|
|
|
|
static void reparent_cb(const char *name,
|
|
const char *old_cwd,
|
|
const char *new_cwd,
|
|
void *data)
|
|
{
|
|
char **path = data;
|
|
char *tmp = *path;
|
|
|
|
if (!tmp)
|
|
return;
|
|
|
|
*path = reparent_relative_path(old_cwd, new_cwd, tmp);
|
|
free(tmp);
|
|
|
|
if (name) {
|
|
trace_printf_key(&trace_setup_key,
|
|
"setup: reparent %s to '%s'",
|
|
name, *path);
|
|
}
|
|
}
|
|
|
|
void chdir_notify_reparent(const char *name, char **path)
|
|
{
|
|
chdir_notify_register(name, reparent_cb, path);
|
|
}
|
|
|
|
int chdir_notify(const char *new_cwd)
|
|
{
|
|
struct strbuf old_cwd = STRBUF_INIT;
|
|
struct list_head *pos;
|
|
|
|
if (strbuf_getcwd(&old_cwd) < 0)
|
|
return -1;
|
|
if (chdir(new_cwd) < 0) {
|
|
int saved_errno = errno;
|
|
strbuf_release(&old_cwd);
|
|
errno = saved_errno;
|
|
return -1;
|
|
}
|
|
|
|
trace_printf_key(&trace_setup_key,
|
|
"setup: chdir from '%s' to '%s'",
|
|
old_cwd.buf, new_cwd);
|
|
|
|
list_for_each(pos, &chdir_notify_entries) {
|
|
struct chdir_notify_entry *e =
|
|
list_entry(pos, struct chdir_notify_entry, list);
|
|
e->cb(e->name, old_cwd.buf, new_cwd, e->data);
|
|
}
|
|
|
|
strbuf_release(&old_cwd);
|
|
return 0;
|
|
}
|
|
|
|
char *reparent_relative_path(const char *old_cwd,
|
|
const char *new_cwd,
|
|
const char *path)
|
|
{
|
|
char *ret, *full;
|
|
|
|
if (is_absolute_path(path))
|
|
return xstrdup(path);
|
|
|
|
full = xstrfmt("%s/%s", old_cwd, path);
|
|
ret = xstrdup(remove_leading_path(full, new_cwd));
|
|
free(full);
|
|
|
|
return ret;
|
|
}
|