[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Monotone-devel] Re: Commit without working copy

From: graydon hoare
Subject: [Monotone-devel] Re: Commit without working copy
Date: Sat, 04 Dec 2004 00:01:53 -0500
User-agent: Mozilla Thunderbird 0.8 (X11/20040913)

Grzegorz Jakacki wrote:

OK, thanks. Where should I look into the code if I want to add it?

I have to apologize for all the worried talk here today; I don't really know what the big deal is, this command only takes about 10 minutes to write. I just wrote it. if you stick this in you should get mostly the behavior you want:

    "commit change to a single file")
  if (args.size() != 2 && args.size() != 3)
    throw usage(name);

  file_id old_fid, new_fid;
  revision_id old_rid, new_rid;
  manifest_id old_mid, new_mid;
  manifest_map old_man, new_man;
  file_data old_fdata, new_fdata;
  cert_value branchname;
  revision_data rdata;
  revision_set rev;
  change_set cs;

  string log_message("");
  base64< gzip< data > > gz_dat;
  base64< gzip< delta > > gz_del;
  file_path pth(idx(args, 1)());

  transaction_guard guard(app.db);
  packet_db_writer dbw(app);

  complete(app, idx(args, 0)(), old_rid);

  // find the old rev, manifest and file
  app.db.get_revision_manifest(old_rid, old_mid);
  app.db.get_manifest(old_mid, old_man);
  manifest_map::const_iterator i = old_man.find(pth);
  N(i != old_man.end(),
    F("cannot find file %s revision %s")
    % pth % old_rid);

  // fetch the new file input
  string s = get_stdin();
  pack(data(s), gz_dat);
  new_fdata = file_data(gz_dat);
  calculate_ident(new_fdata, new_fid);

  // diff and store the file edge
  old_fid = manifest_entry_id(i);
  app.db.get_file_version(old_fid, old_fdata);
  diff(old_fdata.inner(), new_fdata.inner(), gz_del);
  dbw.consume_file_delta(old_fid, new_fid,

  // diff and store the manifest edge
  new_man = old_man;
  new_man[pth] = new_fid;
  calculate_ident(new_man, new_mid);
  diff(old_man, new_man, gz_del);
  dbw.consume_manifest_delta(old_mid, new_mid,

  // build and store a changeset and revision
  cs.apply_delta(pth, old_fid, new_fid);
  rev.new_manifest = new_mid;
                                  std::make_pair(old_mid, cs)));
  calculate_ident(rev, new_rid);
  write_revision_set(rev, rdata);
  dbw.consume_revision_data(new_rid, rdata);

  // take care of any extra certs
  guess_branch (old_rid, app, branchname);

  if (args.size() == 3)
    log_message = idx(args, 2)();
    get_log_message(rev, app, log_message);

  N(log_message.find_first_not_of(" \r\t\n") != string::npos,
    F("empty log message"));

  cert_revision_in_branch(new_rid, branchname, app, dbw);
  cert_revision_date_now(new_rid, app, dbw);
  cert_revision_author_default(new_rid, app, dbw);
  cert_revision_changelog(new_rid, log_message, app, dbw);

  // finish off

if you like I can add this as a "standard" monotone command, though it seems a bit special-purpose.. there is certainly some background pressure to overhaul monotone's command-line interface a bit. I was hoping to get around to that sometime after all these extra branches are integrated.


reply via email to

[Prev in Thread] Current Thread [Next in Thread]