git: add a jj git clone command to make it easier to get started

With this commit, you can do `jj git clone
https://github.com/martinvonz/jj jj` and such, which seems like a good
step towards making it easier to get started.
This commit is contained in:
Martin von Zweigbergk 2021-01-01 10:59:46 -08:00
parent e14db781b0
commit 77bb8b600b

View File

@ -434,6 +434,12 @@ fn get_app<'a, 'b>() -> App<'a, 'b> {
.default_value("origin"),
),
)
.subcommand(
SubCommand::with_name("clone")
.about("create a new repo backed by a clone of a git repo")
.arg(Arg::with_name("source").index(1).required(true))
.arg(Arg::with_name("destination").index(2).required(true)),
)
.subcommand(
SubCommand::with_name("push")
.about("push a revision to a git remote branch")
@ -1998,6 +2004,47 @@ fn cmd_git_fetch(
Ok(())
}
fn cmd_git_clone(
ui: &mut Ui,
_matches: &ArgMatches,
_git_matches: &ArgMatches,
cmd_matches: &ArgMatches,
) -> Result<(), CommandError> {
let source = cmd_matches.value_of("source").unwrap();
let wc_path_str = cmd_matches.value_of("destination").unwrap();
let wc_path = ui.cwd().join(wc_path_str);
if wc_path.exists() {
assert!(wc_path.is_dir());
} else {
fs::create_dir(&wc_path).unwrap();
}
let repo = ReadonlyRepo::init_internal_git(ui.settings(), wc_path);
writeln!(
ui,
"Fetching into new repo in {:?}",
repo.working_copy_path()
);
let remote_name = "origin";
repo.store()
.git_repo()
.unwrap()
.remote(remote_name, source)
.unwrap();
let mut tx = repo.start_transaction("fetch from git remote into empty repo");
git::fetch(&mut tx, remote_name).map_err(|err| match err {
GitFetchError::NotAGitRepo | GitFetchError::NoSuchRemote => {
panic!("should't happen as we just created the repo and the git remote")
}
GitFetchError::InternalGitError(err) => {
CommandError::UserError(format!("Fetch failed: {:?}", err))
}
})?;
tx.commit();
writeln!(ui, "Done");
Ok(())
}
fn cmd_git_push(
ui: &mut Ui,
matches: &ArgMatches,
@ -2053,6 +2100,8 @@ fn cmd_git(
) -> Result<(), CommandError> {
if let Some(command_matches) = sub_matches.subcommand_matches("fetch") {
cmd_git_fetch(ui, matches, sub_matches, command_matches)?;
} else if let Some(command_matches) = sub_matches.subcommand_matches("clone") {
cmd_git_clone(ui, matches, sub_matches, command_matches)?;
} else if let Some(command_matches) = sub_matches.subcommand_matches("push") {
cmd_git_push(ui, matches, sub_matches, command_matches)?;
} else if let Some(command_matches) = sub_matches.subcommand_matches("refresh") {