TrackGit
Pull.cpp
Go to the documentation of this file.
1 
8 #include "Pull.h"
9 #include "../Utils.h"
10 
11 #include <InterfaceKit.h>
12 
13 #include <git2.h>
14 #include <stdio.h>
15 #include <stdlib.h>
16 #include <string.h>
17 
18 
23 Pull::Pull(BString repo)
24  :
25  GitCommand()
26 {
27  fRepo = repo;
28  fPullWindow = NULL;
29 }
30 
31 
32 void
34 {
35 }
36 
37 
44 {
45  if (fPullWindow == NULL)
47  return fPullWindow;
48 }
49 
50 
54 int fetchhead_ref_cb(const char* name, const char* url, const git_oid* oid,
55  unsigned int is_merge, void* payload_v) {
56  struct fetch_payload* payload = (struct fetch_payload*) payload_v;
57  if (is_merge) {
58  strcpy(payload->branch, name);
59  memcpy(&payload->branch_oid, oid, sizeof(git_oid));
60  }
61 }
62 
63 
69 void*
70 DoPullThread(void* arg)
71 {
72  struct pull_params* p = (struct pull_params*) arg;
73 
74  git_libgit2_init();
75 
76  git_repository* repo = NULL;
77  git_remote *remote;
78  int err;
79 
80  if (p->pullWindow)
81  p->pullWindow->SetText("Pulling repository...");
82  err = git_repository_open(&repo, p->path);
83  if (err < 0)
84  goto ret;
85 
86  printf("Getting remote\n");
87  err = git_remote_lookup(&remote, repo, "origin");
88  if (err < 0) {
89  BString buffer("Error : No remote found.");
90  BAlert *alert = new BAlert("", buffer.String(), "Cancel",
91  0, 0, B_WIDTH_AS_USUAL, B_WARNING_ALERT);
92  alert->Go();
93  goto clean;
94  }
95 
96  printf("Fetching...\n");
97  if (p->pullWindow)
98  p->pullWindow->SetText("Fetching changes...");
99  err = git_remote_fetch(remote, NULL, NULL, NULL);
100  if (err < 0)
101  goto ret;
102 
103  err = git_remote_fetch(remote, NULL, NULL, NULL);
104  if (err < 0)
105  goto ret;
106 
107  struct fetch_payload payload;
108  git_repository_fetchhead_foreach(repo, fetchhead_ref_cb, &payload);
109 
110  git_annotated_commit* heads[1];
111  err = git_annotated_commit_lookup(&heads[0], repo, &payload.branch_oid);
112  if (err < 0)
113  goto ret;
114 
115  if (p->pullWindow)
116  p->pullWindow->SetText("Checking for merge...");
117  git_merge_analysis_t merge_analysis_t;
118  git_merge_preference_t merge_preference_t;
119  err = git_merge_analysis(&merge_analysis_t, &merge_preference_t,
120  repo, (const git_annotated_commit**)&heads[0], 1);
121 
122  if (merge_analysis_t & GIT_MERGE_ANALYSIS_UP_TO_DATE) {
123  BString buffer("Repository up to date.");
124  BAlert *alert = new BAlert("", buffer.String(), "OK",
125  0, 0, B_WIDTH_AS_USUAL);
126  alert->Go();
127  goto ret;
128  } else if (merge_analysis_t & GIT_MERGE_ANALYSIS_FASTFORWARD) {
129  if (p->pullWindow)
130  p->pullWindow->SetText("Performing fast-forward...");
131  err = perform_fastforward(repo, &payload.branch_oid,
132  (merge_analysis_t & GIT_MERGE_ANALYSIS_UNBORN));
133  goto ret;
134  } else if (merge_analysis_t & GIT_MERGE_ANALYSIS_NORMAL) {
135  if (p->pullWindow)
136  p->pullWindow->SetText("Performing merge...");
137  git_merge_options merge_opts = GIT_MERGE_OPTIONS_INIT;
138  git_checkout_options checkout_opts = GIT_CHECKOUT_OPTIONS_INIT;
139 
140  merge_opts.file_flags = GIT_MERGE_FILE_STYLE_DIFF3;
141 
142  checkout_opts.checkout_strategy = GIT_CHECKOUT_FORCE |
143  GIT_CHECKOUT_ALLOW_CONFLICTS;
144 
145  err = git_merge(repo,
146  (const git_annotated_commit **)&heads[0], 1,
147  &merge_opts, &checkout_opts);
148  if (err < 0)
149  goto ret;
150  }
151 
152  /* If we get here, we actually performed the merge above */
153  git_index* index;
154  err = git_repository_index(&index, repo);
155  if (err < 0)
156  goto ret;
157 
158  if (git_index_has_conflicts(index)) {
159  /* Handle conflicts */
160  p->pullWindow->Hide();
161  output_conflicts(index);
162  } else {
163  if (p->pullWindow)
164  p->pullWindow->SetText("Applying commit...");
165  create_commit(repo, index, "Merge");
166  printf("Merge made\n");
167  }
168 
169 ret:
170  if (err < 0) {
171  const git_error* er = giterr_last();
172  printf("Error %d : %s\n", er->klass, er->message);
173 
174  BString buffer("Error : %s");
175  buffer.ReplaceFirst("%s", er->message);
176  BAlert *alert = new BAlert("", buffer.String(), "Cancel",
177  0, 0, B_WIDTH_AS_USUAL, B_WARNING_ALERT);
178  alert->Go();
179  }
180 clean:
181  git_repository_free(repo);
182  git_libgit2_shutdown();
183  if (p->pullWindow && p->pullWindow->LockLooper())
184  p->pullWindow->Quit();
185  free(arg);
186 }
187 
188 
194 pthread_t
195 Pull::DoPull(PullWindow* pullWindow, const char* path)
196 {
197  struct pull_params *p = (struct pull_params*)
198  malloc(sizeof(struct pull_params));
199  p->path = path;
200  p->pullWindow = pullWindow;
201  pthread_t thread_id;
202  pthread_create(&thread_id, NULL, DoPullThread, p);
203  return thread_id;
204 }
Pull(BString)
Pull command constructor.
Definition: Pull.cpp:23
const char * path
Definition: Pull.h:32
Payload to search for merge branch.
Definition: Pull.h:23
void output_conflicts(git_index *index)
Shows conflicts in current repo index in a window.
Definition: Utils.cpp:248
virtual void Quit()
The function to Quit the window.
virtual void Execute()
This is where actual calls to libgit2 will go.
Definition: Pull.cpp:33
int create_commit(git_repository *repo, git_index *index, const char *message)
Creates a commit on given repo, index and message.
Definition: Utils.cpp:186
virtual TrackGitWindow * GetWindow()
This returns pointer to the Pull window.
Definition: Pull.cpp:43
static pthread_t DoPull(PullWindow *, const char *)
This spawns thread to perform pull over given repo.
Definition: Pull.cpp:195
GitCommand Class.
Definition: GitCommand.h:20
int fetchhead_ref_cb(const char *name, const char *url, const git_oid *oid, unsigned int is_merge, void *payload_v)
This function gets the branch to be merged.
Definition: Pull.cpp:54
BString fRepo
The repository path where Pull option is selected.
Definition: Pull.h:45
char branch[100]
Definition: Pull.h:24
PullWindow * pullWindow
Definition: Pull.h:33
void * DoPullThread(void *arg)
This does git pull on given repository.
Definition: Pull.cpp:70
TrackGitWindow * fPullWindow
Pull Window.
Definition: Pull.h:49
Header file of Pull command.
git_oid branch_oid
Definition: Pull.h:25
The TrackGit Window class.
void SetText(const char *)
This function sets texts of the textview within window.
Definition: PullWindow.cpp:59
int perform_fastforward(git_repository *repo, const git_oid *target_oid, int is_unborn)
This performs fastforward on given repo, branch id.
Definition: Utils.cpp:103
Parameters to pass to pull thread.
Definition: Pull.h:31
The Pull window class.
Definition: PullWindow.h:22