802 lines · 24.0 KB · Rust
RawDownload
// Copyright 2022 The Jujutsu Authors//// Licensed under the Apache License, Version 2.0 (the "License");// you may not use this file except in compliance with the License.// You may obtain a copy of the License at//// https://www.apache.org/licenses/LICENSE-2.0//// Unless required by applicable law or agreed to in writing, software// distributed under the License is distributed on an "AS IS" BASIS,// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.// See the License for the specific language governing permissions and// limitations under the License. use std::fs;use std::io::Write as _;use std::path::Path;use std::path::PathBuf; use indoc::indoc;use testutils::git; use crate::common::TestEnvironment; fn read_git_config(repo_path: &Path) -> String {    let git_config = fs::read_to_string(repo_path.join(".jj/repo/store/git/config"))        .or_else(|_| fs::read_to_string(repo_path.join(".git/config")))        .unwrap();    git_config        .split_inclusive('\n')        .filter(|line| {            // Filter out non‐portable values.            [                "\tfilemode =",                "\tsymlinks =",                "\tignorecase =",                "\tprecomposeunicode =",            ]            .iter()            .all(|prefix| !line.to_ascii_lowercase().starts_with(prefix))        })        .collect()} #[test]fn test_git_remotes() {    let test_env = TestEnvironment::default();     test_env.run_jj_in(".", ["git", "init", "repo"]).success();    let work_dir = test_env.work_dir("repo");     let output = work_dir.run_jj(["git", "remote", "list"]);    insta::assert_snapshot!(output, @"");    let output = work_dir.run_jj(["git", "remote", "add", "foo", "http://example.com/repo/foo"]);    insta::assert_snapshot!(output, @"");    let output = work_dir.run_jj(["git", "remote", "add", "bar", "http://example.com/repo/bar"]);    insta::assert_snapshot!(output, @"");    let output = work_dir.run_jj([        "git",        "remote",        "add",        "baz",        "http://example.com/repo/baz",        "--push-url",        "git@example.com:repo/baz",    ]);    insta::assert_snapshot!(output, @"");    let output = work_dir.run_jj(["git", "remote", "list"]);    insta::assert_snapshot!(output, @"    bar http://example.com/repo/bar    baz http://example.com/repo/baz (push: git@example.com:repo/baz)    foo http://example.com/repo/foo    [EOF]    ");    let output = work_dir.run_jj(["git", "remote", "remove", "foo"]);    insta::assert_snapshot!(output, @"");    let output = work_dir.run_jj(["git", "remote", "list"]);    insta::assert_snapshot!(output, @"    bar http://example.com/repo/bar    baz http://example.com/repo/baz (push: git@example.com:repo/baz)    [EOF]    ");    let output = work_dir.run_jj(["git", "remote", "remove", "nonexistent"]);    insta::assert_snapshot!(output, @"    ------- stderr -------    Error: No git remote named 'nonexistent'    [EOF]    [exit status: 1]    ");    insta::assert_snapshot!(read_git_config(work_dir.root()), @r#"    [core]    	repositoryformatversion = 0    	bare = true    	logallrefupdates = false    [remote "bar"]    	url = http://example.com/repo/bar    	fetch = +refs/heads/*:refs/remotes/bar/*    [remote "baz"]    	url = http://example.com/repo/baz    	pushurl = git@example.com:repo/baz    	fetch = +refs/heads/*:refs/remotes/baz/*    "#);     // named remote that cannot be parsed    work_dir.write_file(        ".jj/repo/store/git/config",        indoc! {r#"            [remote "foo"]                url = invalid\        "#},    );    let output = work_dir.run_jj(["git", "remote", "list"]);    insta::assert_snapshot!(output, @r#"    ------- stderr -------    Error: Failed to load configured remote foo    Caused by:    1: The fetch url under `remote.foo` was invalid    2: The url at "remote.<name>.url=" could not be parsed    3: local path "" does not specify a path to a repository    [EOF]    [exit status: 1]    "#);} #[test]fn test_git_remote_add() {    let test_env = TestEnvironment::default();     test_env.run_jj_in(".", ["git", "init", "repo"]).success();    let work_dir = test_env.work_dir("repo");    work_dir        .run_jj(["git", "remote", "add", "foo", "http://example.com/repo/foo"])        .success();    let output = work_dir.run_jj([        "git",        "remote",        "add",        "foo",        "http://example.com/repo/foo2",    ]);    insta::assert_snapshot!(output, @"    ------- stderr -------    Error: Git remote named 'foo' already exists    [EOF]    [exit status: 1]    ");    let output = work_dir.run_jj(["git", "remote", "add", "git", "http://example.com/repo/git"]);    insta::assert_snapshot!(output, @"    ------- stderr -------    Error: Git remote named 'git' is reserved for local Git repository    [EOF]    [exit status: 1]    ");    let output = work_dir.run_jj(["git", "remote", "list"]);    insta::assert_snapshot!(output, @"    foo http://example.com/repo/foo    [EOF]    ");} #[test]fn test_git_remote_with_fetch_tags() {    let test_env = TestEnvironment::default();     test_env.run_jj_in(".", ["git", "init", "repo"]).success();    let work_dir = test_env.work_dir("repo");     let output = work_dir.run_jj(["git", "remote", "add", "foo", "http://example.com/repo"]);    insta::assert_snapshot!(output, @"");     let output = work_dir.run_jj([        "git",        "remote",        "add",        "foo-included",        "http://example.com/repo",        "--fetch-tags",        "included",    ]);    insta::assert_snapshot!(output, @"");     let output = work_dir.run_jj([        "git",        "remote",        "add",        "foo-all",        "http://example.com/repo",        "--fetch-tags",        "all",    ]);    insta::assert_snapshot!(output, @"");     let output = work_dir.run_jj([        "git",        "remote",        "add",        "foo-none",        "http://example.com/repo",        "--fetch-tags",        "none",    ]);    insta::assert_snapshot!(output, @"");     insta::assert_snapshot!(read_git_config(work_dir.root()), @r#"    [core]    	repositoryformatversion = 0    	bare = true    	logallrefupdates = false    [remote "foo"]    	url = http://example.com/repo    	fetch = +refs/heads/*:refs/remotes/foo/*    [remote "foo-included"]    	url = http://example.com/repo    	fetch = +refs/heads/*:refs/remotes/foo-included/*    [remote "foo-all"]    	url = http://example.com/repo    	tagOpt = --tags    	fetch = +refs/heads/*:refs/remotes/foo-all/*    [remote "foo-none"]    	url = http://example.com/repo    	tagOpt = --no-tags    	fetch = +refs/heads/*:refs/remotes/foo-none/*    "#);} #[test]fn test_git_remote_set_url() {    let test_env = TestEnvironment::default();     test_env.run_jj_in(".", ["git", "init", "repo"]).success();    let work_dir = test_env.work_dir("repo");    work_dir        .run_jj(["git", "remote", "add", "foo", "http://example.com/repo/foo"])        .success();    let output = work_dir.run_jj([        "git",        "remote",        "set-url",        "bar",        "http://example.com/repo/bar",    ]);    insta::assert_snapshot!(output, @"    ------- stderr -------    Error: No git remote named 'bar'    [EOF]    [exit status: 1]    ");    let output = work_dir.run_jj([        "git",        "remote",        "set-url",        "git",        "http://example.com/repo/git",    ]);    insta::assert_snapshot!(output, @"    ------- stderr -------    Error: Git remote named 'git' is reserved for local Git repository    [EOF]    [exit status: 1]    ");    let output = work_dir.run_jj([        "git",        "remote",        "set-url",        "foo",        "http://example.com/repo/bar",    ]);    insta::assert_snapshot!(output, @"");    let output = work_dir.run_jj(["git", "remote", "list"]);    insta::assert_snapshot!(output, @"    foo http://example.com/repo/bar    [EOF]    ");    insta::assert_snapshot!(read_git_config(work_dir.root()), @r#"    [core]    	repositoryformatversion = 0    	bare = true    	logallrefupdates = false    [remote "foo"]    	url = http://example.com/repo/bar    	fetch = +refs/heads/*:refs/remotes/foo/*    "#);    // explicitly set the push url to the same value as fetch works.    let output = work_dir.run_jj([        "git",        "remote",        "set-url",        "foo",        "--push",        "https://example.com/repo/bar",    ]);    insta::assert_snapshot!(output, @"");    insta::assert_snapshot!(read_git_config(work_dir.root()), @r#"    [core]    	repositoryformatversion = 0    	bare = true    	logallrefupdates = false    [remote "foo"]    	url = http://example.com/repo/bar    	pushurl = https://example.com/repo/bar    	fetch = +refs/heads/*:refs/remotes/foo/*    "#);    let output = work_dir.run_jj([        "git",        "remote",        "set-url",        "foo",        "--push",        "git@example.com:repo/bar",    ]);    insta::assert_snapshot!(output, @"");    insta::assert_snapshot!(read_git_config(work_dir.root()), @r#"    [core]    	repositoryformatversion = 0    	bare = true    	logallrefupdates = false    [remote "foo"]    	url = http://example.com/repo/bar    	pushurl = git@example.com:repo/bar    	fetch = +refs/heads/*:refs/remotes/foo/*    "#);    let output = work_dir.run_jj([        "git",        "remote",        "set-url",        "foo",        "--fetch",        "http://example.com/repo/bar2",    ]);    insta::assert_snapshot!(output, @"");    insta::assert_snapshot!(read_git_config(work_dir.root()), @r#"    [core]    	repositoryformatversion = 0    	bare = true    	logallrefupdates = false    [remote "foo"]    	url = http://example.com/repo/bar2    	pushurl = git@example.com:repo/bar    	fetch = +refs/heads/*:refs/remotes/foo/*    "#);    let output = work_dir.run_jj([        "git",        "remote",        "set-url",        "foo",        "http://example.com/repo/bar",    ]);    insta::assert_snapshot!(output, @"");    insta::assert_snapshot!(read_git_config(work_dir.root()), @r#"    [core]    	repositoryformatversion = 0    	bare = true    	logallrefupdates = false    [remote "foo"]    	url = http://example.com/repo/bar    	pushurl = git@example.com:repo/bar    	fetch = +refs/heads/*:refs/remotes/foo/*    "#);    let output = work_dir.run_jj([        "git",        "remote",        "set-url",        "foo",        "https://example.com/repo/baz",        "--fetch",        "https://example.com/repo/bar2",    ]);    insta::assert_snapshot!(output, @"    ------- stderr -------    error: the argument '[URL]' cannot be used with '--fetch <FETCH>'     Usage: jj git remote set-url <REMOTE> <URL>     For more information, try '--help'.    [EOF]    [exit status: 2]    ");    let output = work_dir.run_jj([        "git",        "remote",        "set-url",        "foo",        "https://example.com/repo/baz",        "--push",        "git@example.com:/repo/baz",    ]);    insta::assert_snapshot!(output, @"");    insta::assert_snapshot!(read_git_config(work_dir.root()), @r#"    [core]    	repositoryformatversion = 0    	bare = true    	logallrefupdates = false    [remote "foo"]    	url = https://example.com/repo/baz    	pushurl = git@example.com:/repo/baz    	fetch = +refs/heads/*:refs/remotes/foo/*    "#);    let output = work_dir.run_jj([        "git",        "remote",        "set-url",        "foo",        "--fetch",        "https://example.com/repo/bar",        "--push",        "git@example.com:/repo/bar",    ]);    insta::assert_snapshot!(output, @"");    insta::assert_snapshot!(read_git_config(work_dir.root()), @r#"    [core]    	repositoryformatversion = 0    	bare = true    	logallrefupdates = false    [remote "foo"]    	url = https://example.com/repo/bar    	pushurl = git@example.com:/repo/bar    	fetch = +refs/heads/*:refs/remotes/foo/*    "#);} #[test]fn test_git_remote_relative_path() {    let test_env = TestEnvironment::default();    test_env.run_jj_in(".", ["git", "init", "repo"]).success();    let work_dir = test_env.work_dir("repo");     // Relative path using OS-native separator    let path = PathBuf::from_iter(["..", "native", "sep"]);    work_dir        .run_jj(["git", "remote", "add", "foo", path.to_str().unwrap()])        .success();    let output = work_dir.run_jj(["git", "remote", "list"]);    insta::assert_snapshot!(output, @"    foo $TEST_ENV/native/sep    [EOF]    ");     // Relative path using UNIX separator    test_env        .run_jj_in(            ".",            ["-Rrepo", "git", "remote", "set-url", "foo", "unix/sep"],        )        .success();    let output = work_dir.run_jj(["git", "remote", "list"]);    insta::assert_snapshot!(output, @"    foo $TEST_ENV/unix/sep    [EOF]    ");} #[test]fn test_git_remote_rename() {    let test_env = TestEnvironment::default();     test_env.run_jj_in(".", ["git", "init", "repo"]).success();    let work_dir = test_env.work_dir("repo");    work_dir        .run_jj(["git", "remote", "add", "foo", "http://example.com/repo/foo"])        .success();    work_dir        .run_jj(["git", "remote", "add", "baz", "http://example.com/repo/baz"])        .success();    let output = work_dir.run_jj(["git", "remote", "rename", "bar", "foo"]);    insta::assert_snapshot!(output, @"    ------- stderr -------    Error: No git remote named 'bar'    [EOF]    [exit status: 1]    ");    let output = work_dir.run_jj(["git", "remote", "rename", "foo", "baz"]);    insta::assert_snapshot!(output, @"    ------- stderr -------    Error: Git remote named 'baz' already exists    [EOF]    [exit status: 1]    ");    let output = work_dir.run_jj(["git", "remote", "rename", "foo", "git"]);    insta::assert_snapshot!(output, @"    ------- stderr -------    Error: Git remote named 'git' is reserved for local Git repository    [EOF]    [exit status: 1]    ");    let output = work_dir.run_jj(["git", "remote", "rename", "foo", "bar"]);    insta::assert_snapshot!(output, @"");    let output = work_dir.run_jj(["git", "remote", "list"]);    insta::assert_snapshot!(output, @"    bar http://example.com/repo/foo    baz http://example.com/repo/baz    [EOF]    ");    insta::assert_snapshot!(read_git_config(work_dir.root()), @r#"    [core]    	repositoryformatversion = 0    	bare = true    	logallrefupdates = false    [remote "baz"]    	url = http://example.com/repo/baz    	fetch = +refs/heads/*:refs/remotes/baz/*

Lines 1–500 of 802.