summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormrb0nk500 <b0nk@b0nk.xyz>2022-08-05 13:44:20 -0300
committermrb0nk500 <b0nk@b0nk.xyz>2022-08-05 13:44:20 -0300
commit689f0738581ee6dec440d7123e5431f4a78adaf9 (patch)
tree2d2db83c7cd1d2b58a8c9f0b1f1befca6f6ff309
parent9f58d83f1d7116c824ff074184a6c90556410b5b (diff)
git: Add `create_pull_request_branch()`
This takes in the PR, the index of that PR, and the repo the PR is for, and will create a branch for that PR in the given repo. Currently it only supports working with remote branches, but eventually it'll support patch files too.
-rw-r--r--git.c87
-rw-r--r--git.h1
2 files changed, 88 insertions, 0 deletions
diff --git a/git.c b/git.c
index 7e65323..cbc72d0 100644
--- a/git.c
+++ b/git.c
@@ -587,6 +587,93 @@ git_repo *get_repo(git_repo **repos, const char *name) {
return NULL;
}
+int create_pull_request_branch(pull_request *pr, index_t *idx, git_repo *repo) {
+ int ret = 0;
+
+ /* Is this a NULL PR? */
+ if (pr == NULL) {
+ log(LOG_ERR, "Pull Request is NULL.");
+ return -1;
+ } else {
+ /* Prepend "pr" to the index path to create the PR branch index. */
+ char *pr_branch_index = make_index_path("pr", idx, 0);
+
+ /* Is the PR branch index empty? */
+ if (is_empty(pr_branch_index)) {
+ log(LOG_ERR, "Empty PR branch index.");
+ return -1;
+ } else {
+ /* Create the PR branch by just using the PR branch index. */
+ char *pr_branch = pr_branch_index;
+ /* Are we using a remote branch, and is the name of that branch non-empty? */
+ if (pr->pr_type && !is_empty(pr->branch->name)) {
+ /* Append the branch name to the PR branch index. */
+ pr_branch = dir_path_name((const char *)pr_branch_index, pr->branch->name);
+ /* Free the PR branch index */
+ free(pr_branch_index);
+ }
+ /* Is repo non-NULL, and the git repo non-NULL? */
+ if (repo != NULL && repo->repo != NULL) {
+ /* Are we using a remote branch? */
+ if (pr->pr_type) {
+ git_branch *branch = pr->branch;
+ /* Is the remote repo's URL non-empty? */
+ if (!is_empty(branch->repo)) {
+ git_remote *remote;
+ /* Did we successfully create the anonymous remote? */
+ if (!git_remote_create_anonymous(&remote, repo->repo, branch->repo)) {
+ char *branch_name = branch->name;
+ char *refspec;
+ const git_strarray refspecs = {&refspec, 1};
+ /* Is the branch name empty? */
+ if (is_empty(branch->name)) {
+ git_buf default_branch = {0};
+ log(LOG_WARNING, "Empty remote repo branch name, using default remote branch instead.");
+ /* Did we successfully get the default remote branch? */
+ if (!git_remote_default_branch(&default_branch, remote)) {
+ branch_name = default_branch.ptr;
+ } else {
+ log(LOG_ERR, "Failed to get default branch of remote repo \"%s\".", branch->repo);
+ free(pr_branch);
+ return -1;
+ }
+ }
+
+ refspec = calloc(format_len("%s:%s", branch_name, pr_branch)+1, sizeof(char));
+ sprintf(refspec, "%s:%s", branch_name, pr_branch);
+
+ /* Did we successfully fetch the remote repo? */
+ if (!git_remote_fetch(remote, &refspecs, NULL, NULL)) {
+ log(LOG_NOTICE, "Successfully fetched branch \"%s\" of remote repo \"%s\" into branch \"%s\".", branch_name, branch->repo, pr_branch);
+ ret = 0;
+ } else {
+ log(LOG_ERR, "Failed to fetch remote repo \"%s\".", branch->repo);
+ ret = -1;
+ }
+
+ /* Did we actually use the default remote branch? */
+ if (branch_name != branch->name) {
+ free(branch_name);
+ }
+ free(refspec);
+ free(pr_branch);
+ return ret;
+ } else {
+ log(LOG_ERR, "Failed to create anonymous remote for remote repo \"%s\".", branch->repo);
+ free(pr_branch);
+ return -1;
+ }
+ }
+ }
+ } else {
+ log(LOG_ERR, "Git repo is NULL.");
+ free(pr_branch);
+ return -1;
+ }
+ }
+ }
+}
+
int create_pull_request_dir(pull_request *pr, index_t *idx, const char *root, const char *repo) {
int ret = 0;
struct stat st;
diff --git a/git.h b/git.h
index 595f7a5..e2c6776 100644
--- a/git.h
+++ b/git.h
@@ -56,6 +56,7 @@ extern git_repo **init_git(config *cfg);
extern pull_request *get_pull_request(index_t *idx, const char *root, const char *repo);
extern int add_comment(comment *comment, const char *pr_root);
extern git_repo *get_repo(git_repo **repos, const char *name);
+extern int create_pull_request_branch(pull_request *pr, index_t *idx, git_repo *repo);
extern int create_pull_request_dir(pull_request *pr, index_t *idx, const char *root, const char *repo);
int parse_remote_branch(void *ctx, void *ret, const keyword *key, keyword_val val);