TrackGit
Clone.cpp
Go to the documentation of this file.
1 
8 #include "Clone.h"
9 #include "../UI/CloneWindow.h"
10 
11 #include <AppKit.h>
12 
13 #include <stdlib.h>
14 #include <strings.h>
15 
16 #include <git2.h>
17 
23 Clone::Clone(BString repo, BString dirPath)
24  :
25  GitCommand()
26 {
27  fRepo = repo;
28  fDirPath = dirPath;
29  fCloneWindow = NULL;
30 }
31 
32 
39 {
40  if (fCloneWindow == NULL)
41  fCloneWindow = new CloneWindow(fRepo, fDirPath, this);
42  return fCloneWindow;
43 }
44 
45 
49 void
51 {
52 }
53 
54 
59 static void
60 print_progress(const progress_data* progress)
61 {
62  int network_percent = progress->fetch_progress.total_objects > 0 ?
63  (100*progress->fetch_progress.received_objects) /
64  progress->fetch_progress.total_objects :
65  0;
66  int index_percent = progress->fetch_progress.total_objects > 0 ?
67  (100*progress->fetch_progress.indexed_objects) /
68  progress->fetch_progress.total_objects :
69  0;
70 
71  int checkout_percent = progress->total_steps > 0
72  ? (100 * progress->completed_steps) / progress->total_steps
73  : 0;
74  int kbytes = progress->fetch_progress.received_bytes / 1024;
75 
76  BString progressString;
77 
78  if (progress->fetch_progress.total_objects &&
79  progress->fetch_progress.received_objects ==
80  progress->fetch_progress.total_objects) {
81  progressString << "Resolving deltas "
82  << progress->fetch_progress.indexed_deltas
83  << "/" << progress->fetch_progress.total_deltas;
84  } else {
85  progressString << "Network " << network_percent
86  << " (" << kbytes << " kb, "
87  << progress->fetch_progress.received_objects << "/"
88  << progress->fetch_progress.total_objects << ")\n";
89  progressString << "Indexed " << index_percent << " ("
90  << progress->fetch_progress.indexed_objects << "/"
91  << progress->fetch_progress.total_objects << ")\n";
92  }
93 
94  if (progress->cloneWindow) {
95  progress->cloneWindow->SetProgressText(progressString);
96  progress->cloneWindow->SetProgress(index_percent);
97  }
98 }
99 
100 
104 static int
105 sideband_progress(const char *str, int len, void *payload)
106 {
107  (void)payload; // unused
108 
109  printf("remote: %.*s\n", len, str);
110  return 0;
111 }
112 
113 
119 static int
120 fetch_progress(const git_transfer_progress *stats, void *payload)
121 {
122  progress_data *progress = (progress_data*)payload;
123  progress->fetch_progress = *stats;
124  print_progress(progress);
125  return 0;
126 }
127 
128 
136 static void
137 checkout_progress(const char *path, size_t cur, size_t tot, void
138  *payload)
139 {
140  progress_data *progress = (progress_data*)payload;
141  progress->completed_steps = cur;
142  progress->total_steps = tot;
143  progress->path = path;
144  print_progress(progress);
145 }
146 
147 
153 void*
154 DoCloneThread(void* arg)
155 {
156  struct param* p = (struct param*) arg;
157  const char* url = p->url;
158  const char* path = p->path;
159 
160  printf("Cloning %s into %s\n", url, path);
161  BString cloneText;
162  cloneText << "Cloning " << url << " into " << path;
163  if (p->cloneWindow)
164  p->cloneWindow->SetProgressText(cloneText);
165 
166  progress_data progress = {{0}};
167  progress.cloneWindow = p->cloneWindow;
168  git_repository *cloned_repo = NULL;
169  git_clone_options clone_opts = GIT_CLONE_OPTIONS_INIT;
170  git_checkout_options checkout_opts = GIT_CHECKOUT_OPTIONS_INIT;
171  int error;
172 
173  git_libgit2_init();
174 
175  // Set up options
176  checkout_opts.checkout_strategy = GIT_CHECKOUT_SAFE;
177  checkout_opts.progress_cb = checkout_progress;
178  checkout_opts.progress_payload = &progress;
179  clone_opts.checkout_opts = checkout_opts;
180  clone_opts.fetch_opts.callbacks.sideband_progress = sideband_progress;
181  clone_opts.fetch_opts.callbacks.transfer_progress = &fetch_progress;
182  clone_opts.fetch_opts.callbacks.payload = &progress;
183 
184  // Do the clone
185  int ret = git_clone(&cloned_repo, url, path, &clone_opts);
186 
187  if (ret != 0) {
188  const git_error* err = giterr_last();
189  printf("Error %d : %s\n", err->klass, err->message);
190 
191  BString buffer("Error : %s");
192  buffer.ReplaceFirst("%s", err->message);
193  BAlert *alert = new BAlert("", buffer.String(), "Cancel",
194  0, 0, B_WIDTH_AS_USUAL, B_WARNING_ALERT);
195  alert->Go();
196  }
197 
198  git_repository_free(cloned_repo);
199  git_libgit2_shutdown();
200  if (p->cloneWindow && p->cloneWindow->LockLooper())
201  p->cloneWindow->Quit();
202  free(arg);
203 }
204 
205 
212 pthread_t
213 Clone::DoClone(CloneWindow* cloneWindow, const char* url, const char* path)
214 {
215  struct param *p = (struct param*) malloc(sizeof(struct param));
216  p->url = url;
217  p->path = path;
219  pthread_t thread_id;
220  pthread_create(&thread_id, NULL, DoCloneThread, p);
221  return thread_id;
222 }
Clone(BString, BString)
Clone class Constructor.
Definition: Clone.cpp:23
static void checkout_progress(const char *path, size_t cur, size_t tot, void *payload)
Prints checkout progress.
Definition: Clone.cpp:137
size_t total_steps
Definition: Clone.h:27
Header file of Clone command.
const char * path
Definition: Clone.h:38
virtual void Quit()
The function to Quit the window.
git_transfer_progress fetch_progress
Definition: Clone.h:25
size_t completed_steps
Definition: Clone.h:26
GitCommand Class.
Definition: GitCommand.h:20
The progress data payload.
Definition: Clone.h:24
void SetProgress(float)
Sets the progress value of the progress bar in progress window.
Definition: CloneWindow.cpp:71
static void print_progress(const progress_data *progress)
Prints progress of command to the progress window.
Definition: Clone.cpp:60
void SetProgressText(BString)
Prints progress text to textview of window.
Definition: CloneWindow.cpp:60
CloneWindow * cloneWindow
Definition: Clone.h:39
const char * url
Definition: Clone.h:37
TrackGitWindow * fCloneWindow
The window to show progress.
Definition: Clone.h:58
TrackGitWindow * GetWindow()
This returns pointer to the clone window.
Definition: Clone.cpp:38
static int sideband_progress(const char *str, int len, void *payload)
Prints the progress from remote.
Definition: Clone.cpp:105
static int fetch_progress(const git_transfer_progress *stats, void *payload)
Creates data structures for printing progress.
Definition: Clone.cpp:120
BString fDirPath
The current directory where Clone option is selected.
Definition: Clone.h:54
Parameters to pass to clone thread.
Definition: Clone.h:36
The Clone Window class.
Definition: CloneWindow.h:30
virtual void Execute()
Clone command execution.
Definition: Clone.cpp:50
pthread_t DoClone(CloneWindow *, const char *, const char *)
Spawns a thread to clone.
Definition: Clone.cpp:213
The TrackGit Window class.
const char * path
Definition: Clone.h:28
CloneWindow * cloneWindow
Definition: Clone.h:29
void * DoCloneThread(void *arg)
Clones the given url into given path along with showing progress in given progress window...
Definition: Clone.cpp:154
BString fRepo
The repo/directory where the command is called.
Definition: Clone.h:50