/* Traverse the commit graph until remote_id is met or a merged commit * (commit with two parents) is met. * * If a merged commit is met before remote_id, that implies that * we did a real merge when merged with the branch headed by remote_id. * In this case we'll need more computation to find out the "delta" commits * between these two branches. Otherwise, if the merge was a fast-forward * one, it's enough to just send all the commits between our head commit * and remote_id. */ static gboolean traverse_commit_fast_forward (SeafCommit *commit, void *data, gboolean *stop) { CcnetProcessor *processor = data; TransferTask *task = ((SeafileSendcommitV3Proc *)processor)->tx_task; USE_PRIV; if (priv->remote_id[0] != 0 && strcmp (priv->remote_id, commit->commit_id) == 0) { *stop = TRUE; return TRUE; } if (commit->second_parent_id != NULL) { *stop = TRUE; priv->fast_forward = FALSE; return TRUE; } priv->id_list = g_list_prepend (priv->id_list, g_strdup(commit->commit_id)); /* We don't need to send the contents under an empty dir. */ if (strcmp (commit->root_id, EMPTY_SHA1) != 0) object_list_insert (task->fs_roots, commit->root_id); object_list_insert (task->commits, commit->commit_id); return TRUE; }
static void delete_command_undo(Command_t *parent) { DeleteCommand_t *command = (DeleteCommand_t*) parent; object_list_insert(command->list, command->position, command->obj); object_list_set_changed(command->list, command->changed); }
static void commit_write_cb (OSAsyncResult *res, void *data) { CcnetProcessor *processor = data; TransferTask *task = ((SeafileGetcommitV3Proc *)processor)->tx_task; SeafCommit *commit; if (!res->success) { seaf_warning ("Failed to write commit %.8s.\n", res->obj_id); transfer_task_set_error (task, TASK_ERR_DOWNLOAD_COMMIT); ccnet_processor_send_update (processor, SC_SHUTDOWN, SS_SHUTDOWN, NULL, 0); ccnet_processor_done (processor, FALSE); return; } commit = seaf_commit_from_data (res->obj_id, res->data, res->len); if (!commit) { seaf_warning ("[getcommit] Bad commit object received.\n"); transfer_task_set_error (task, TASK_ERR_DOWNLOAD_COMMIT); ccnet_processor_send_update (processor, SC_BAD_OBJECT, SS_BAD_OBJECT, NULL, 0); ccnet_processor_done (processor, FALSE); return; } if (strcmp (commit->root_id, EMPTY_SHA1) != 0) object_list_insert (task->fs_roots, commit->root_id); seaf_commit_unref (commit); ccnet_processor_done (processor, TRUE); }
static gboolean collect_upload_commit_ids (SeafCommit *commit, void *data, gboolean *stop) { CcnetProcessor *processor = data; TransferTask *task = ((SeafileSendcommitV3Proc *)processor)->tx_task; USE_PRIV; if (strcmp (priv->last_uploaded_id, commit->commit_id) == 0) { priv->visited_last_uploaded = TRUE; *stop = TRUE; return TRUE; } if (priv->remote_id[0] != 0 && strcmp (priv->remote_id, commit->commit_id) == 0) { *stop = TRUE; return TRUE; } if (commit->parent_id && !seaf_commit_manager_commit_exists (seaf->commit_mgr, commit->repo_id, commit->version, commit->parent_id)) { *stop = TRUE; return TRUE; } if (commit->second_parent_id && !seaf_commit_manager_commit_exists (seaf->commit_mgr, commit->repo_id, commit->version, commit->second_parent_id)) { *stop = TRUE; return TRUE; } priv->id_list = g_list_prepend (priv->id_list, g_strdup(commit->commit_id)); /* We don't need to send the contents under an empty dir. */ if (strcmp (commit->root_id, EMPTY_SHA1) != 0) object_list_insert (task->fs_roots, commit->root_id); object_list_insert (task->commits, commit->commit_id); return TRUE; }
static gboolean commit_collector (SeafCommit *commit, void *data, gboolean *stop) { ObjectList *ol = data; object_list_insert (ol, commit->commit_id); return TRUE; }
static gboolean compute_delta (SeafCommit *commit, void *data, gboolean *stop) { CcnetProcessor *processor = data; TransferTask *task = ((SeafileSendcommitV3Proc *)processor)->tx_task; USE_PRIV; if (!g_hash_table_lookup (priv->commit_hash, commit->commit_id)) { priv->id_list = g_list_prepend (priv->id_list, g_strdup(commit->commit_id)); if (strcmp (commit->root_id, EMPTY_SHA1) != 0) object_list_insert (task->fs_roots, commit->root_id); object_list_insert (task->commits, commit->commit_id); } else { /* Stop traversing down from this commit if it already exists * in the remote branch. */ *stop = TRUE; } return TRUE; }
static void one_remote_object(const struct object_id *oid) { struct object *obj; obj = lookup_object(oid->hash); if (!obj) obj = parse_object(oid); /* Ignore remote objects that don't exist locally */ if (!obj) return; obj->flags |= REMOTE; if (!object_list_contains(objects, obj)) object_list_insert(obj, &objects); }
static int process(struct walker *walker, struct object *obj) { if (obj->flags & SEEN) return 0; obj->flags |= SEEN; if (has_sha1_file(obj->sha1)) { /* We already have it, so we should scan it now. */ obj->flags |= TO_SCAN; } else { if (obj->flags & COMPLETE) return 0; walker->prefetch(walker, obj->sha1); } object_list_insert(obj, process_queue_end); process_queue_end = &(*process_queue_end)->next; return 0; }
static gboolean traverse_commit (SeafCommit *commit, void *data, gboolean *stop) { CcnetProcessor *processor = data; TransferTask *task = ((SeafileSendcommitV2Proc *)processor)->tx_task; USE_PRIV; if (priv->end_commit_id[0] != 0 && strcmp (priv->end_commit_id, commit->commit_id) == 0) { *stop = TRUE; return TRUE; } send_commit (processor, commit->commit_id); if (strcmp (commit->root_id, EMPTY_SHA1) != 0) object_list_insert (task->fs_roots, commit->root_id); return TRUE; }
static void receive_commit (CcnetProcessor *processor, char *content, int clen) { ObjectPack *pack = (ObjectPack *)content; TransferTask *task = ((SeafileGetcommitV2Proc *)processor)->tx_task; SeafCommit *commit; if (clen < sizeof(ObjectPack)) { g_warning ("[getcommit] invalid object id.\n"); goto bad; } seaf_debug ("[getcommit] recv commit object %.8s\n", pack->id); if (save_commit (pack, clen) < 0) { goto bad; } commit = seaf_commit_manager_get_commit (seaf->commit_mgr, pack->id); if (!commit) goto bad; if (strcmp (commit->root_id, EMPTY_SHA1) != 0) object_list_insert (task->fs_roots, commit->root_id); seaf_commit_unref (commit); return; bad: g_warning ("[getcommit] Bad commit object received.\n"); transfer_task_set_error (((SeafileGetcommitV2Proc *)processor)->tx_task, TASK_ERR_DOWNLOAD_COMMIT); ccnet_processor_send_update (processor, SC_BAD_OBJECT, SS_BAD_OBJECT, NULL, 0); ccnet_processor_done (processor, FALSE); }