From d8899e1ae7084a6150a8bef39370e51925d526fa Mon Sep 17 00:00:00 2001 From: Benjamin Tan Date: Mon, 4 Mar 2024 18:52:48 +0800 Subject: [PATCH] git clone: add revset alias for `trunk()` --- CHANGELOG.md | 3 +++ cli/src/commands/git/clone.rs | 13 +++++++++++ cli/tests/test_git_clone.rs | 44 ++++++++++++++++++++++++++++++++++- docs/revsets.md | 4 ++++ 4 files changed, 63 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6bf24ffff..a93fd4ff0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,6 +20,9 @@ to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). individually instead of being passed a directory by setting `merge-tools.$TOOL.diff-invocation-mode="file-by-file"` in config.toml. +* `jj git clone` adds the default branch of the remote as repository + settings for `revset-aliases."trunk()"`.` + ### Fixed bugs ## [0.19.0] - 2024-07-03 diff --git a/cli/src/commands/git/clone.rs b/cli/src/commands/git/clone.rs index edef604b5..1a072f7f2 100644 --- a/cli/src/commands/git/clone.rs +++ b/cli/src/commands/git/clone.rs @@ -24,6 +24,7 @@ use jj_lib::workspace::Workspace; use crate::cli_util::{CommandHelper, WorkspaceCommandHelper}; use crate::command_error::{user_error, user_error_with_message, CommandError}; use crate::commands::git::{map_git_error, maybe_add_gitignore}; +use crate::config::{write_config_value_to_file, ConfigNamePathBuf}; use crate::git_util::{get_git_repo, print_git_import_stats, with_remote_git_callbacks}; use crate::ui::Ui; @@ -142,6 +143,18 @@ pub fn cmd_git_clone( let (mut workspace_command, stats) = clone_result?; if let Some(default_branch) = &stats.default_branch { + // Set repository level `trunk()` alias to the default remote branch. + let config_path = workspace_command.repo().repo_path().join("config.toml"); + write_config_value_to_file( + &ConfigNamePathBuf::from_iter(["revset-aliases", "trunk()"]), + &format!("{default_branch}@{remote_name}"), + &config_path, + )?; + writeln!( + ui.status(), + "Setting the revset alias \"trunk()\" to \"{default_branch}@{remote_name}\"" + )?; + let default_branch_remote_ref = workspace_command .repo() .view() diff --git a/cli/tests/test_git_clone.rs b/cli/tests/test_git_clone.rs index 40f7d6338..5fe552a43 100644 --- a/cli/tests/test_git_clone.rs +++ b/cli/tests/test_git_clone.rs @@ -64,6 +64,7 @@ fn test_git_clone() { insta::assert_snapshot!(stderr, @r###" Fetching into new repo in "$TEST_ENV/clone" branch: main@origin [new] tracked + Setting the revset alias "trunk()" to "main@origin" Working copy now at: uuqppmxq 1f0b881a (empty) (no description set) Parent commit : mzyxwzks 9f01a0e0 main | message Added 1 files, modified 0 files, removed 0 files @@ -175,6 +176,7 @@ fn test_git_clone_colocate() { insta::assert_snapshot!(stderr, @r###" Fetching into new repo in "$TEST_ENV/clone" branch: main@origin [new] tracked + Setting the revset alias "trunk()" to "main@origin" Working copy now at: uuqppmxq 1f0b881a (empty) (no description set) Parent commit : mzyxwzks 9f01a0e0 main | message Added 1 files, modified 0 files, removed 0 files @@ -332,6 +334,7 @@ fn test_git_clone_remote_default_branch() { Fetching into new repo in "$TEST_ENV/clone1" branch: feature1@origin [new] tracked branch: main@origin [new] tracked + Setting the revset alias "trunk()" to "main@origin" Working copy now at: sqpuoqvx cad212e1 (empty) (no description set) Parent commit : mzyxwzks 9f01a0e0 feature1 main | message Added 1 files, modified 0 files, removed 0 files @@ -344,6 +347,15 @@ fn test_git_clone_remote_default_branch() { @origin: mzyxwzks 9f01a0e0 message "###); + // "trunk()" alias should be set to default branch "main" + let stdout = test_env.jj_cmd_success( + &test_env.env_root().join("clone1"), + &["config", "list", "--repo", "revset-aliases.'trunk()'"], + ); + insta::assert_snapshot!(stdout, @r###" + revset-aliases.'trunk()' = "main@origin" + "###); + // Only the default branch will be imported if auto-local-branch is off test_env.add_config("git.auto-local-branch = false"); let (_stdout, stderr) = @@ -352,7 +364,8 @@ fn test_git_clone_remote_default_branch() { Fetching into new repo in "$TEST_ENV/clone2" branch: feature1@origin [new] untracked branch: main@origin [new] untracked - Working copy now at: pmmvwywv fa729b1e (empty) (no description set) + Setting the revset alias "trunk()" to "main@origin" + Working copy now at: rzvqmyuk cc8a5041 (empty) (no description set) Parent commit : mzyxwzks 9f01a0e0 feature1@origin main | message Added 1 files, modified 0 files, removed 0 files "###); @@ -362,6 +375,35 @@ fn test_git_clone_remote_default_branch() { main: mzyxwzks 9f01a0e0 message @origin: mzyxwzks 9f01a0e0 message "###); + + // Change the default branch in remote + git_repo.set_head("refs/heads/feature1").unwrap(); + let (_stdout, stderr) = + test_env.jj_cmd_ok(test_env.env_root(), &["git", "clone", "source", "clone3"]); + insta::assert_snapshot!(stderr, @r###" + Fetching into new repo in "$TEST_ENV/clone3" + branch: feature1@origin [new] untracked + branch: main@origin [new] untracked + Setting the revset alias "trunk()" to "feature1@origin" + Working copy now at: nppvrztz b8a8a17b (empty) (no description set) + Parent commit : mzyxwzks 9f01a0e0 feature1 main@origin | message + Added 1 files, modified 0 files, removed 0 files + "###); + insta::assert_snapshot!( + get_branch_output(&test_env, &test_env.env_root().join("clone2")), @r###" + feature1@origin: mzyxwzks 9f01a0e0 message + main: mzyxwzks 9f01a0e0 message + @origin: mzyxwzks 9f01a0e0 message + "###); + + // "trunk()" alias should be set to new default branch "feature1" + let stdout = test_env.jj_cmd_success( + &test_env.env_root().join("clone3"), + &["config", "list", "--repo", "revset-aliases.'trunk()'"], + ); + insta::assert_snapshot!(stdout, @r###" + revset-aliases.'trunk()' = "feature1@origin" + "###); } fn get_branch_output(test_env: &TestEnvironment, repo_path: &Path) -> String { diff --git a/docs/revsets.md b/docs/revsets.md index b7676ec56..7d4f58fbc 100644 --- a/docs/revsets.md +++ b/docs/revsets.md @@ -362,6 +362,10 @@ for a comprehensive list. tried. If more than one potential trunk commit exists, the newest one is chosen. If none of the branches exist, the revset evaluates to `root()`. + When working with an existing Git repository (via `jj git clone`), + `trunk()` will be overridden at the repository level to the default branch of + the remote. + You can [override](./config.md) this as appropriate. If you do, make sure it always resolves to exactly one commit. For example: