just playing with tangled
1// Copyright 2020-2023 The Jujutsu Authors
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// https://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15mod clone;
16mod export;
17mod fetch;
18mod import;
19mod init;
20mod push;
21mod remote;
22mod root;
23
24use std::path::Path;
25
26use clap::Subcommand;
27use jj_lib::config::ConfigFile;
28use jj_lib::config::ConfigSource;
29use jj_lib::git;
30use jj_lib::git::UnexpectedGitBackendError;
31use jj_lib::ref_name::RemoteNameBuf;
32use jj_lib::ref_name::RemoteRefSymbol;
33use jj_lib::store::Store;
34
35use self::clone::cmd_git_clone;
36use self::clone::GitCloneArgs;
37use self::export::cmd_git_export;
38use self::export::GitExportArgs;
39use self::fetch::cmd_git_fetch;
40use self::fetch::GitFetchArgs;
41use self::import::cmd_git_import;
42use self::import::GitImportArgs;
43use self::init::cmd_git_init;
44use self::init::GitInitArgs;
45use self::push::cmd_git_push;
46use self::push::GitPushArgs;
47use self::remote::cmd_git_remote;
48use self::remote::RemoteCommand;
49use self::root::cmd_git_root;
50use self::root::GitRootArgs;
51use crate::cli_util::CommandHelper;
52use crate::cli_util::WorkspaceCommandHelper;
53use crate::command_error::user_error_with_message;
54use crate::command_error::CommandError;
55use crate::ui::Ui;
56
57/// Commands for working with Git remotes and the underlying Git repo
58///
59/// See this [comparison], including a [table of commands].
60///
61/// [comparison]:
62/// https://jj-vcs.github.io/jj/latest/git-comparison/.
63///
64/// [table of commands]:
65/// https://jj-vcs.github.io/jj/latest/git-command-table
66#[derive(Subcommand, Clone, Debug)]
67pub enum GitCommand {
68 Clone(GitCloneArgs),
69 Export(GitExportArgs),
70 Fetch(GitFetchArgs),
71 Import(GitImportArgs),
72 Init(GitInitArgs),
73 Push(GitPushArgs),
74 #[command(subcommand)]
75 Remote(RemoteCommand),
76 Root(GitRootArgs),
77}
78
79pub fn cmd_git(
80 ui: &mut Ui,
81 command: &CommandHelper,
82 subcommand: &GitCommand,
83) -> Result<(), CommandError> {
84 match subcommand {
85 GitCommand::Clone(args) => cmd_git_clone(ui, command, args),
86 GitCommand::Export(args) => cmd_git_export(ui, command, args),
87 GitCommand::Fetch(args) => cmd_git_fetch(ui, command, args),
88 GitCommand::Import(args) => cmd_git_import(ui, command, args),
89 GitCommand::Init(args) => cmd_git_init(ui, command, args),
90 GitCommand::Push(args) => cmd_git_push(ui, command, args),
91 GitCommand::Remote(args) => cmd_git_remote(ui, command, args),
92 GitCommand::Root(args) => cmd_git_root(ui, command, args),
93 }
94}
95
96pub fn maybe_add_gitignore(workspace_command: &WorkspaceCommandHelper) -> Result<(), CommandError> {
97 if workspace_command.working_copy_shared_with_git() {
98 std::fs::write(
99 workspace_command
100 .workspace_root()
101 .join(".jj")
102 .join(".gitignore"),
103 "/*\n",
104 )
105 .map_err(|e| user_error_with_message("Failed to write .jj/.gitignore file", e))
106 } else {
107 Ok(())
108 }
109}
110
111fn get_single_remote(store: &Store) -> Result<Option<RemoteNameBuf>, UnexpectedGitBackendError> {
112 let mut names = git::get_all_remote_names(store)?;
113 Ok(match names.len() {
114 1 => names.pop(),
115 _ => None,
116 })
117}
118
119/// Sets repository level `trunk()` alias to the specified remote symbol.
120fn write_repository_level_trunk_alias(
121 ui: &Ui,
122 repo_path: &Path,
123 symbol: RemoteRefSymbol<'_>,
124) -> Result<(), CommandError> {
125 let mut file = ConfigFile::load_or_empty(ConfigSource::Repo, repo_path.join("config.toml"))?;
126 file.set_value(["revset-aliases", "trunk()"], symbol.to_string())
127 .expect("initial repo config shouldn't have invalid values");
128 file.save()?;
129 writeln!(
130 ui.status(),
131 "Setting the revset alias `trunk()` to `{symbol}`",
132 )?;
133 Ok(())
134}