unrecord: show list of changes if none were given as arguments

[?]
Dec 16, 2020, 8:57 PM
SLJ3OHD4F6GJGZ3SV2D7DMR3PXYHPSI64X77KZ3RJ24EGEX6ZNQAC

Dependencies

  • [2] 62XVBWPY remove redundant Clap attributes
  • [3] SE4RJYBZ No pager on Windows (really not)
  • [4] H23LO7U7 a few more clippy lints addressed
  • [5] BBKV6VMN Fixing push/pull messages, and do not reverse the changes to download/upload
  • [6] IMCZFTIJ Update selection instructions to also mention pushing
  • [7] BE7GUCI2 Completing dependencies only with changes the remote does not have
  • [8] M5FK3ABT Complete dependencies when pushing and pulling
  • [9] XWETQ4DE Upgrading versions
  • [10] OAXTXEAF commands/pushpull: display dependencies of change
  • [11] JWTT77WJ Add help on subcommands
  • [12] I52XSRUH Massive cleanup, and simplification
  • [13] L4JXJHWX pijul/*: reorganize imports and remove extern crate
  • [14] SXEYMYF7 Fixing the bad changes in history (unfortunately, by rebooting).
  • [15] 5DVRL6MF Hard-unrecord
  • [16] GUNVHCG3 commands/pushpull: show change description if it exists
  • [17] YAJAXIV5 Unrecording changes atomically
  • [18] AEPEFS7O Write help for each argument
  • [19] K6GWUOD5 Styling progress bars
  • [20] UTDZKZGP infer subcommands

Change contents

  • replacement in pijul/src/main.rs at line 94
    [2.106][6.701:751](),[6.85496][6.701:751]()
    /// Unrecords all changes upto the given hash
    [2.106]
    [6.85558]
    /// Unrecords a list of changes.
    ///
    /// The changes will be removed from your log, but your working
    /// copy will stay exactly the same, unless the
    /// `--reset` flag was passed. A change can only be unrecorded
    /// if all changes that depend on it are also unrecorded in the
    /// same operation. There are two ways to call `pijul-unrecord`:
    ///
    /// * With a list of <change-id>s. The given changes will be
    /// unrecorded, if possible.
    ///
    /// * Without listing any <change-id>s. You will be
    /// presented with a list of changes to choose from.
    /// The length of the list is determined by the `unrecord_changes`
    /// setting in your global config or the `--show-changes` option,
    /// with the latter taking precedence.
  • edit in pijul/src/config.rs at line 11
    [6.90002]
    [6.90002]
    pub unrecord_changes: Option<usize>,
  • replacement in pijul/src/commands/unrecord.rs at line 3
    [6.1144][6.0:18]()
    use anyhow::bail;
    [6.1144]
    [6.1144]
    use super::{make_changelist, parse_changelist};
    use anyhow::{anyhow, bail};
  • replacement in pijul/src/commands/unrecord.rs at line 7
    [6.59][6.59:110]()
    use libpijul::{Base32, MutTxnT, MutTxnTExt, TxnT};
    [6.59]
    [6.1235]
    use libpijul::{Base32, MutTxnT, MutTxnTExt, TxnT, TxnTExt};
  • replacement in pijul/src/commands/unrecord.rs at line 20
    [6.95955][6.111:204]()
    /// Undo the change in the working copy (preserving unrecorded changes if there are any)
    [6.95955]
    [6.204]
    /// Also undo the changes in the working copy (preserving unrecorded changes if there are any)
  • replacement in pijul/src/commands/unrecord.rs at line 23
    [6.249][6.375:444](),[6.95955][6.375:444]()
    /// Identifier of the change (unambiguous prefixes are accepted)
    [6.249]
    [6.444]
    /// Show N changes in a text editor if no <change-id>s were given.
    /// Defaults to the value
    /// of `unrecord_changes` in your global configuration.
    #[clap(long = "show-changes", value_name = "N", conflicts_with("change-id"))]
    show_changes: Option<usize>,
    /// The hash of a change (unambiguous prefixes are accepted)
  • replacement in pijul/src/commands/unrecord.rs at line 46
    [6.486][6.314:356](),[6.314][6.314:356]()
    let mut changes = Vec::new();
    [6.486]
    [6.356]
    let hashes = if self.change_id.is_empty() {
    // No change ids were given, present a list for choosing
    // The number can be set in the global config or passed as a command-line option
    let number_of_changes = if let Some(n) = self.show_changes {
    n
    } else {
    let cfg = crate::config::Global::load()?;
    cfg.unrecord_changes.ok_or_else(|| {
    anyhow!(
    "Can't determine how many changes to show. \
    Please set the `unrecord_changes` option in \
    your global config or run `pijul unrecord` \
    with the `--show-changes` option."
    )
    })?
    };
    let hashes = txn
    .reverse_log(&channel.borrow(), None)
    .map(|(_, (h, _))| h)
    .take(number_of_changes)
    .collect::<Vec<_>>();
    let o = make_changelist(&repo.changes, &hashes, "unrecord")?;
    parse_changelist(&edit::edit_bytes(&o[..])?)
    .iter()
    .map(|h| h.to_base32())
    .collect::<_>()
    } else {
    self.change_id
    };
  • replacement in pijul/src/commands/unrecord.rs at line 76
    [6.401][6.401:439]()
    for c in self.change_id {
    [6.401]
    [6.439]
    let mut changes = Vec::new();
    for c in hashes {
  • replacement in pijul/src/commands/unrecord.rs at line 82
    [6.1985][6.594:648](),[6.594][6.594:648]()
    changes.push((hash, change_id, n, c))
    [6.1985]
    [6.648]
    changes.push((hash, change_id, n, c));
  • edit in pijul/src/commands/pushpull.rs at line 5
    [6.1696]
    [6.1696]
    use super::{make_changelist, parse_changelist};
  • edit in pijul/src/commands/pushpull.rs at line 422
    [6.121148][6.121148:121285](),[6.121285][6.2611:2644](),[6.2644][5.294:310](),[5.310][6.121328:121366](),[6.2644][6.121328:121366](),[6.121328][6.121328:121366](),[6.121366][6.2645:2671](),[6.2671][6.121402:121455](),[6.121402][6.121402:121455](),[6.121455][5.311:385](),[5.385][6.121531:121602](),[6.81][6.121531:121602](),[6.108][6.121531:121602](),[6.121531][6.121531:121602](),[6.121602][5.386:421](),[5.421][6.121618:121713](),[6.105][6.121618:121713](),[6.121618][6.121618:121713](),[6.121713][4.0:34](),[4.34][6.121751:121839](),[6.121751][6.121751:121839](),[6.121839][6.0:275](),[6.275][6.121839:122345](),[6.121839][6.121839:122345](),[6.122345][6.0:194](),[6.194][6.122345:122374](),[6.122345][6.122345:122374](),[6.122374][6.2672:2753](),[6.2753][6.122475:122537](),[6.122475][6.122475:122537](),[6.122537][6.2754:2825](),[6.2825][6.122618:122682](),[6.122618][6.122618:122682]()
    /// Make the "changelist", i.e. the list of patches, editable in a
    /// text editor.
    fn make_changelist<S: ChangeStore>(
    changes: &S,
    pullable: &[libpijul::Hash],
    verb: &str,
    ) -> Result<Vec<u8>, anyhow::Error> {
    use libpijul::Base32;
    let mut v = Vec::new();
    writeln!(
    v,
    "# Please select the changes to {}. The lines that contain just a
    # valid hash, and no other character (except possibly a newline), will
    # be {}ed.\n",
    verb, verb,
    )
    .unwrap();
    let mut first_p = true;
    for p in pullable {
    if !first_p {
    writeln!(v).unwrap();
    }
    first_p = false;
    writeln!(v, "{}\n", p.to_base32()).unwrap();
    let deps = changes.get_dependencies(&p)?;
    if !deps.is_empty() {
    write!(v, " Dependencies:").unwrap();
    for d in deps {
    write!(v, " {}", d.to_base32()).unwrap();
    }
    writeln!(v).unwrap();
    }
    let change = changes.get_header(&p)?;
    write!(v, " Author: [").unwrap();
    let mut first = true;
    for a in change.authors.iter() {
    if !first {
    write!(v, ", ").unwrap();
    }
    first = false;
    write!(v, "{}", a).unwrap();
    }
    writeln!(v, "]").unwrap();
    writeln!(v, " Date: {}\n", change.timestamp).unwrap();
    for l in change.message.lines() {
    writeln!(v, " {}", l).unwrap();
    }
    if let Some(desc) = change.description {
    writeln!(v).unwrap();
    for l in desc.lines() {
    writeln!(v, " {}", l).unwrap();
    }
    }
    }
    Ok(v)
    }
    fn parse_changelist(o: &[u8]) -> Vec<libpijul::Hash> {
    use libpijul::Base32;
    if let Ok(o) = std::str::from_utf8(o) {
    o.lines()
    .filter_map(|l| libpijul::Hash::from_base32(l.as_bytes()))
    .collect()
    } else {
    Vec::new()
    }
    }
  • edit in pijul/src/commands/mod.rs at line 106
    [3.14]
    /// Make a "changelist", i.e. a list of patches that can be edited in
    /// a text editor.
    fn make_changelist<S: libpijul::changestore::ChangeStore>(
    changes: &S,
    pullable: &[libpijul::Hash],
    verb: &str,
    ) -> Result<Vec<u8>, anyhow::Error> {
    use libpijul::Base32;
    use std::io::Write;
    let mut v = Vec::new();
    // TODO: This message should probably be customizable
    writeln!(
    v,
    "# Please select the changes to {}. The lines that contain just a
    # valid hash, and no other character (except possibly a newline), will
    # be {}ed.\n",
    verb, verb,
    )
    .unwrap();
    let mut first_p = true;
    for p in pullable {
    if !first_p {
    writeln!(v, "").unwrap();
    }
    first_p = false;
    writeln!(v, "{}\n", p.to_base32()).unwrap();
    let deps = changes.get_dependencies(&p)?;
    if !deps.is_empty() {
    write!(v, " Dependencies:").unwrap();
    for d in deps {
    write!(v, " {}", d.to_base32()).unwrap();
    }
    writeln!(v).unwrap();
    }
    let change = changes.get_header(&p)?;
    write!(v, " Author: [").unwrap();
    let mut first = true;
    for a in change.authors.iter() {
    if !first {
    write!(v, ", ").unwrap();
    }
    first = false;
    write!(v, "{}", a).unwrap();
    }
    writeln!(v, "]").unwrap();
    writeln!(v, " Date: {}\n", change.timestamp).unwrap();
    for l in change.message.lines() {
    writeln!(v, " {}", l).unwrap();
    }
    if let Some(desc) = change.description {
    writeln!(v).unwrap();
    for l in desc.lines() {
    writeln!(v, " {}", l).unwrap();
    }
    }
    }
    Ok(v)
    }
    /// Parses a list of hashes from a slice of bytes.
    /// Everything that is not a line consisting of a
    /// valid hash and nothing else will be ignored.
    fn parse_changelist(o: &[u8]) -> Vec<libpijul::Hash> {
    use libpijul::Base32;
    if let Ok(o) = std::str::from_utf8(o) {
    o.lines()
    .filter_map(|l| libpijul::Hash::from_base32(l.as_bytes()))
    .collect()
    } else {
    Vec::new()
    }
    }