sapling/eden/mononoke/cmds/admin/pushrebase.rs
Stanislau Hlebik 8cd6278de9 mononoke: implement ensure_ancestors_of option for bookmarks
Summary:
This option would let us tell that a given bookmark (or bookmarks if they are
specified via a regex) is allowed to move only if it stays an ancestor of a
given bookmark.
Note - this is a sev followup, and we intend to use it for */stable bookmarks
(e.g. fbcode/stable, fbsource/stable etc). They are always intended to be an
ancestor of master

Reviewed By: krallin

Differential Revision: D29878144

fbshipit-source-id: a5ce08a09328e6a19af4d233c1a273a5e620b9ce
2021-07-27 12:47:22 -07:00

107 lines
2.9 KiB
Rust

/*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This software may be used and distributed according to the terms of the
* GNU General Public License version 2.
*/
use anyhow::{anyhow, Error};
use blobrepo::BlobRepo;
use blobstore::Loadable;
use bookmarks::BookmarkName;
use clap::{App, Arg, ArgMatches, SubCommand};
use fbinit::FacebookInit;
use futures::{compat::Future01CompatExt, TryFutureExt};
use cmdlib::{
args::{self, MononokeMatches},
helpers,
};
use context::CoreContext;
use maplit::hashset;
use metaconfig_types::BookmarkAttrs;
use pushrebase::do_pushrebase_bonsai;
use slog::Logger;
use crate::error::SubcommandError;
pub const ARG_BOOKMARK: &str = "bookmark";
pub const ARG_CSID: &str = "csid";
pub const PUSHREBASE: &str = "pushrebase";
pub fn build_subcommand<'a, 'b>() -> App<'a, 'b> {
SubCommand::with_name(PUSHREBASE)
.about("pushrebases a commit to a bookmark")
.arg(
Arg::with_name(ARG_CSID)
.long(ARG_CSID)
.takes_value(true)
.required(true)
.help("{hg|bonsai} changeset id or bookmark name"),
)
.arg(
Arg::with_name(ARG_BOOKMARK)
.long(ARG_BOOKMARK)
.takes_value(true)
.required(true)
.help("name of the bookmark to pushrebase to"),
)
}
pub async fn subcommand_pushrebase<'a>(
fb: FacebookInit,
logger: Logger,
matches: &'a MononokeMatches<'_>,
sub_matches: &'a ArgMatches<'_>,
) -> Result<(), SubcommandError> {
let ctx = CoreContext::new_with_logger(fb, logger.clone());
let repo: BlobRepo = args::open_repo(fb, &logger, &matches).await?;
let cs_id = sub_matches
.value_of(ARG_CSID)
.ok_or_else(|| anyhow!("{} arg is not specified", ARG_CSID))?;
let cs_id = helpers::csid_resolve(ctx.clone(), repo.clone(), cs_id)
.compat()
.await?;
let bookmark = sub_matches
.value_of(ARG_BOOKMARK)
.ok_or_else(|| anyhow!("{} arg is not specified", ARG_BOOKMARK))?;
let config_store = matches.config_store();
let (_, repo_config) = args::get_config(config_store, matches)?;
let bookmark = BookmarkName::new(bookmark)?;
let pushrebase_flags = repo_config.pushrebase.flags;
let bookmark_attrs = BookmarkAttrs::new(fb, repo_config.bookmarks.clone()).await?;
let pushrebase_hooks = bookmarks_movement::get_pushrebase_hooks(
&ctx,
&repo,
&bookmark,
&bookmark_attrs,
&repo_config.pushrebase,
)
.map_err(Error::from)?;
let bcs = cs_id
.load(&ctx, &repo.get_blobstore())
.map_err(Error::from)
.await?;
let pushrebase_res = do_pushrebase_bonsai(
&ctx,
&repo,
&pushrebase_flags,
&bookmark,
&hashset![bcs],
None,
&pushrebase_hooks,
)
.map_err(Error::from)
.await?;
println!("{}", pushrebase_res.head);
Ok(())
}