示例#1
0
static void finish_bulk_checkin(struct bulk_checkin_state *state)
{
	struct object_id oid;
	struct strbuf packname = STRBUF_INIT;
	int i;

	if (!state->f)
		return;

	if (state->nr_written == 0) {
		close(state->f->fd);
		unlink(state->pack_tmp_name);
		goto clear_exit;
	} else if (state->nr_written == 1) {
		sha1close(state->f, oid.hash, CSUM_FSYNC);
	} else {
		int fd = sha1close(state->f, oid.hash, 0);
		fixup_pack_header_footer(fd, oid.hash, state->pack_tmp_name,
					 state->nr_written, oid.hash,
					 state->offset);
		close(fd);
	}

	strbuf_addf(&packname, "%s/pack/pack-", get_object_directory());
	finish_tmp_packfile(&packname, state->pack_tmp_name,
			    state->written, state->nr_written,
			    &state->pack_idx_opts, oid.hash);
	for (i = 0; i < state->nr_written; i++)
		free(state->written[i]);

clear_exit:
	free(state->written);
	memset(state, 0, sizeof(*state));

	strbuf_release(&packname);
	/* Make objects we just wrote available to ourselves */
	reprepare_packed_git();
}
示例#2
0
void bitmap_writer_finish(struct pack_idx_entry **index,
                          uint32_t index_nr,
                          const char *filename,
                          uint16_t options)
{
    static char tmp_file[PATH_MAX];
    static uint16_t default_version = 1;
    static uint16_t flags = BITMAP_OPT_FULL_DAG;
    struct sha1file *f;

    struct bitmap_disk_header header;

    int fd = odb_mkstemp(tmp_file, sizeof(tmp_file), "pack/tmp_bitmap_XXXXXX");

    if (fd < 0)
        die_errno("unable to create '%s'", tmp_file);
    f = sha1fd(fd, tmp_file);

    memcpy(header.magic, BITMAP_IDX_SIGNATURE, sizeof(BITMAP_IDX_SIGNATURE));
    header.version = htons(default_version);
    header.options = htons(flags | options);
    header.entry_count = htonl(writer.selected_nr);
    hashcpy(header.checksum, writer.pack_checksum);

    sha1write(f, &header, sizeof(header));
    dump_bitmap(f, writer.commits);
    dump_bitmap(f, writer.trees);
    dump_bitmap(f, writer.blobs);
    dump_bitmap(f, writer.tags);
    write_selected_commits_v1(f, index, index_nr);

    if (options & BITMAP_OPT_HASH_CACHE)
        write_hash_cache(f, index, index_nr);

    sha1close(f, NULL, CSUM_FSYNC);

    if (adjust_shared_perm(tmp_file))
        die_errno("unable to make temporary bitmap file readable");

    if (rename(tmp_file, filename))
        die_errno("unable to rename temporary bitmap file to '%s'", filename);
}
示例#3
0
文件: transport.c 项目: ruoso/git
int transport_update_ref_remote(struct transport* transport,
				struct ref *remote_refs) {
	// On this command, we need to reproduce small parts of other commands,
	// but because we want to avoid the assumption that we are running from
	// a local git repository, we'll not re-use that code.
	struct git_transport_data *data = transport->data;
	int ret = 0;
	if (!data->got_remote_heads) {
		struct ref *tmp_refs;
		connect_setup(transport, 1, 0);
		get_remote_heads(data->fd[0], NULL, 0, &tmp_refs, REF_NORMAL,
				 NULL, &data->shallow);
		data->got_remote_heads = 1;
	}
	

	// Now we skip into the functionality from send_pack, where
	// we send the new refs to the server. Since this is a lower-level
	// command, we do not do all the checks from
	// set_ref_status_for_push. We also do support all the options
	// that send_pack does
	//
	// TODO: support omitting the old value for existing refs
	struct strbuf req_buf = STRBUF_INIT;
	struct ref *ref;
	int out = data->fd[1];
	for (ref = remote_refs; ref; ref = ref->next) {
	  char *old_hex = sha1_to_hex(ref->old_sha1);
	  char *new_hex = sha1_to_hex(ref->new_sha1);
	  packet_buf_write(&req_buf, "%s %s %s",
			     old_hex, new_hex, ref->name);
	}
	write_or_die(out, req_buf.buf, req_buf.len);
	packet_flush(out);
	strbuf_release(&req_buf);

	// And finally, we skip all the way to write_pack_file
	// This is actually the part that would absolutely depend on
	// having a local git repository.
	//
	// The basic assumption here is that you can only use this
	// command for objects that are already in the remote,
	// otherwise this would be a regular push.
	//
	// The end result is that the pack we need to send is always
	// empty.
	struct sha1file *f;
	unsigned char sha1[20];
	f = sha1fd_throughput(out, "<stdout>", NULL);
	write_pack_header(f, 0);
	sha1close(f, sha1, CSUM_CLOSE);

	// We now finish the connection on the same fashion that
	// git_transport_push does
	close(data->fd[1]);
	close(data->fd[0]);
	ret |= finish_connect(data->conn);
	data->conn = NULL;
	data->got_remote_heads = 0;

	return ret;
}