Commit 9c82357b by Carlos Martín Nieto

Add a remotes API

Signed-off-by: Carlos Martín Nieto <carlos@cmartin.tk>
parent 0b10c9ea
......@@ -54,4 +54,7 @@
#include "git2/index.h"
#include "git2/config.h"
#include "git2/remote.h"
#include "git2/refspec.h"
#endif
#ifndef INCLUDE_branch_h__
#define INCLUDE_branch_h__
struct git_branch {
char *remote; /* TODO: Make this a git_remote */
char *merge;
};
#endif
#ifndef INCLUDE_git_refspec_h__
#define INCLUDE_git_refspec_h__
#include "git2/types.h"
/**
* Get the source specifier
*
* @param refspec the refspec
* @return the refspec's source specifier
*/
const char *git_refspec_src(const git_refspec *refspec);
/**
* Get the destination specifier
*
* @param refspec the refspec
* @return the refspec's destination specifier
*/
const char *git_refspec_dst(const git_refspec *refspec);
#endif
#ifndef INCLUDE_git_remote_h__
#define INCLUDE_git_remote_h__
#include "git2/common.h"
#include "git2/repository.h"
#include "git2/refspec.h"
/**
* Get the information for a particular remote
*
* @param out pointer to the new remote object
* @param cfg the repository's configuration
* @param name the remote's name
* @return 0 on success; error value otherwise
*/
GIT_EXTERN(int) git_remote_get(struct git_remote **out, struct git_config *cfg, const char *name);
/**
* Get the remote's name
*
* @param remote the remote
* @return a pointer to the name
*/
GIT_EXTERN(const char *) git_remote_name(struct git_remote *remote);
/**
* Get the remote's url
*
* @param remote the remote
* @return a pointer to the url
*/
GIT_EXTERN(const char *) git_remote_url(struct git_remote *remote);
/**
* Get the fetch refspec
*
* @param remote the remote
* @return a pointer to the fetch refspec or NULL if it doesn't exist
*/
GIT_EXTERN(const git_refspec *) git_remote_fetchspec(struct git_remote *remote);
/**
* Get the push refspec
*
* @param remote the remote
* @return a pointer to the push refspec or NULL if it doesn't exist
*/
GIT_EXTERN(const git_refspec *) git_remote_fetchspec(struct git_remote *remote);
/**
* Free the memory associated with a remote
*
* @param remote the remote to free
*/
GIT_EXTERN(void) git_remote_free(struct git_remote *remote);
#endif
......@@ -167,6 +167,9 @@ typedef enum {
GIT_REF_LISTALL = GIT_REF_OID|GIT_REF_SYMBOLIC|GIT_REF_PACKED,
} git_rtype;
typedef struct git_refspec git_refspec;
typedef struct git_remote git_remote;
/** @} */
GIT_END_DECL
......
/*
* This file is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License, version 2,
* as published by the Free Software Foundation.
*
* In addition to the permissions in the GNU General Public License,
* the authors give you unlimited permission to link the compiled
* version of this file into combinations with other programs,
* and to distribute those combinations without any restriction
* coming from the use of this file. (The General Public License
* restrictions do apply in other respects; for example, they cover
* modification of the file, and distribution when not linked into
* a combined executable.)
*
* This file is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; see the file COPYING. If not, write to
* the Free Software Foundation, 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#include "common.h"
#include "refspec.h"
int git_refspec_parse(git_refspec *refspec, const char *str)
{
char *delim;
memset(refspec, 0x0, sizeof(git_refspec));
if (*str == '+') {
refspec->force = 1;
str++;
}
delim = strchr(str, ':');
if (delim == NULL)
return git__throw(GIT_EOBJCORRUPTED, "Failed to parse refspec. No ':'");
refspec->src = git__strndup(str, delim - str);
if (refspec->src == NULL)
return GIT_ENOMEM;
refspec->dst = git__strdup(delim + 1);
if (refspec->dst == NULL) {
free(refspec->src);
refspec->src = NULL;
return GIT_ENOMEM;
}
return GIT_SUCCESS;
}
const char *git_refspec_src(const git_refspec *refspec)
{
return refspec->src;
}
const char *git_refspec_dst(const git_refspec *refspec)
{
return refspec->dst;
}
#ifndef INCLUDE_refspec_h__
#define INCLUDE_refspec_h__
#include "git2/refspec.h"
struct git_refspec {
int force;
char *src;
char *dst;
};
int git_refspec_parse(struct git_refspec *refspec, const char *str);
#endif
/*
* This file is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License, version 2,
* as published by the Free Software Foundation.
*
* In addition to the permissions in the GNU General Public License,
* the authors give you unlimited permission to link the compiled
* version of this file into combinations with other programs,
* and to distribute those combinations without any restriction
* coming from the use of this file. (The General Public License
* restrictions do apply in other respects; for example, they cover
* modification of the file, and distribution when not linked into
* a combined executable.)
*
* This file is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; see the file COPYING. If not, write to
* the Free Software Foundation, 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#include "git2/remote.h"
#include "git2/config.h"
#include "git2/types.h"
#include "config.h"
#include "repository.h"
#include "remote.h"
static int refspec_parse(git_refspec *refspec, const char *str)
{
char *delim;
memset(refspec, 0x0, sizeof(git_refspec));
if (*str == '+') {
refspec->force = 1;
str++;
}
delim = strchr(str, ':');
if (delim == NULL)
return git__throw(GIT_EOBJCORRUPTED, "Failed to parse refspec. No ':'");
refspec->src = git__strndup(str, delim - str);
if (refspec->src == NULL)
return GIT_ENOMEM;
refspec->dst = git__strdup(delim + 1);
if (refspec->dst == NULL) {
free(refspec->src);
refspec->src = NULL;
return GIT_ENOMEM;
}
return GIT_SUCCESS;
}
static int parse_remote_refspec(git_config *cfg, git_refspec *refspec, const char *var)
{
const char *val;
int error;
error = git_config_get_string(cfg, var, &val);
if (error < GIT_SUCCESS)
return error;
return git_refspec_parse(refspec, val);
}
int git_remote_get(git_remote **out, git_config *cfg, const char *name)
{
git_remote *remote;
char *buf = NULL;
const char *val;
int ret, error, buf_len;
remote = git__malloc(sizeof(git_remote));
if (remote == NULL)
return GIT_ENOMEM;
memset(remote, 0x0, sizeof(git_remote));
remote->name = git__strdup(name);
if (remote->name == NULL) {
error = GIT_ENOMEM;
goto cleanup;
}
/* "fetch" is the longest var name we're interested in */
buf_len = STRLEN("remote.") + STRLEN(".fetch") + strlen(name) + 1;
buf = git__malloc(buf_len);
if (buf == NULL) {
error = GIT_ENOMEM;
goto cleanup;
}
ret = snprintf(buf, buf_len, "%s.%s.%s", "remote", name, "url");
if (ret < 0) {
error = git__throw(GIT_EOSERR, "Failed to build config var name");
goto cleanup;
}
error = git_config_get_string(cfg, buf, &val);
if (error < GIT_SUCCESS) {
error = git__rethrow(error, "Remote's url doesn't exist");
goto cleanup;
}
remote->url = git__strdup(val);
if (remote->url == NULL) {
error = GIT_ENOMEM;
goto cleanup;
}
ret = snprintf(buf, buf_len, "%s.%s.%s", "remote", name, "fetch");
if (ret < 0) {
error = git__throw(GIT_EOSERR, "Failed to build config var name");
goto cleanup;
}
error = git_config_get_string(cfg, buf, &val);
if (error < GIT_SUCCESS)
goto cleanup;
error = refspec_parse(&remote->fetch, val);
if (error < GIT_SUCCESS)
goto cleanup;
ret = snprintf(buf, buf_len, "%s.%s.%s", "remote", name, "push");
if (ret < 0) {
error = git__throw(GIT_EOSERR, "Failed to build config var name");
goto cleanup;
}
error = git_config_get_string(cfg, buf, &val);
if (error < GIT_SUCCESS)
goto cleanup;
error = refspec_parse(&remote->push, val);
if (error < GIT_SUCCESS)
goto cleanup;
*out = remote;
cleanup:
free(buf);
if (error < GIT_SUCCESS)
git_remote_free(remote);
return error;
}
const char *git_remote_name(struct git_remote *remote)
{
return remote->name;
}
const char *git_remote_url(struct git_remote *remote)
{
return remote->url;
}
const git_refspec *git_remote_fetchspec(struct git_remote *remote)
{
return &remote->fetch;
}
const git_refspec *git_remote_pushspec(struct git_remote *remote)
{
return &remote->push;
}
void git_remote_free(git_remote *remote)
{
free(remote->fetch.src);
free(remote->fetch.dst);
free(remote->push.src);
free(remote->push.dst);
free(remote->url);
free(remote->name);
free(remote);
}
#ifndef INCLUDE_remote_h__
#define INCLUDE_remote_h__
#include "remote.h"
#include "refspec.h"
struct git_remote {
char *name;
char *url;
struct git_refspec fetch;
struct git_refspec push;
};
#endif
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment