Example #1
0
void gw_mkdir_with_parents(const ustring & directory)
// Creates directory, with the parents, if need be.
// Function mkdir could be used (see man 2 mkdir), but this does not allow for 
// the creation of the parent directories. The core utility mkdir provides
// this functionality, so is preferred, and used here.
// Later one g_mkdir_with_parents () was used, but this did not create 
// directories properly. Hence we are stuck with mkdir.
{
#if 0
  ustring s;
  GwSpawn spawn (Directories->get_mkdir());
  spawn.arg (Directories->get_mkdir_args());
  spawn.arg (directory);
/*   GwSpawn spawn("mkdir");
#ifndef WIN32
  spawn.arg("-p");
#endif
  spawn.arg(directory);
#ifdef WIN32
  spawn.devnull();
#endif
 */  spawn.run();
 #endif
 
#ifdef WIN32
	// Use Windows system call to do this "right"
	bool retval = CreateDirectory(directory.c_str(), NULL);
	// Returns 0 if OK
	// Returns non-zero if error, and GetLastError will tell us:
	// ERROR_ALREADY_EXISTS The specified directory already exists.
	// ERROR_PATH_NOT_FOUND One or more intermediate directories do not exist; this function will only create the final directory in the path.
	if (retval == 0) {
		int lasterr = GetLastError();
		if (lasterr == ERROR_ALREADY_EXISTS) { 
			// Not really an error, just informative
			mkdir_info("Already exists " + directory);
		}
		else if (lasterr == ERROR_PATH_NOT_FOUND) {
			mkdir_info("Cannot create " + directory + " because intermediate directories don't exist.");
			// Strip off last part of directory and try again recursively
			Glib::ustring::size_type idx = directory.find_last_of("\\");
			ustring newdir = directory.substr(0, idx);
			gw_mkdir_with_parents(newdir);
			// Now try the full path again
			gw_mkdir_with_parents(directory);
		}
	}
	else {
		// Not really an error, just informative
		mkdir_info("Created " + directory);
	}
#else
  GwSpawn spawn (Directories->get_mkdir());
  spawn.arg (Directories->get_mkdir_args());
  spawn.arg (directory);
  spawn.run();
#endif
}
bool RemoteRepositoryAssistant::try_git_checkout_repository (const ustring& local, const ustring& remote)
// Checks the remote repository out into the local one.
{
  // Directory to run the cloning process in.
  ustring cloning_directory = git_testing_directory (local) + "clone";
  gw_mkdir_with_parents(cloning_directory);

  // Clone the remote repository.
  GwSpawn spawn("git");
  spawn.arg("clone");
  spawn.workingdirectory(cloning_directory);
  spawn.arg(git_testing_directory (remote));
  spawn.run();
  bool okay = (spawn.exitstatus == 0);

  // Message if things didn't work out.
  if (!okay) {
    gtk_label_set_text(GTK_LABEL(label_try_git), _("git clone fails to clone the repository"));
  }
  
  // Move the repository into place.
  ustring cloned_directory = gw_build_filename (cloning_directory, remote);
  ustring local_directory = git_testing_directory (local);
  unix_rmdir(local_directory);
  if (okay) {
    unix_mv(cloned_directory, local_directory);
  }
  unix_rmdir(cloning_directory);
  
  // Return result.
  return okay;
}
Example #3
0
void resource_viewer_ensure_directory()
// Ensures that the working directory for the resource viewer is there.
{
  ustring directory = resource_viewer_directory();
  if (!g_file_test(directory.c_str(), G_FILE_TEST_IS_DIR)) {
    gw_mkdir_with_parents(directory);
  }
}
Example #4
0
bool uncompress(const ustring & archive, const ustring & directory)
// Uncompresses "archive" into "directory".
// Returns whether this was successful.
{
  // Bail out if the archive was not recognized.
  if (!compressed_archive_recognized(archive)) {
    gw_critical(_("cannot uncompress unrecognized archive"));
    return false;
  }
  // Ensure that the output directory is there.
  gw_mkdir_with_parents (directory);

  // Get the uncompression identifier.
  int uncompression_identifier = uncompression_identifier_get (archive);

  // Do the uncompression.
  int result = -1;
  switch (uncompression_identifier) {
  case 0:
    {
		gw_message("I'm not yet smart enough to handle the " + archive + " file type");
		break;
    }
  case 1:
    { // If you have a zip utility installed in Windows, etc.
      GwSpawn spawn (Directories->get_unzip());
      spawn.arg ("-o"); // overwrite without prompting
      if (!directory.empty ()) {
        spawn.arg ("-d"); // extract files into exdir
        spawn.arg (directory);
      }
      spawn.arg (archive);
      spawn.progress (_("Unpacking"), false);
      spawn.run ();
      result = 0;
      break;
    }
  case 2:
    {
      GwSpawn spawn(Directories->get_tar());
	  spawn.arg ("--force-local"); // to permit : in filename (like C:\Users\...)
      spawn.arg("-xvzf"); // x=eXtract, z=gunZip, f=Filename to extract
      if (!directory.empty()) {
        spawn.workingdirectory(directory);
      }
      spawn.arg(archive);
      spawn.progress(_("Unpacking"), false);
      spawn.run();
      result = spawn.exitstatus;
	  DEBUG("tar return code="+std::to_string(result));
      break;
    }
  }

  // Return whether things were ok.  
  return (result == 0);
}
void RemoteRepositoryAssistant::on_button_clone ()
{
  // Progress.
  ProgressWindow progresswindow (_("Cloning repository"), false);
  progresswindow.set_fraction (0.5);
  
  // Clear out persistent clone directory.
  repository_unclone();
  
  // Create temporal clone directory.
  ustring temporal_clone_directory = git_testing_directory ("tempclone");
  unix_rmdir(temporal_clone_directory);
  gw_mkdir_with_parents(temporal_clone_directory);
  
  // Clone the remote repository
  GwSpawn spawn("git");
  spawn.workingdirectory(temporal_clone_directory);
  spawn.arg ("clone");
  spawn.arg(repository_url_get());
  spawn.run();

  if (spawn.exitstatus == 0) {
    // Move the cloned repository into the persistent clone directory.
    ReadDirectories rd (temporal_clone_directory, "", "");
    if (!rd.directories.empty()) {
      ustring subdirectory = rd.directories[0];
      subdirectory = gw_build_filename (temporal_clone_directory, subdirectory);
      unix_mv (subdirectory, persistent_clone_directory);
    }
    unix_rmdir(temporal_clone_directory);
  } else {
    // Clone failed, clear out any remains.
    repository_unclone();
  }  
  
  // Update structures.
  gtk_assistant_set_page_complete (GTK_ASSISTANT (assistant), vbox_clone, repository_was_cloned());
  if (repository_was_cloned()) {
    gtk_label_set_text (GTK_LABEL (label_clone), _("The data has been cloned, you can go forward"));
    previously_cloned_url = repository_url_get();
  } else {
    gtk_label_set_text (GTK_LABEL (label_clone), _("Cloning the data failed, please try again"));
    repository_unclone();
  }
}
bool RemoteRepositoryAssistant::try_git_create_repository (const ustring& name, bool remote)
{
  ustring directory = git_testing_directory (name);
  gw_mkdir_with_parents (directory);
  GwSpawn spawn ("git");
  spawn.workingdirectory (directory);
  if (remote) 
    spawn.arg ("--bare");
  spawn.arg ("init");
  if (remote)
    spawn.arg ("--shared");
  spawn.run();
  bool okay = (spawn.exitstatus == 0);
  if (!okay) {
    gtk_label_set_text(GTK_LABEL(label_try_git), _("git init fails to create a repository"));
  }
  return okay;
}
Example #7
0
void notes_storage_verify()
// Verify / setup the project notes storage system.
{
    // Check an/or create the notes storage area.
    ustring directory;
    directory = notes_shared_storage_folder ();
    if (!g_file_test(directory.c_str(), G_FILE_TEST_IS_DIR)) {
        gw_mkdir_with_parents (directory);
    }

    // Convert old notes database to new format in separate files.
    // The reason for this is that notes in separate files can be shared through git.
    notes_convert_database_to_plain_files ();

    // If there's no index, create one.
    if (!g_file_test(notes_index_filename ().c_str(), G_FILE_TEST_IS_REGULAR)) {
        notes_create_index ();
    }
}
Example #8
0
void OpenDocument::unpack_template()
{
  // Clear working directory.
  unix_rmdir(workingdirectory);
  gw_mkdir_with_parents(workingdirectory);
  // Copy template there.
  // Note: To create the template use zip -r template.odt *
#ifdef WIN32
  ustring command = "unzip -o ";
  command.append(gw_build_filename(Directories->get_package_data(), "template.odt"));
  command.append(" -d ");
  command.append(shell_quote_space(workingdirectory));
#else
  ustring command = "cd";
  command.append(shell_quote_space(workingdirectory));
  command.append("; cp ");
  command.append(gw_build_filename(Directories->get_package_data(), "template.odt"));
  command.append(" .; unzip *; rm *.odt");
#endif
  if (system(command.c_str())) ; // This one does not work with GwSpawn because of the wildcards used.
}
void RestoreAssistant::on_assistant_apply ()
{
  // Unpack the tarball.
  ustring unpack_directory = gw_build_filename (Directories->get_temp (), "restore");
  unix_rmdir (unpack_directory);
  gw_mkdir_with_parents (unpack_directory);
  if (uncompress (filename, unpack_directory)) {

    // Do specialized operations on the unpacked data.
    switch (get_type()) {
      case btBible:
      {
        restore_project (unpack_directory, bible_name, restore_feedback);
        break;
      }
      case btNotes:
      {
        restore_notes (unpack_directory, restore_feedback);
        break;
      }
      case btResource:
      {
        restore_resource (unpack_directory, restore_feedback);
        break;
      }
      case btAll:
      {
        restore_all_stage_one (unpack_directory, restore_feedback);
        break;
      }
    }
  } else {
    restore_feedback.push_back (_("Failed to unpack file ") + filename);
  }
 
  // Show summary.
  gtk_assistant_set_current_page (GTK_ASSISTANT (assistant), page_number_progress);
}
Example #10
0
void XeTeX::create_work_area ()
{
  working_directory = gw_build_filename (Directories->get_temp (), "xetex");
  unix_rmdir (working_directory);
  gw_mkdir_with_parents (working_directory);
}
Example #11
0
void mechon_mamre_action_page (HtmlWriter2& htmlwriter)
{
  htmlwriter.heading_open (3);
  htmlwriter.text_add (_("Hebrew import from Mechon Mamre"));
  htmlwriter.heading_close ();

  vector <ustring> messages;
  bool keep_going = true;

  // Locate the downloaded file.
  ustring ct005zipfilename = gw_build_filename (g_get_home_dir (), "ct005.zip");
  messages.push_back (_("Looking for file ") + ct005zipfilename);
  if (!g_file_test (ct005zipfilename.c_str(), G_FILE_TEST_IS_REGULAR)) {
    ct005zipfilename.clear();
  }
  if (ct005zipfilename.empty()) {
    ct005zipfilename = gw_build_filename (g_get_home_dir (), "Desktop", "ct005.zip");
    messages.push_back (_("Looking for file ") + ct005zipfilename);
    if (!g_file_test (ct005zipfilename.c_str(), G_FILE_TEST_IS_REGULAR)) {
      ct005zipfilename.clear();
    }
  }
  if (ct005zipfilename.empty()) {
    ct005zipfilename = gw_build_filename (g_get_home_dir (), "Downloads", "ct005.zip");
    messages.push_back (_("Looking for file ") + ct005zipfilename);
    if (!g_file_test (ct005zipfilename.c_str(), G_FILE_TEST_IS_REGULAR)) {
      ct005zipfilename.clear();
    }
  }
  if (ct005zipfilename.empty()) {
    messages.push_back (_("Can't find Hebrew input file"));
    keep_going = false;
  }
  if (keep_going) {
    messages.push_back (_("Using file ") + ct005zipfilename);
  }

  // Unpack the zipped file.
  ustring directory;
  if (keep_going) {
    directory = gw_build_filename (Directories->get_temp (), "uncompress");
    unix_rmdir (directory);
    gw_mkdir_with_parents (directory);
    if (!uncompress (ct005zipfilename, directory)) {
      messages.push_back (_("Could not unpack the file"));
      keep_going = false;
    }
    messages.push_back (_("Unpacking into folder ") + directory);
  }

  // Show the readme file.
  if (keep_going) {
    ustring readmefile = gw_build_filename (directory, "readme.txt");
    ReadText rt (readmefile, true, true);
    ustring line;
    for (unsigned int i = 0; i < rt.lines.size(); i++) {
      if (rt.lines[i].empty()) {
        if (!line.empty()) {
          messages.push_back (line);
          line.clear();
        }
      } else {
        line.append (rt.lines[i] + " ");
      }
    }
    messages.push_back (line);
  }

  // Look for the directory where all the html files reside.
  if (keep_going) {
    directory = gw_build_filename (directory, "c", "ct");
    if (!g_file_test (directory.c_str(), G_FILE_TEST_IS_DIR)) {
      messages.push_back (_("Can't find data in directory ") + directory);
    }
    messages.push_back (_("Looking for data in directory ") + directory);
  }
  
  // Get a list of the html files that have the data.
  vector <ustring> files;
  if (keep_going) {
    ReadFiles rf (directory, "c", ".htm");
    for (unsigned int i = 0; i < rf.files.size(); i++) {
      ustring filename = gw_build_filename (directory, rf.files[i]);
      // Check on a few characteristics.
      if (mechon_mamre_copyright(filename)) {
        unsigned int digitcount = digit_count_in_string(rf.files[i]);
        if ((digitcount == 3) || (digitcount == 4)) {
          files.push_back(filename);
        }
      }
    }
  }

  // Create a new Bible into which to import the data.
  ustring bible = _("Hebrew Mechon Mamre");
  if (keep_going) {
    if (project_exists (bible)) {
      messages.push_back (_("A Bible already exists by this name: ") + bible);
      keep_going = false;      
    } else {
      project_create_restore (bible, "");
      messages.push_back (_("Creating a new Bible called \"") + bible + "\"");
      // Make a couple of settings.
      extern Settings * settings;
      ProjectConfiguration * projectconfig = settings->projectconfig (bible);
      projectconfig->versification_set ("Original");
      projectconfig->editable_set (false);
      projectconfig->right_to_left_set (true);
      projectconfig->spelling_check_set (false);
    }
  }

  // Store all the chapters 0 in each book.
  if (keep_going) {
    vector <unsigned int> books = books_type_to_ids(btOldTestament);
    ProgressWindow progresswindow (_("Creating books"), false);
    progresswindow.set_iterate (0, 1, books.size());
    for (unsigned int bk = 0; bk < books.size(); bk++) {
      progresswindow.iterate ();
      vector <ustring> usfm;
      usfm.push_back ("\\id " + books_id_to_paratext (books[bk]));
      CategorizeChapterVerse ccv (usfm);      
      project_store_chapter (bible, books[bk], ccv);
    }  
  }

  // Store all the chapters.
  if (keep_going) {
    ProgressWindow progresswindow (_("Importing chapters"), false);
    progresswindow.set_iterate (0, 1, files.size());
    for (unsigned int i = 0; i < files.size(); i++) {
      progresswindow.iterate ();
      unsigned int book = 0;
      unsigned int chapter = 0;
      mechon_mamre_extract_book_chapter (files[i], book, chapter);
      vector <ustring> contents = mechon_mamre_extract_contents (files[i], chapter);
      CategorizeChapterVerse ccv (contents);
      project_store_chapter (bible, book, ccv);
      messages.push_back (_("Importing ") + books_id_to_localname (book) + " " + convert_to_string (chapter) + _(" from file ") + files[i]);
    }
  }

  // Write accumulated messages.
  htmlwriter.heading_open (3);
  if (keep_going) {
    htmlwriter.text_add (_("Success! Bible was created: ") + bible);
  } else {
    htmlwriter.text_add (_("Error!"));
  }
  htmlwriter.heading_close ();
  if (keep_going) {
    htmlwriter.paragraph_open ();
    htmlwriter.text_add (_("To view the Hebrew text, open the Bible in the editor. Optionally set the font for better display of the Hebrew text. A donation made to Mechon Mamre will support their work."));
    htmlwriter.paragraph_close ();
  }
  for (unsigned int i = 0; i < messages.size(); i++) {
    htmlwriter.paragraph_open ();
    htmlwriter.text_add (messages[i]);
    htmlwriter.paragraph_close ();
  }  
  
  // Write OK.
  htmlwriter.paragraph_open ();
  htmlwriter.hyperlink_add ("ok", _("Ok"));
  htmlwriter.paragraph_close ();
}
Example #12
0
void WindowMerge::merge_edited_into_master(bool approve)
// This merges the edited data into the master data, and does error checking.
{
  // Bail out if there's nothing to merge.
  if (main_project_data == edited_project_data) {
    gtkw_dialog_info(NULL, _("Both the chapters already are the same"));
    return;
  }

  // Get the available snapshots of the master and edited projects.
  vector <unsigned int> masterseconds = snapshots_get_seconds (current_master_project, book, chapter);
  vector <unsigned int> editedseconds = snapshots_get_seconds (current_edited_project, book, chapter);

  // We need to look for the common ancestor.
  // It needs a fast routine that goes through the history as little as possible.

  // Make a combined set of the times and flags.
  vector <bool> combinedflags;
  vector <unsigned int> combinedseconds;
  for (unsigned int i = 0; i < masterseconds.size(); i++) {
    combinedflags.push_back (true);
    combinedseconds.push_back (masterseconds[i]);    
  }
  for (unsigned int i = 0; i < editedseconds.size(); i++) {
    combinedflags.push_back (false);
    combinedseconds.push_back (editedseconds[i]);    
  }
  // Sort the combined set on the time, most recent ones first.
  quick_sort (combinedseconds, combinedflags, 0, combinedseconds.size());
  {
    vector <bool> flags = combinedflags;
    vector <unsigned int> seconds = combinedseconds;
    combinedflags.clear();
    combinedseconds.clear();
    for (int i = flags.size() - 1; i >= 0; i--) {
      combinedflags.push_back (flags[i]);
      combinedseconds.push_back (seconds[i]);
    }
  }

  // Go through the history of both projects, extract the state in history,
  // and compare them in order to find the common ancestor.
  vector <ustring> mastertexts;
  vector <ustring> editedtexts;
  ustring common_ancestor;
  for (unsigned int i = 0; i < combinedseconds.size(); i++) {
    unsigned int second = combinedseconds[i];
    bool master = combinedflags[i];
    if (master) {
      mastertexts.push_back(snapshots_get_chapter(current_master_project, book, chapter, second));
    } else {
      editedtexts.push_back(snapshots_get_chapter(current_edited_project, book, chapter, second));
    }
    for (unsigned int m = 0; m < mastertexts.size(); m++) {
      for (unsigned int e = 0; e < editedtexts.size(); e++) {
        if (common_ancestor.empty()) {
          if (mastertexts[m] == editedtexts[e]) {
            common_ancestor = mastertexts[m];
          }
        }
      }
    }
    if (!common_ancestor.empty()) {
      break;
    }
  }  

  // If no common ancestor was found, give message and bail out.
  if (common_ancestor.empty()) {
    gtkw_dialog_error(NULL, _("Can't merge because a common ancestor was not found"));
    return;
  }
  // Do the merge in a temporal directory.
  workingdirectory = gw_build_filename(Directories->get_temp(), "merge");
  unix_rmdir(workingdirectory);
  gw_mkdir_with_parents(workingdirectory);

  /*
     Merge works with file1, file2 and file3.

     merge [ options ] file1 file2 file3

     merge incorporates all changes that lead from file2 to file3 into file1.
     The result ordinarily goes into file1.
     merge is useful for combining separate changes to an original. 
     Suppose file2 is the original, and both file1 and file3 are modifications of file2. 
     Then merge combines both changes.
   */
  ustring file1 = gw_build_filename(workingdirectory, "file1");
  ustring file2 = gw_build_filename(workingdirectory, "file2");
  ustring file3 = gw_build_filename(workingdirectory, "file3");

  /*
     merge has problems when two consecutive lines are changed, 
     one line in one file and the other line in the other file. 
     Therefore data is going to be cut on the spaces, 
     so that there is one word per line. 
     Each new line is indicated too so as to facilitate joining the loose bits again.
     Another advantage of this is that the merge operation becomes finer grained.
   */

  // Write the data for the common ancestor.
  g_file_set_contents(file2.c_str(), merge_split_data(common_ancestor).c_str(), -1, NULL);

  // Write the data for the main project.
  g_file_set_contents(file1.c_str(), merge_split_data(main_project_data).c_str(), -1, NULL);

  // Write the data for the edited project.
  g_file_set_contents(file3.c_str(), merge_split_data(edited_project_data).c_str(), -1, NULL);

  // Do the three-way merge.
  {
    GwSpawn spawn("merge");
    spawn.workingdirectory(workingdirectory);
    spawn.arg(file1);
    spawn.arg(file2);
    spawn.arg(file3);
    spawn.run();
  }

  // Read the result of the merge.
  ustring merge_result;
  {
    gchar *contents;
    g_file_get_contents(file1.c_str(), &contents, NULL, NULL);
    if (contents) {
      merge_result = contents;
      g_free(contents);
    }
  }

  // Make conflicts human readable.
  merge_result = merge_conflicts_2_human_readable_text(merge_result);

  // Join the bits again.
  merge_result = merge_join_data(merge_result);

  // If there are conflicts, resolve them.
  if (merge_result.find(merge_conflict_markup(1)) != string::npos) {
    MergeDialog dialog(merge_result);
    if (dialog.run() == GTK_RESPONSE_OK) {
      merge_result = dialog.reconciled_text;
    }
  }
  // If there are still conflicts, give a message and bail out.
  if (merge_result.find(merge_conflict_markup(1)) != string::npos) {
    gtkw_dialog_error(NULL, _("The chapters were not merged"));
    return;
  }

  if (approve) {

    // Setup the approval system.
    approval_setup(main_project_data, merge_result);

  } else {

    // Store the merge result in both chapters.  
    ParseLine parseline(merge_result);
    CategorizeChapterVerse ccv(parseline.lines);
    project_store_chapter(current_master_project, book, ccv);
    project_store_chapter(current_edited_project, book, ccv);
    // A normal snapshot may be removed over time, so we need a persistent one to enable future merges.
    snapshots_shoot_chapter (current_master_project, book, chapter, 0, true);
    snapshots_shoot_chapter (current_edited_project, book, chapter, 0, true);

    // Message ok.
    gtkw_dialog_info(NULL, _("The chapters were successfully merged"));

  }
}
bool RemoteRepositoryAssistant::try_git ()
// Tries git and returns true if everything's fine.
{
  // Progress.
  ProgressWindow progresswindow (_("Trying the contents tracker"), false);
  
  // Whether git is okay.
  bool okay = true;
  
  if (okay) {
    progresswindow.set_fraction (0.05);
    gw_message (_("Check git version number"));
    okay = check_git_version ();
  }
  
  // Clean the directory to work in.
  {
    ustring directory = git_testing_directory ("");
    unix_rmdir (directory);
    gw_mkdir_with_parents (directory);
  }
  
  if (okay) {
    progresswindow.set_fraction (0.11);
    gw_message (_("Create first local repository"));
    okay = try_git_create_repository ("local1", false);
  }

  if (okay) {
    progresswindow.set_fraction (0.17);
    gw_message (_("Store data into first local repository"));
    okay = try_git_store_data_in_repository ("local1", "--test--");
  }

  if (okay) {
    progresswindow.set_fraction (0.23);
    gw_message (_("Create remote repository"));
    okay = try_git_create_repository ("remote", true);
  }

  if (okay) {
    progresswindow.set_fraction (0.29);
    gw_message (_("Fetch data from the first local repository into the remote one"));
    okay = try_git_fetch_repository ("remote", "local1");
  }

  if (okay) {
    progresswindow.set_fraction (0.35);
    gw_message (_("Checkout the first local repository"));
    okay = try_git_checkout_repository ("local1", "remote");
  }

  if (okay) {
    progresswindow.set_fraction (0.41);
    gw_message (_("Check data of first local repository"));
    okay = try_git_check_data_in_repository ("local1", "--test--");
  }

  if (okay) {
    progresswindow.set_fraction (0.47);
    gw_message (_("Checkout the second local repository"));
    okay = try_git_checkout_repository ("local2", "remote");
  }

  if (okay) {
    progresswindow.set_fraction (0.52);
    gw_message (_("Check data of second local repository"));
    okay = try_git_check_data_in_repository ("local2", "--test--");
  }

  if (okay) {
    progresswindow.set_fraction (0.58);
    gw_message (_("Store different data into first repository"));
    okay = try_git_store_data_in_repository ("local1", "---test---");
  }

  if (okay) {
    progresswindow.set_fraction (0.64);
    gw_message (_("Push first repository"));
    okay = try_git_push_repository ("local1");
  }

  if (okay) {
    progresswindow.set_fraction (0.70);
    gw_message (_("Pull second repository"));
    okay = try_git_pull_repository ("local2");
  }

  if (okay) {
    progresswindow.set_fraction (0.76);
    gw_message ("Check data in second repository");
    okay = try_git_check_data_in_repository ("local2", "---test---");
  }

  if (okay) {
    progresswindow.set_fraction (0.82);
    gw_message (_("Store different data into second repository"));
    okay = try_git_store_data_in_repository ("local2", "----test----");
  }

  if (okay) {
    progresswindow.set_fraction (0.88);
    gw_message (_("Push second repository"));
    okay = try_git_push_repository ("local2");
  }

  if (okay) {
    progresswindow.set_fraction (0.94);
    gw_message (_("Pull first repository"));
    okay = try_git_pull_repository ("local1");
  }

  if (okay) {
    progresswindow.set_fraction (1);
    gw_message (_("Check data in first repository"));
    okay = try_git_check_data_in_repository ("local1", "----test----");
  }

  // Return whether git is ok.
  return okay;
}