2017-06-06 17:45:44 -07:00
|
|
|
#ifdef HAVE_CONFIG_H
|
|
|
|
# include "config.h"
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#include <Eina.h>
|
|
|
|
#include <Ecore.h>
|
|
|
|
#include <Ecore_File.h>
|
2017-06-07 22:38:21 -07:00
|
|
|
#include <Ethumb.h>
|
2017-06-06 17:45:44 -07:00
|
|
|
|
|
|
|
#include "Edi.h"
|
|
|
|
#include "edi_private.h"
|
2017-06-07 22:38:21 -07:00
|
|
|
#include "edi_exe.h"
|
2017-06-06 17:45:44 -07:00
|
|
|
#include "edi_path.h"
|
|
|
|
#include "edi_scm.h"
|
2017-06-07 22:38:21 -07:00
|
|
|
#include "md5.h"
|
2017-06-06 17:45:44 -07:00
|
|
|
|
|
|
|
Edi_Scm_Engine *_edi_scm_global_object = NULL;
|
|
|
|
|
|
|
|
static int
|
|
|
|
_edi_scm_exec(const char *command)
|
|
|
|
{
|
|
|
|
int code;
|
|
|
|
char *oldpwd;
|
|
|
|
Edi_Scm_Engine *self = _edi_scm_global_object;
|
|
|
|
|
|
|
|
if (!self) return -1;
|
|
|
|
|
|
|
|
oldpwd = getcwd(NULL, PATH_MAX);
|
|
|
|
|
2017-12-28 15:44:28 -08:00
|
|
|
chdir(self->root_directory);
|
2017-06-06 17:45:44 -07:00
|
|
|
code = edi_exe_wait(command);
|
|
|
|
chdir(oldpwd);
|
|
|
|
|
|
|
|
free(oldpwd);
|
|
|
|
|
|
|
|
return code;
|
|
|
|
}
|
|
|
|
|
|
|
|
static char *
|
|
|
|
_edi_scm_exec_response(const char *command)
|
|
|
|
{
|
|
|
|
char *oldpwd, *response;
|
|
|
|
Edi_Scm_Engine *self = _edi_scm_global_object;
|
|
|
|
|
|
|
|
if (!self) return NULL;
|
|
|
|
|
|
|
|
oldpwd = getcwd(NULL, PATH_MAX);
|
|
|
|
|
2017-12-28 15:44:28 -08:00
|
|
|
chdir(self->root_directory);
|
2017-06-06 17:45:44 -07:00
|
|
|
response = edi_exe_response(command);
|
|
|
|
chdir(oldpwd);
|
|
|
|
|
|
|
|
free(oldpwd);
|
|
|
|
|
|
|
|
return response;
|
|
|
|
}
|
|
|
|
|
|
|
|
EAPI int
|
|
|
|
edi_scm_git_new(void)
|
|
|
|
{
|
2017-09-16 12:41:46 -07:00
|
|
|
int code;
|
|
|
|
char *oldpwd;
|
|
|
|
|
|
|
|
oldpwd = getcwd(NULL, PATH_MAX);
|
|
|
|
|
|
|
|
chdir(edi_project_get());
|
|
|
|
code = edi_exe_wait("git init .");
|
|
|
|
chdir(oldpwd);
|
|
|
|
|
|
|
|
free(oldpwd);
|
|
|
|
|
|
|
|
return code;
|
2017-06-06 17:45:44 -07:00
|
|
|
}
|
|
|
|
|
2017-06-08 23:13:02 -07:00
|
|
|
EAPI int
|
|
|
|
edi_scm_git_clone(const char *url, const char *dir)
|
|
|
|
{
|
|
|
|
int code;
|
|
|
|
Eina_Strbuf *command = eina_strbuf_new();
|
|
|
|
|
|
|
|
eina_strbuf_append_printf(command, "git clone '%s' '%s'", url, dir);
|
|
|
|
code = edi_exe_wait(eina_strbuf_string_get(command));
|
|
|
|
|
|
|
|
eina_strbuf_free(command);
|
|
|
|
return code;
|
|
|
|
}
|
|
|
|
|
2017-06-06 17:45:44 -07:00
|
|
|
static int
|
2017-12-20 13:47:21 -08:00
|
|
|
_edi_scm_git_file_stage(const char *path)
|
2017-06-06 17:45:44 -07:00
|
|
|
{
|
|
|
|
int code;
|
|
|
|
Eina_Strbuf *command = eina_strbuf_new();
|
|
|
|
|
2017-09-27 11:42:45 -07:00
|
|
|
eina_strbuf_append_printf(command, "git add %s", path);
|
2017-06-06 17:45:44 -07:00
|
|
|
|
|
|
|
code = _edi_scm_exec(eina_strbuf_string_get(command));
|
|
|
|
|
|
|
|
eina_strbuf_free(command);
|
|
|
|
|
|
|
|
return code;
|
|
|
|
}
|
|
|
|
|
2017-12-20 13:47:21 -08:00
|
|
|
static int
|
|
|
|
_edi_scm_git_file_unstage(const char *path)
|
|
|
|
{
|
|
|
|
int code;
|
|
|
|
Eina_Strbuf *command = eina_strbuf_new();
|
|
|
|
|
|
|
|
eina_strbuf_append_printf(command, "git reset HEAD %s", path);
|
|
|
|
|
|
|
|
code = _edi_scm_exec(eina_strbuf_string_get(command));
|
|
|
|
|
|
|
|
eina_strbuf_free(command);
|
|
|
|
|
|
|
|
return code;
|
|
|
|
}
|
|
|
|
|
2017-06-06 17:45:44 -07:00
|
|
|
static int
|
|
|
|
_edi_scm_git_file_mod(const char *path)
|
|
|
|
{
|
|
|
|
int code;
|
|
|
|
Eina_Strbuf *command = eina_strbuf_new();
|
|
|
|
|
2017-09-27 11:42:45 -07:00
|
|
|
eina_strbuf_append_printf(command, "git mod %s", path);
|
2017-06-06 17:45:44 -07:00
|
|
|
|
|
|
|
code = _edi_scm_exec(eina_strbuf_string_get(command));
|
|
|
|
|
|
|
|
eina_strbuf_free(command);
|
|
|
|
|
|
|
|
return code;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
_edi_scm_git_file_move(const char *source, const char *dest)
|
|
|
|
{
|
|
|
|
int code;
|
|
|
|
Eina_Strbuf *command = eina_strbuf_new();
|
|
|
|
|
|
|
|
eina_strbuf_append_printf(command, "git mv %s %s", source, dest);
|
|
|
|
|
|
|
|
code = _edi_scm_exec(eina_strbuf_string_get(command));
|
|
|
|
|
|
|
|
eina_strbuf_free(command);
|
|
|
|
|
|
|
|
return code;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
_edi_scm_git_file_del(const char *path)
|
|
|
|
{
|
|
|
|
int code;
|
|
|
|
Eina_Strbuf *command = eina_strbuf_new();
|
|
|
|
|
2017-09-27 11:42:45 -07:00
|
|
|
eina_strbuf_append_printf(command, "git rm %s", path);
|
2017-06-06 17:45:44 -07:00
|
|
|
|
|
|
|
code = _edi_scm_exec(eina_strbuf_string_get(command));
|
|
|
|
|
|
|
|
eina_strbuf_free(command);
|
|
|
|
|
|
|
|
return code;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
_edi_scm_git_status(void)
|
|
|
|
{
|
|
|
|
int code;
|
|
|
|
Eina_Strbuf *command = eina_strbuf_new();
|
|
|
|
|
|
|
|
eina_strbuf_append(command, "git status");
|
|
|
|
|
|
|
|
code = _edi_scm_exec(eina_strbuf_string_get(command));
|
|
|
|
|
|
|
|
eina_strbuf_free(command);
|
|
|
|
|
|
|
|
return code;
|
|
|
|
}
|
|
|
|
|
2017-06-17 04:59:10 -07:00
|
|
|
static Edi_Scm_Status *
|
|
|
|
_parse_line(char *line)
|
|
|
|
{
|
2017-09-27 11:42:45 -07:00
|
|
|
char *esc_path, *path, *fullpath, *change;
|
2017-06-17 04:59:10 -07:00
|
|
|
Edi_Scm_Status *status;
|
|
|
|
|
|
|
|
change = line;
|
|
|
|
line[2] = '\0';
|
|
|
|
path = line + 3;
|
|
|
|
|
|
|
|
status = malloc(sizeof(Edi_Scm_Status));
|
|
|
|
if (!status)
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
status->staged = EINA_FALSE;
|
|
|
|
|
|
|
|
if (change[0] == 'A' || change[1] == 'A')
|
|
|
|
{
|
|
|
|
status->change = EDI_SCM_STATUS_ADDED;
|
2017-09-15 17:19:54 -07:00
|
|
|
if (change[0] == 'A')
|
|
|
|
{
|
|
|
|
status->staged = status->change = EDI_SCM_STATUS_ADDED_STAGED;
|
|
|
|
}
|
2017-06-17 04:59:10 -07:00
|
|
|
}
|
|
|
|
else if (change[0] == 'R' || change[1] == 'R')
|
|
|
|
{
|
|
|
|
status->change = EDI_SCM_STATUS_RENAMED;
|
2017-09-15 17:19:54 -07:00
|
|
|
if (change[0] == 'R')
|
|
|
|
{
|
|
|
|
status->staged = status->change = EDI_SCM_STATUS_RENAMED_STAGED;
|
|
|
|
}
|
2017-06-17 04:59:10 -07:00
|
|
|
}
|
|
|
|
else if (change[0] == 'M' || change[1] == 'M')
|
|
|
|
{
|
|
|
|
status->change = EDI_SCM_STATUS_MODIFIED;
|
2017-09-15 17:19:54 -07:00
|
|
|
if (change[0] == 'M')
|
|
|
|
{
|
|
|
|
status->staged = status->change = EDI_SCM_STATUS_MODIFIED_STAGED;
|
|
|
|
}
|
2017-06-17 04:59:10 -07:00
|
|
|
}
|
|
|
|
else if (change[0] == 'D' || change[1] == 'D')
|
|
|
|
{
|
|
|
|
status->change = EDI_SCM_STATUS_DELETED;
|
2017-09-15 17:19:54 -07:00
|
|
|
if (change[0] == 'D')
|
|
|
|
{
|
|
|
|
status->staged = status->change = EDI_SCM_STATUS_DELETED_STAGED;
|
|
|
|
}
|
2017-06-17 04:59:10 -07:00
|
|
|
}
|
|
|
|
else if (change[0] == '?' && change[1] == '?')
|
|
|
|
{
|
|
|
|
status->change = EDI_SCM_STATUS_UNTRACKED;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
status->change = EDI_SCM_STATUS_UNKNOWN;
|
|
|
|
|
2017-09-27 11:42:45 -07:00
|
|
|
esc_path = ecore_file_escape_name(path);
|
|
|
|
status->path = eina_stringshare_add(esc_path);
|
2017-12-28 15:44:28 -08:00
|
|
|
fullpath = edi_path_append(edi_scm_engine_get()->root_directory, esc_path);
|
2017-09-17 08:34:35 -07:00
|
|
|
status->fullpath = eina_stringshare_add(fullpath);
|
2017-09-27 11:42:45 -07:00
|
|
|
status->unescaped = eina_stringshare_add(path);
|
|
|
|
|
2017-09-17 08:34:35 -07:00
|
|
|
free(fullpath);
|
2017-09-27 11:42:45 -07:00
|
|
|
free(esc_path);
|
2017-06-17 04:59:10 -07:00
|
|
|
|
|
|
|
return status;
|
|
|
|
}
|
|
|
|
|
2017-08-28 06:01:41 -07:00
|
|
|
static Edi_Scm_Status_Code
|
|
|
|
_edi_scm_git_file_status(const char *path)
|
|
|
|
{
|
|
|
|
Edi_Scm_Status *status;
|
2017-09-15 17:19:54 -07:00
|
|
|
char command[4096];
|
2017-09-27 11:42:45 -07:00
|
|
|
char *line, *escaped;
|
2017-09-15 17:19:54 -07:00
|
|
|
Edi_Scm_Status_Code result;
|
2017-08-28 06:01:41 -07:00
|
|
|
|
2017-09-27 11:42:45 -07:00
|
|
|
escaped = ecore_file_escape_name(path);
|
|
|
|
snprintf(command, sizeof(command), "git status --porcelain %s", escaped);
|
|
|
|
free(escaped);
|
2017-09-15 17:19:54 -07:00
|
|
|
line = _edi_scm_exec_response(command);
|
|
|
|
if (!line[0] || !line[1])
|
|
|
|
{
|
|
|
|
result = EDI_SCM_STATUS_NONE;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
status = _parse_line(line);
|
|
|
|
result = status->change;
|
|
|
|
eina_stringshare_del(status->path);
|
2017-09-17 08:34:35 -07:00
|
|
|
eina_stringshare_del(status->fullpath);
|
2017-09-27 11:42:45 -07:00
|
|
|
eina_stringshare_del(status->unescaped);
|
2017-09-15 17:19:54 -07:00
|
|
|
free(status);
|
|
|
|
}
|
2017-08-28 06:01:41 -07:00
|
|
|
|
|
|
|
free(line);
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2017-06-17 04:59:10 -07:00
|
|
|
static Eina_List *
|
|
|
|
_edi_scm_git_status_get(void)
|
|
|
|
{
|
|
|
|
char *output, *pos, *start, *end;
|
|
|
|
char *line;
|
|
|
|
size_t size;
|
|
|
|
Eina_Strbuf *command;
|
|
|
|
Edi_Scm_Status *status;
|
|
|
|
Eina_List *list = NULL;
|
|
|
|
|
|
|
|
command = eina_strbuf_new();
|
|
|
|
|
|
|
|
eina_strbuf_append(command, "git status --porcelain");
|
|
|
|
|
|
|
|
output = _edi_scm_exec_response(eina_strbuf_string_get(command));
|
|
|
|
|
|
|
|
eina_strbuf_free(command);
|
|
|
|
|
|
|
|
end = NULL;
|
|
|
|
|
|
|
|
pos = output;
|
|
|
|
start = pos;
|
|
|
|
|
|
|
|
while (*pos++)
|
|
|
|
{
|
|
|
|
if (*pos == '\n')
|
|
|
|
end = pos;
|
|
|
|
if (start && end)
|
|
|
|
{
|
|
|
|
size = end - start;
|
|
|
|
line = malloc(size + 1);
|
|
|
|
memcpy(line, start, size);
|
|
|
|
line[size] = '\0';
|
|
|
|
|
|
|
|
status = _parse_line(line);
|
|
|
|
if (status)
|
|
|
|
list = eina_list_append(list, status);
|
|
|
|
|
|
|
|
free(line);
|
|
|
|
start = end + 1;
|
|
|
|
end = NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
end = pos;
|
|
|
|
size = end - start;
|
|
|
|
if (size > 1)
|
|
|
|
{
|
|
|
|
line = malloc(size + 1);
|
|
|
|
memcpy(line, start, size);
|
|
|
|
line[size] = '\0';
|
|
|
|
|
|
|
|
status = _parse_line(line);
|
|
|
|
if (status)
|
|
|
|
list = eina_list_append(list, status);
|
|
|
|
|
|
|
|
free(line);
|
|
|
|
}
|
|
|
|
|
|
|
|
free(output);
|
|
|
|
|
|
|
|
return list;
|
|
|
|
}
|
|
|
|
|
2017-09-11 08:27:40 -07:00
|
|
|
static char *
|
2017-09-21 12:45:33 -07:00
|
|
|
_edi_scm_git_diff(Eina_Bool cached)
|
2017-09-11 08:27:40 -07:00
|
|
|
{
|
|
|
|
char *output;
|
|
|
|
Eina_Strbuf *command;
|
|
|
|
|
|
|
|
command = eina_strbuf_new();
|
|
|
|
|
2017-09-21 12:45:33 -07:00
|
|
|
if (cached)
|
|
|
|
eina_strbuf_append(command, "git diff --cached");
|
|
|
|
else
|
|
|
|
eina_strbuf_append(command, "git diff");
|
2017-09-11 08:27:40 -07:00
|
|
|
|
|
|
|
output = _edi_scm_exec_response(eina_strbuf_string_get(command));
|
|
|
|
|
|
|
|
eina_strbuf_free(command);
|
|
|
|
|
|
|
|
return output;
|
|
|
|
}
|
|
|
|
|
2017-06-06 17:45:44 -07:00
|
|
|
static int
|
|
|
|
_edi_scm_git_commit(const char *message)
|
|
|
|
{
|
|
|
|
int code;
|
|
|
|
Eina_Strbuf *command = eina_strbuf_new();
|
|
|
|
|
2017-09-27 11:42:45 -07:00
|
|
|
eina_strbuf_append_printf(command, "git commit -m \"%s\"", message);
|
2017-06-06 17:45:44 -07:00
|
|
|
|
|
|
|
code = _edi_scm_exec(eina_strbuf_string_get(command));
|
|
|
|
|
|
|
|
eina_strbuf_free(command);
|
|
|
|
|
|
|
|
return code;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
_edi_scm_git_push(void)
|
|
|
|
{
|
2017-06-06 19:23:40 -07:00
|
|
|
return _edi_scm_exec("git push");
|
2017-06-06 17:45:44 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
_edi_scm_git_pull(void)
|
|
|
|
{
|
|
|
|
int code;
|
|
|
|
Eina_Strbuf *command = eina_strbuf_new();
|
|
|
|
|
|
|
|
eina_strbuf_append(command, "git pull");
|
|
|
|
|
|
|
|
code = _edi_scm_exec(eina_strbuf_string_get(command));
|
|
|
|
|
|
|
|
eina_strbuf_free(command);
|
|
|
|
|
|
|
|
return code;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
_edi_scm_git_stash(void)
|
|
|
|
{
|
|
|
|
int code;
|
|
|
|
Eina_Strbuf *command = eina_strbuf_new();
|
|
|
|
|
|
|
|
eina_strbuf_append(command, "git stash");
|
|
|
|
|
|
|
|
code = _edi_scm_exec(eina_strbuf_string_get(command));
|
|
|
|
|
|
|
|
eina_strbuf_free(command);
|
|
|
|
|
|
|
|
return code;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
_edi_scm_git_remote_add(const char *remote_url)
|
|
|
|
{
|
|
|
|
int code;
|
|
|
|
Eina_Strbuf *command = eina_strbuf_new();
|
|
|
|
|
|
|
|
eina_strbuf_append_printf(command, "git remote add origin %s", remote_url);
|
|
|
|
|
|
|
|
code = _edi_scm_exec(eina_strbuf_string_get(command));
|
|
|
|
eina_strbuf_free(command);
|
|
|
|
|
2017-06-06 19:23:40 -07:00
|
|
|
if (code == 0)
|
|
|
|
code = _edi_scm_exec("git push --set-upstream origin master");
|
|
|
|
|
2017-06-06 17:45:44 -07:00
|
|
|
return code;
|
|
|
|
}
|
|
|
|
|
|
|
|
static const char *
|
|
|
|
_edi_scm_git_remote_name_get(void)
|
|
|
|
{
|
2017-06-07 14:32:10 -07:00
|
|
|
static char *_remote_name;
|
2017-06-06 17:45:44 -07:00
|
|
|
Edi_Scm_Engine *engine = _edi_scm_global_object;
|
|
|
|
|
|
|
|
if (!engine)
|
|
|
|
return NULL;
|
|
|
|
|
2018-03-19 16:38:01 -07:00
|
|
|
if (_remote_name)
|
|
|
|
free(_remote_name);
|
|
|
|
|
|
|
|
_remote_name = _edi_scm_exec_response("git config --get user.name");
|
|
|
|
|
|
|
|
if (_remote_name && !_remote_name[0])
|
|
|
|
{
|
|
|
|
free(_remote_name);
|
|
|
|
_remote_name = NULL;
|
|
|
|
}
|
2017-06-06 17:45:44 -07:00
|
|
|
|
2017-06-07 14:32:10 -07:00
|
|
|
return _remote_name;
|
2017-06-06 17:45:44 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
static const char *
|
|
|
|
_edi_scm_git_remote_email_get(void)
|
|
|
|
{
|
2017-06-07 14:32:10 -07:00
|
|
|
static char *_remote_email;
|
2017-06-06 17:45:44 -07:00
|
|
|
Edi_Scm_Engine *engine = _edi_scm_global_object;
|
|
|
|
|
|
|
|
if (!engine)
|
|
|
|
return NULL;
|
|
|
|
|
2018-03-19 16:38:01 -07:00
|
|
|
if (_remote_email)
|
|
|
|
free(_remote_email);
|
|
|
|
|
|
|
|
_remote_email = _edi_scm_exec_response("git config --get user.email");
|
|
|
|
|
|
|
|
if (_remote_email && !_remote_email[0])
|
|
|
|
{
|
|
|
|
free(_remote_email);
|
|
|
|
_remote_email = NULL;
|
|
|
|
}
|
2017-06-06 17:45:44 -07:00
|
|
|
|
2017-06-07 14:32:10 -07:00
|
|
|
return _remote_email;
|
2017-06-06 17:45:44 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
static const char *
|
|
|
|
_edi_scm_git_remote_url_get(void)
|
|
|
|
{
|
2017-06-07 14:32:10 -07:00
|
|
|
static char *_remote_url;
|
2017-06-06 17:45:44 -07:00
|
|
|
Edi_Scm_Engine *engine = _edi_scm_global_object;
|
|
|
|
|
|
|
|
if (!engine)
|
|
|
|
return NULL;
|
|
|
|
|
2018-03-19 16:38:01 -07:00
|
|
|
if (_remote_url)
|
|
|
|
free(_remote_url);
|
|
|
|
|
|
|
|
_remote_url = _edi_scm_exec_response("git remote get-url origin");
|
|
|
|
|
|
|
|
if (_remote_url && !_remote_url[0])
|
|
|
|
{
|
|
|
|
free(_remote_url);
|
|
|
|
_remote_url = NULL;
|
|
|
|
}
|
2017-06-06 17:45:44 -07:00
|
|
|
|
2017-06-07 14:32:10 -07:00
|
|
|
return _remote_url;
|
2017-06-06 17:45:44 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
2017-06-07 14:32:10 -07:00
|
|
|
_edi_scm_git_credentials_set(const char *name, const char *email)
|
2017-06-06 17:45:44 -07:00
|
|
|
{
|
|
|
|
int code;
|
|
|
|
Eina_Strbuf *command = eina_strbuf_new();
|
|
|
|
|
|
|
|
eina_strbuf_append_printf(command, "git config user.name '%s'", name);
|
|
|
|
code = _edi_scm_exec(eina_strbuf_string_get(command));
|
|
|
|
eina_strbuf_reset(command);
|
|
|
|
eina_strbuf_append_printf(command, "git config user.email '%s'", email);
|
|
|
|
code = _edi_scm_exec(eina_strbuf_string_get(command));
|
|
|
|
|
|
|
|
eina_strbuf_free(command);
|
|
|
|
|
|
|
|
return code;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Eina_Bool
|
|
|
|
_edi_scm_enabled(Edi_Scm_Engine *engine)
|
|
|
|
{
|
|
|
|
char *path;
|
|
|
|
if (!engine) return EINA_FALSE;
|
|
|
|
|
|
|
|
if (!engine->path)
|
|
|
|
{
|
|
|
|
path = edi_path_append(edi_project_get(), engine->directory);
|
|
|
|
engine->path = eina_stringshare_add(path);
|
|
|
|
free(path);
|
|
|
|
}
|
|
|
|
|
|
|
|
return ecore_file_exists(engine->path);
|
|
|
|
}
|
|
|
|
|
|
|
|
EAPI Eina_Bool
|
|
|
|
edi_scm_remote_enabled(void)
|
|
|
|
{
|
|
|
|
Edi_Scm_Engine *e = _edi_scm_global_object;
|
|
|
|
if (!e)
|
|
|
|
return EINA_FALSE;
|
|
|
|
|
2017-06-07 14:32:10 -07:00
|
|
|
return !!e->remote_url_get();
|
2017-06-06 17:45:44 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
EAPI Eina_Bool
|
|
|
|
edi_scm_enabled(void)
|
|
|
|
{
|
|
|
|
Edi_Scm_Engine *engine = _edi_scm_global_object;
|
|
|
|
if (!engine)
|
|
|
|
return EINA_FALSE;
|
|
|
|
|
2017-09-15 17:19:54 -07:00
|
|
|
if (!engine->initialized)
|
|
|
|
return EINA_FALSE;
|
|
|
|
|
2017-06-06 17:45:44 -07:00
|
|
|
return _edi_scm_enabled(engine);
|
|
|
|
}
|
|
|
|
|
|
|
|
EAPI Edi_Scm_Engine *
|
|
|
|
edi_scm_engine_get(void)
|
|
|
|
{
|
2017-12-30 11:00:04 -08:00
|
|
|
return _edi_scm_global_object;
|
2017-06-06 17:45:44 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
EAPI void
|
|
|
|
edi_scm_shutdown()
|
|
|
|
{
|
|
|
|
Edi_Scm_Engine *engine = _edi_scm_global_object;
|
|
|
|
|
|
|
|
if (!engine)
|
|
|
|
return;
|
|
|
|
|
|
|
|
eina_stringshare_del(engine->path);
|
2017-12-28 15:44:28 -08:00
|
|
|
free(engine->root_directory);
|
2017-06-06 17:45:44 -07:00
|
|
|
free(engine);
|
|
|
|
|
|
|
|
_edi_scm_global_object = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
EAPI int
|
2017-12-20 13:47:21 -08:00
|
|
|
edi_scm_stage(const char *path)
|
2017-06-06 17:45:44 -07:00
|
|
|
{
|
2017-09-27 11:42:45 -07:00
|
|
|
char *escaped;
|
|
|
|
int result;
|
2017-06-06 17:45:44 -07:00
|
|
|
Edi_Scm_Engine *e = edi_scm_engine_get();
|
|
|
|
|
2017-09-27 11:42:45 -07:00
|
|
|
escaped = ecore_file_escape_name(path);
|
|
|
|
|
2017-12-20 13:47:21 -08:00
|
|
|
result = e->file_stage(escaped);
|
2017-09-27 11:42:45 -07:00
|
|
|
|
|
|
|
free(escaped);
|
|
|
|
|
|
|
|
return result;
|
2017-06-06 17:45:44 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
EAPI int
|
|
|
|
edi_scm_del(const char *path)
|
|
|
|
{
|
2017-09-27 11:42:45 -07:00
|
|
|
char *escaped;
|
|
|
|
int result;
|
2017-06-06 17:45:44 -07:00
|
|
|
Edi_Scm_Engine *e = edi_scm_engine_get();
|
|
|
|
|
2017-09-27 11:42:45 -07:00
|
|
|
escaped = ecore_file_escape_name(path);
|
|
|
|
|
|
|
|
result = e->file_del(escaped);
|
|
|
|
|
|
|
|
free(escaped);
|
|
|
|
|
|
|
|
return result;
|
2017-06-06 17:45:44 -07:00
|
|
|
}
|
|
|
|
|
2017-12-20 13:47:21 -08:00
|
|
|
EAPI int
|
|
|
|
edi_scm_unstage(const char *path)
|
|
|
|
{
|
|
|
|
char *escaped;
|
|
|
|
int result;
|
|
|
|
Edi_Scm_Engine *e = edi_scm_engine_get();
|
|
|
|
|
|
|
|
escaped = ecore_file_escape_name(path);
|
|
|
|
|
|
|
|
result = e->file_unstage(escaped);
|
|
|
|
|
|
|
|
free(escaped);
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2017-06-06 17:45:44 -07:00
|
|
|
EAPI int
|
|
|
|
edi_scm_move(const char *src, const char *dest)
|
|
|
|
{
|
2017-09-27 11:42:45 -07:00
|
|
|
char *esc_src, *esc_dst;
|
|
|
|
int result;
|
2017-06-06 17:45:44 -07:00
|
|
|
Edi_Scm_Engine *e = edi_scm_engine_get();
|
|
|
|
|
2017-09-27 11:42:45 -07:00
|
|
|
esc_src = ecore_file_escape_name(src);
|
|
|
|
esc_dst = ecore_file_escape_name(dest);
|
|
|
|
|
|
|
|
result = e->move(esc_src, esc_dst);
|
|
|
|
|
|
|
|
free(esc_src);
|
|
|
|
free(esc_dst);
|
|
|
|
|
|
|
|
return result;
|
2017-06-06 17:45:44 -07:00
|
|
|
}
|
|
|
|
|
2017-06-17 04:59:10 -07:00
|
|
|
EAPI Eina_Bool
|
|
|
|
edi_scm_status_get(void)
|
|
|
|
{
|
|
|
|
Edi_Scm_Engine *e = edi_scm_engine_get();
|
|
|
|
|
|
|
|
e->statuses = e->status_get();
|
|
|
|
|
|
|
|
if (!e->statuses)
|
|
|
|
return EINA_FALSE;
|
|
|
|
|
|
|
|
return EINA_TRUE;
|
|
|
|
}
|
|
|
|
|
2017-08-28 06:01:41 -07:00
|
|
|
EAPI Edi_Scm_Status_Code
|
|
|
|
edi_scm_file_status(const char *path)
|
|
|
|
{
|
2017-09-27 11:42:45 -07:00
|
|
|
char *escaped;
|
|
|
|
int result;
|
2017-08-28 06:01:41 -07:00
|
|
|
Edi_Scm_Engine *e = edi_scm_engine_get();
|
|
|
|
|
2017-09-27 11:42:45 -07:00
|
|
|
escaped = ecore_file_escape_name(path);
|
|
|
|
|
|
|
|
result = e->file_status(escaped);
|
|
|
|
|
|
|
|
free(escaped);
|
|
|
|
|
|
|
|
return result;
|
2017-08-28 06:01:41 -07:00
|
|
|
}
|
|
|
|
|
2017-06-06 17:45:44 -07:00
|
|
|
EAPI void
|
|
|
|
edi_scm_commit(const char *message)
|
|
|
|
{
|
2017-09-17 08:34:35 -07:00
|
|
|
Edi_Scm_Engine *e = edi_scm_engine_get();
|
|
|
|
|
|
|
|
e->commit(message);
|
2017-06-06 17:45:44 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_edi_scm_status_thread_cb(void *data, Ecore_Thread *thread)
|
|
|
|
{
|
|
|
|
Edi_Scm_Engine *e = data;
|
|
|
|
|
|
|
|
e->status();
|
|
|
|
|
|
|
|
ecore_thread_cancel(thread);
|
|
|
|
}
|
|
|
|
|
|
|
|
EAPI void
|
|
|
|
edi_scm_status(void)
|
|
|
|
{
|
|
|
|
Edi_Scm_Engine *e = edi_scm_engine_get();
|
|
|
|
|
|
|
|
ecore_thread_run(_edi_scm_status_thread_cb, NULL, NULL, e);
|
|
|
|
}
|
|
|
|
|
|
|
|
EAPI int
|
|
|
|
edi_scm_remote_add(const char *remote_url)
|
|
|
|
{
|
|
|
|
Edi_Scm_Engine *e = edi_scm_engine_get();
|
|
|
|
|
|
|
|
return e->remote_add(remote_url);
|
|
|
|
}
|
|
|
|
|
2017-09-11 08:27:40 -07:00
|
|
|
EAPI char *
|
2017-09-21 12:45:33 -07:00
|
|
|
edi_scm_diff(Eina_Bool cached)
|
2017-09-11 08:27:40 -07:00
|
|
|
{
|
|
|
|
Edi_Scm_Engine *e = edi_scm_engine_get();
|
|
|
|
|
2017-09-21 12:45:33 -07:00
|
|
|
return e->diff(cached);
|
2017-09-11 08:27:40 -07:00
|
|
|
}
|
|
|
|
|
2017-06-06 17:45:44 -07:00
|
|
|
EAPI void
|
|
|
|
edi_scm_stash(void)
|
|
|
|
{
|
|
|
|
Edi_Scm_Engine *e = edi_scm_engine_get();
|
|
|
|
|
2017-09-18 16:18:46 -07:00
|
|
|
e->stash();
|
2017-06-06 17:45:44 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
EAPI int
|
2017-06-07 14:32:10 -07:00
|
|
|
edi_scm_credentials_set(const char *user, const char *email)
|
2017-06-06 17:45:44 -07:00
|
|
|
{
|
|
|
|
Edi_Scm_Engine *e = edi_scm_engine_get();
|
|
|
|
|
2017-06-07 14:32:10 -07:00
|
|
|
return e->credentials_set(user, email);
|
2017-06-06 17:45:44 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_edi_scm_pull_thread_cb(void *data, Ecore_Thread *thread)
|
|
|
|
{
|
|
|
|
Edi_Scm_Engine *e = data;
|
|
|
|
|
|
|
|
e->pull();
|
|
|
|
|
|
|
|
ecore_thread_cancel(thread);
|
|
|
|
}
|
|
|
|
|
|
|
|
EAPI void
|
|
|
|
edi_scm_pull(void)
|
|
|
|
{
|
|
|
|
Edi_Scm_Engine *e = edi_scm_engine_get();
|
|
|
|
|
|
|
|
ecore_thread_run(_edi_scm_pull_thread_cb, NULL, NULL, e);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_edi_scm_push_thread_cb(void *data, Ecore_Thread *thread)
|
|
|
|
{
|
|
|
|
Edi_Scm_Engine *e = data;
|
|
|
|
|
|
|
|
e->push();
|
|
|
|
|
|
|
|
ecore_thread_cancel(thread);
|
|
|
|
}
|
|
|
|
|
|
|
|
EAPI void
|
|
|
|
edi_scm_push(void)
|
|
|
|
{
|
|
|
|
Edi_Scm_Engine *e = edi_scm_engine_get();
|
|
|
|
|
|
|
|
ecore_thread_run(_edi_scm_push_thread_cb, NULL, NULL, e);
|
|
|
|
}
|
|
|
|
|
2017-12-28 15:44:28 -08:00
|
|
|
EAPI const char *
|
|
|
|
edi_scm_root_directory_get(void)
|
|
|
|
{
|
|
|
|
Edi_Scm_Engine *e = edi_scm_engine_get();
|
|
|
|
|
|
|
|
return e->root_directory;
|
|
|
|
}
|
|
|
|
|
2017-06-06 17:45:44 -07:00
|
|
|
static Edi_Scm_Engine *
|
2017-12-30 11:00:04 -08:00
|
|
|
_edi_scm_git_init(const char *rootdir)
|
2017-06-06 17:45:44 -07:00
|
|
|
{
|
|
|
|
Edi_Scm_Engine *engine;
|
|
|
|
|
|
|
|
if (!ecore_file_app_installed("git"))
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
_edi_scm_global_object = engine = calloc(1, sizeof(Edi_Scm_Engine));
|
2017-12-30 11:00:04 -08:00
|
|
|
engine->name = "git";
|
|
|
|
engine->directory = ".git";
|
2017-12-20 13:47:21 -08:00
|
|
|
engine->file_stage = _edi_scm_git_file_stage;
|
2017-06-17 04:59:10 -07:00
|
|
|
engine->file_mod = _edi_scm_git_file_mod;
|
|
|
|
engine->file_del = _edi_scm_git_file_del;
|
2017-12-20 13:47:21 -08:00
|
|
|
engine->file_unstage = _edi_scm_git_file_unstage;
|
2017-06-17 04:59:10 -07:00
|
|
|
engine->move = _edi_scm_git_file_move;
|
|
|
|
engine->status = _edi_scm_git_status;
|
2017-09-11 08:27:40 -07:00
|
|
|
engine->diff = _edi_scm_git_diff;
|
2017-06-17 04:59:10 -07:00
|
|
|
engine->commit = _edi_scm_git_commit;
|
|
|
|
engine->pull = _edi_scm_git_pull;
|
|
|
|
engine->push = _edi_scm_git_push;
|
|
|
|
engine->stash = _edi_scm_git_stash;
|
2017-08-28 06:01:41 -07:00
|
|
|
engine->file_status = _edi_scm_git_file_status;
|
2017-06-17 04:59:10 -07:00
|
|
|
|
|
|
|
engine->remote_add = _edi_scm_git_remote_add;
|
|
|
|
engine->remote_name_get = _edi_scm_git_remote_name_get;
|
2017-06-07 14:32:10 -07:00
|
|
|
engine->remote_email_get = _edi_scm_git_remote_email_get;
|
2017-06-17 04:59:10 -07:00
|
|
|
engine->remote_url_get = _edi_scm_git_remote_url_get;
|
|
|
|
engine->credentials_set = _edi_scm_git_credentials_set;
|
|
|
|
engine->status_get = _edi_scm_git_status_get;
|
2017-06-06 17:45:44 -07:00
|
|
|
|
2017-12-30 11:00:04 -08:00
|
|
|
engine->root_directory = strdup(rootdir);
|
|
|
|
engine->initialized = EINA_TRUE;
|
2017-12-29 03:53:26 -08:00
|
|
|
|
2017-12-30 11:00:04 -08:00
|
|
|
return engine;
|
|
|
|
}
|
2017-12-29 03:53:26 -08:00
|
|
|
|
2017-12-30 11:00:04 -08:00
|
|
|
static char *
|
|
|
|
_edi_scm_root_find(const char *dir, const char *scmdir)
|
|
|
|
{
|
|
|
|
char *directory, *engine_root, *path, *tmp;
|
|
|
|
|
|
|
|
engine_root = NULL;
|
|
|
|
directory = strdup(dir);
|
|
|
|
while (directory && strlen(directory) > 1)
|
2017-12-29 03:53:26 -08:00
|
|
|
{
|
2017-12-30 11:00:04 -08:00
|
|
|
path = edi_path_append(directory, scmdir);
|
|
|
|
if (ecore_file_exists(path) && ecore_file_is_dir(path))
|
|
|
|
{
|
|
|
|
engine_root = strdup(directory);
|
2017-09-29 13:37:21 -07:00
|
|
|
|
2017-12-30 11:00:04 -08:00
|
|
|
free(directory);
|
|
|
|
free(path);
|
|
|
|
break;
|
|
|
|
}
|
2017-09-15 17:19:54 -07:00
|
|
|
|
2017-12-30 11:00:04 -08:00
|
|
|
tmp = ecore_file_dir_get(directory);
|
|
|
|
free(directory);
|
|
|
|
directory = tmp;
|
|
|
|
free(path);
|
|
|
|
}
|
|
|
|
|
|
|
|
return engine_root;
|
2017-06-06 17:45:44 -07:00
|
|
|
}
|
|
|
|
|
2017-09-29 13:37:21 -07:00
|
|
|
EAPI Edi_Scm_Engine *
|
2017-12-30 11:00:04 -08:00
|
|
|
edi_scm_init_path(const char *path)
|
2017-09-29 13:37:21 -07:00
|
|
|
{
|
2017-12-30 11:00:04 -08:00
|
|
|
char *location;
|
|
|
|
Edi_Scm_Engine *engine;
|
2017-09-29 13:37:21 -07:00
|
|
|
|
2017-12-30 11:00:04 -08:00
|
|
|
engine = NULL;
|
|
|
|
location = _edi_scm_root_find(path, ".git");
|
|
|
|
if (location)
|
|
|
|
{
|
|
|
|
engine = _edi_scm_git_init(location);
|
|
|
|
free(location);
|
|
|
|
}
|
|
|
|
|
|
|
|
return engine;
|
2017-09-29 13:37:21 -07:00
|
|
|
}
|
|
|
|
|
2017-06-06 17:45:44 -07:00
|
|
|
EAPI Edi_Scm_Engine *
|
|
|
|
edi_scm_init(void)
|
|
|
|
{
|
2017-12-30 11:00:04 -08:00
|
|
|
char *cwd;
|
|
|
|
Edi_Scm_Engine *engine;
|
|
|
|
|
|
|
|
if (edi_project_get())
|
|
|
|
return edi_scm_init_path(edi_project_get());
|
2017-06-06 17:45:44 -07:00
|
|
|
|
2017-12-30 11:00:04 -08:00
|
|
|
cwd = getcwd(NULL, PATH_MAX);
|
|
|
|
engine = edi_scm_init_path(cwd);
|
|
|
|
free(cwd);
|
|
|
|
return engine;
|
2017-06-06 17:45:44 -07:00
|
|
|
}
|
|
|
|
|
2017-06-07 22:38:21 -07:00
|
|
|
EAPI const char *
|
|
|
|
edi_scm_avatar_url_get(const char *email)
|
|
|
|
{
|
|
|
|
int n;
|
|
|
|
char *id;
|
|
|
|
const char *url;
|
|
|
|
MD5_CTX ctx;
|
|
|
|
char md5out[(2 * MD5_HASHBYTES) + 1];
|
|
|
|
unsigned char hash[MD5_HASHBYTES];
|
|
|
|
static const char hex[] = "0123456789abcdef";
|
|
|
|
|
|
|
|
if (!email || strlen(email) == 0)
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
id = strdup(email);
|
|
|
|
eina_str_tolower(&id);
|
|
|
|
|
|
|
|
MD5Init(&ctx);
|
|
|
|
MD5Update(&ctx, (unsigned char const*)id, (unsigned)strlen(id));
|
|
|
|
MD5Final(hash, &ctx);
|
|
|
|
|
|
|
|
for (n = 0; n < MD5_HASHBYTES; n++)
|
|
|
|
{
|
|
|
|
md5out[2 * n] = hex[hash[n] >> 4];
|
|
|
|
md5out[2 * n + 1] = hex[hash[n] & 0x0f];
|
|
|
|
}
|
|
|
|
md5out[2 * MD5_HASHBYTES] = '\0';
|
|
|
|
|
|
|
|
url = eina_stringshare_printf("http://www.gravatar.com/avatar/%s", md5out);
|
|
|
|
|
|
|
|
free(id);
|
|
|
|
return url;
|
|
|
|
}
|
|
|
|
|