| /* |
| * libgit2 "rev-list" example - shows how to transform a rev-spec into a list |
| * of commit ids |
| * |
| * Written by the libgit2 contributors |
| * |
| * To the extent possible under law, the author(s) have dedicated all copyright |
| * and related and neighboring rights to this software to the public domain |
| * worldwide. This software is distributed without any warranty. |
| * |
| * You should have received a copy of the CC0 Public Domain Dedication along |
| * with this software. If not, see |
| * <http://creativecommons.org/publicdomain/zero/1.0/>. |
| */ |
| |
| #![deny(warnings)] |
| |
| use docopt::Docopt; |
| use git2::{Error, Oid, Repository, Revwalk}; |
| use serde_derive::Deserialize; |
| |
| #[derive(Deserialize)] |
| struct Args { |
| arg_spec: Vec<String>, |
| flag_topo_order: bool, |
| flag_date_order: bool, |
| flag_reverse: bool, |
| flag_not: Vec<String>, |
| } |
| |
| fn run(args: &Args) -> Result<(), git2::Error> { |
| let repo = Repository::open(".")?; |
| let mut revwalk = repo.revwalk()?; |
| |
| let base = if args.flag_reverse { |
| git2::Sort::REVERSE |
| } else { |
| git2::Sort::NONE |
| }; |
| revwalk.set_sorting( |
| base | if args.flag_topo_order { |
| git2::Sort::TOPOLOGICAL |
| } else if args.flag_date_order { |
| git2::Sort::TIME |
| } else { |
| git2::Sort::NONE |
| }, |
| )?; |
| |
| let specs = args |
| .flag_not |
| .iter() |
| .map(|s| (s, true)) |
| .chain(args.arg_spec.iter().map(|s| (s, false))) |
| .map(|(spec, hide)| { |
| if spec.starts_with('^') { |
| (&spec[1..], !hide) |
| } else { |
| (&spec[..], hide) |
| } |
| }); |
| for (spec, hide) in specs { |
| let id = if spec.contains("..") { |
| let revspec = repo.revparse(spec)?; |
| if revspec.mode().contains(git2::RevparseMode::MERGE_BASE) { |
| return Err(Error::from_str("merge bases not implemented")); |
| } |
| push(&mut revwalk, revspec.from().unwrap().id(), !hide)?; |
| revspec.to().unwrap().id() |
| } else { |
| repo.revparse_single(spec)?.id() |
| }; |
| push(&mut revwalk, id, hide)?; |
| } |
| |
| for id in revwalk { |
| let id = id?; |
| println!("{}", id); |
| } |
| Ok(()) |
| } |
| |
| fn push(revwalk: &mut Revwalk, id: Oid, hide: bool) -> Result<(), Error> { |
| if hide { |
| revwalk.hide(id) |
| } else { |
| revwalk.push(id) |
| } |
| } |
| |
| fn main() { |
| const USAGE: &str = " |
| usage: rev-list [options] [--] <spec>... |
| |
| Options: |
| --topo-order sort commits in topological order |
| --date-order sort commits in date order |
| --reverse sort commits in reverse |
| --not <spec> don't show <spec> |
| -h, --help show this message |
| "; |
| |
| let args = Docopt::new(USAGE) |
| .and_then(|d| d.deserialize()) |
| .unwrap_or_else(|e| e.exit()); |
| match run(&args) { |
| Ok(()) => {} |
| Err(e) => println!("error: {}", e), |
| } |
| } |