2022-11-26 23:57:50 +00:00
|
|
|
// Copyright 2022 The Jujutsu Authors
|
2022-03-09 23:57:12 +00:00
|
|
|
//
|
|
|
|
// 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.
|
|
|
|
|
2022-05-27 15:54:47 +00:00
|
|
|
use std::path::PathBuf;
|
|
|
|
|
2023-08-13 22:41:53 +00:00
|
|
|
use crate::common::{get_stderr_string, get_stdout_string, TestEnvironment};
|
2022-03-30 17:47:11 +00:00
|
|
|
|
|
|
|
pub mod common;
|
2022-03-09 23:57:12 +00:00
|
|
|
|
2022-05-27 15:54:47 +00:00
|
|
|
fn set_up() -> (TestEnvironment, PathBuf) {
|
2022-03-09 23:57:12 +00:00
|
|
|
let test_env = TestEnvironment::default();
|
2023-10-10 11:59:18 +00:00
|
|
|
test_env.jj_cmd_ok(test_env.env_root(), &["init", "--git", "origin"]);
|
2022-11-04 18:25:11 +00:00
|
|
|
let origin_path = test_env.env_root().join("origin");
|
|
|
|
let origin_git_repo_path = origin_path
|
|
|
|
.join(".jj")
|
|
|
|
.join("repo")
|
|
|
|
.join("store")
|
|
|
|
.join("git");
|
|
|
|
|
2023-10-10 11:59:18 +00:00
|
|
|
test_env.jj_cmd_ok(&origin_path, &["describe", "-m=description 1"]);
|
|
|
|
test_env.jj_cmd_ok(&origin_path, &["branch", "create", "branch1"]);
|
|
|
|
test_env.jj_cmd_ok(&origin_path, &["new", "root()", "-m=description 2"]);
|
|
|
|
test_env.jj_cmd_ok(&origin_path, &["branch", "create", "branch2"]);
|
|
|
|
test_env.jj_cmd_ok(&origin_path, &["git", "export"]);
|
2022-03-09 23:57:12 +00:00
|
|
|
|
2023-10-10 11:59:18 +00:00
|
|
|
test_env.jj_cmd_ok(
|
2022-03-26 21:06:48 +00:00
|
|
|
test_env.env_root(),
|
2022-07-02 02:50:51 +00:00
|
|
|
&[
|
|
|
|
"git",
|
|
|
|
"clone",
|
2023-12-16 10:00:14 +00:00
|
|
|
"--config-toml=git.auto-local-branch=true",
|
2022-11-04 18:25:11 +00:00
|
|
|
origin_git_repo_path.to_str().unwrap(),
|
|
|
|
"local",
|
2022-07-02 02:50:51 +00:00
|
|
|
],
|
2022-03-26 21:06:48 +00:00
|
|
|
);
|
2022-11-04 18:25:11 +00:00
|
|
|
let workspace_root = test_env.env_root().join("local");
|
2022-05-27 15:54:47 +00:00
|
|
|
(test_env, workspace_root)
|
|
|
|
}
|
2022-03-09 23:57:12 +00:00
|
|
|
|
2022-05-27 15:54:47 +00:00
|
|
|
#[test]
|
|
|
|
fn test_git_push_nothing() {
|
|
|
|
let (test_env, workspace_root) = set_up();
|
2022-03-09 23:57:12 +00:00
|
|
|
// No branches to push yet
|
2023-10-10 11:59:18 +00:00
|
|
|
let (stdout, stderr) = test_env.jj_cmd_ok(&workspace_root, &["git", "push", "--all"]);
|
2023-10-10 11:07:06 +00:00
|
|
|
insta::assert_snapshot!(stdout, @"");
|
|
|
|
insta::assert_snapshot!(stderr, @r###"
|
2022-04-28 23:32:18 +00:00
|
|
|
Nothing changed.
|
|
|
|
"###);
|
2022-05-27 15:54:47 +00:00
|
|
|
}
|
2022-03-09 23:57:12 +00:00
|
|
|
|
2022-07-02 02:50:51 +00:00
|
|
|
#[test]
|
2022-07-13 04:14:02 +00:00
|
|
|
fn test_git_push_current_branch() {
|
|
|
|
let (test_env, workspace_root) = set_up();
|
cli: make set of immutable commits configurable
This adds a new `revset-aliases.immutable_heads()s` config for
defining the set of immutable commits. The set is defined as the
configured revset, as well as its ancestors, and the root commit
commit (even if the configured set is empty).
This patch also adds enforcement of the config where we already had
checks preventing rewrite of the root commit. The working-copy commit
is implicitly assumed to be writable in most cases. Specifically, we
won't prevent amending the working copy even if the user includes it
in the config but we do prevent `jj edit @` in that case. That seems
good enough to me. Maybe we should emit a warning when the working
copy is in the set of immutable commits.
Maybe we should add support for something more like [Mercurial's
phases](https://wiki.mercurial-scm.org/Phases), which is propagated on
push and pull. There's already some affordance for that in the view
object's `public_heads` field. However, this is simpler, especially
since we can't propagate the phase to Git remotes, and seems like a
good start. Also, it lets you say that commits authored by other users
are immutable, for example.
For now, the functionality is in the CLI library. I'm not sure if we
want to move it into the library crate. I'm leaning towards letting
library users do whatever they want without being restricted by
immutable commits. I do think we should move the functionality into a
future `ui-lib` or `ui-util` crate. That crate would have most of the
functionality in the current `cli_util` module (but in a
non-CLI-specific form).
2023-09-02 02:12:01 +00:00
|
|
|
test_env.add_config(r#"revset-aliases."immutable_heads()" = "none()""#);
|
2022-07-13 04:14:02 +00:00
|
|
|
// Update some branches. `branch1` is not a current branch, but `branch2` and
|
|
|
|
// `my-branch` are.
|
2023-10-10 11:59:18 +00:00
|
|
|
test_env.jj_cmd_ok(
|
2022-07-13 04:14:02 +00:00
|
|
|
&workspace_root,
|
|
|
|
&["describe", "branch1", "-m", "modified branch1 commit"],
|
|
|
|
);
|
2023-10-10 11:59:18 +00:00
|
|
|
test_env.jj_cmd_ok(&workspace_root, &["co", "branch2"]);
|
|
|
|
test_env.jj_cmd_ok(&workspace_root, &["branch", "set", "branch2"]);
|
|
|
|
test_env.jj_cmd_ok(&workspace_root, &["branch", "create", "my-branch"]);
|
|
|
|
test_env.jj_cmd_ok(&workspace_root, &["describe", "-m", "foo"]);
|
2022-07-13 04:14:02 +00:00
|
|
|
// Check the setup
|
2023-10-18 06:12:17 +00:00
|
|
|
let stdout = test_env.jj_cmd_success(&workspace_root, &["branch", "list", "--all"]);
|
2022-07-13 04:14:02 +00:00
|
|
|
insta::assert_snapshot!(stdout, @r###"
|
2023-07-11 01:46:38 +00:00
|
|
|
branch1: lzmmnrxq 19e00bf6 (empty) modified branch1 commit
|
2023-10-24 01:43:12 +00:00
|
|
|
@origin (ahead by 1 commits, behind by 1 commits): lzmmnrxq hidden 45a3aa29 (empty) description 1
|
2023-07-11 01:46:38 +00:00
|
|
|
branch2: yostqsxw 10ee3363 (empty) foo
|
|
|
|
@origin (behind by 1 commits): rlzusymt 8476341e (empty) description 2
|
|
|
|
my-branch: yostqsxw 10ee3363 (empty) foo
|
2022-07-13 04:14:02 +00:00
|
|
|
"###);
|
|
|
|
// First dry-run. `branch1` should not get pushed.
|
2023-10-10 11:59:18 +00:00
|
|
|
let (stdout, stderr) = test_env.jj_cmd_ok(&workspace_root, &["git", "push", "--dry-run"]);
|
2023-10-10 11:07:06 +00:00
|
|
|
insta::assert_snapshot!(stdout, @"");
|
|
|
|
insta::assert_snapshot!(stderr, @r###"
|
2022-07-13 04:14:02 +00:00
|
|
|
Branch changes to push to origin:
|
2022-12-21 04:47:10 +00:00
|
|
|
Move branch branch2 from 8476341eb395 to 10ee3363b259
|
|
|
|
Add branch my-branch to 10ee3363b259
|
2022-07-13 04:14:02 +00:00
|
|
|
Dry-run requested, not pushing.
|
|
|
|
"###);
|
2023-10-10 11:59:18 +00:00
|
|
|
let (stdout, stderr) = test_env.jj_cmd_ok(&workspace_root, &["git", "push"]);
|
2023-10-10 11:07:06 +00:00
|
|
|
insta::assert_snapshot!(stdout, @"");
|
|
|
|
insta::assert_snapshot!(stderr, @r###"
|
2022-07-13 04:14:02 +00:00
|
|
|
Branch changes to push to origin:
|
2022-12-21 04:47:10 +00:00
|
|
|
Move branch branch2 from 8476341eb395 to 10ee3363b259
|
|
|
|
Add branch my-branch to 10ee3363b259
|
2022-07-13 04:14:02 +00:00
|
|
|
"###);
|
2023-10-18 06:12:17 +00:00
|
|
|
let stdout = test_env.jj_cmd_success(&workspace_root, &["branch", "list", "--all"]);
|
2022-07-13 04:14:02 +00:00
|
|
|
insta::assert_snapshot!(stdout, @r###"
|
2023-07-11 01:46:38 +00:00
|
|
|
branch1: lzmmnrxq 19e00bf6 (empty) modified branch1 commit
|
2023-10-24 01:43:12 +00:00
|
|
|
@origin (ahead by 1 commits, behind by 1 commits): lzmmnrxq hidden 45a3aa29 (empty) description 1
|
2023-07-11 01:46:38 +00:00
|
|
|
branch2: yostqsxw 10ee3363 (empty) foo
|
2023-10-18 06:12:17 +00:00
|
|
|
@origin: yostqsxw 10ee3363 (empty) foo
|
2023-07-11 01:46:38 +00:00
|
|
|
my-branch: yostqsxw 10ee3363 (empty) foo
|
2023-10-18 06:12:17 +00:00
|
|
|
@origin: yostqsxw 10ee3363 (empty) foo
|
2022-07-13 04:14:02 +00:00
|
|
|
"###);
|
|
|
|
}
|
|
|
|
|
2022-10-20 21:18:34 +00:00
|
|
|
#[test]
|
|
|
|
fn test_git_push_parent_branch() {
|
|
|
|
let (test_env, workspace_root) = set_up();
|
cli: make set of immutable commits configurable
This adds a new `revset-aliases.immutable_heads()s` config for
defining the set of immutable commits. The set is defined as the
configured revset, as well as its ancestors, and the root commit
commit (even if the configured set is empty).
This patch also adds enforcement of the config where we already had
checks preventing rewrite of the root commit. The working-copy commit
is implicitly assumed to be writable in most cases. Specifically, we
won't prevent amending the working copy even if the user includes it
in the config but we do prevent `jj edit @` in that case. That seems
good enough to me. Maybe we should emit a warning when the working
copy is in the set of immutable commits.
Maybe we should add support for something more like [Mercurial's
phases](https://wiki.mercurial-scm.org/Phases), which is propagated on
push and pull. There's already some affordance for that in the view
object's `public_heads` field. However, this is simpler, especially
since we can't propagate the phase to Git remotes, and seems like a
good start. Also, it lets you say that commits authored by other users
are immutable, for example.
For now, the functionality is in the CLI library. I'm not sure if we
want to move it into the library crate. I'm leaning towards letting
library users do whatever they want without being restricted by
immutable commits. I do think we should move the functionality into a
future `ui-lib` or `ui-util` crate. That crate would have most of the
functionality in the current `cli_util` module (but in a
non-CLI-specific form).
2023-09-02 02:12:01 +00:00
|
|
|
test_env.add_config(r#"revset-aliases."immutable_heads()" = "none()""#);
|
2023-10-10 11:59:18 +00:00
|
|
|
test_env.jj_cmd_ok(&workspace_root, &["edit", "branch1"]);
|
|
|
|
test_env.jj_cmd_ok(
|
2022-10-20 21:18:34 +00:00
|
|
|
&workspace_root,
|
|
|
|
&["describe", "-m", "modified branch1 commit"],
|
|
|
|
);
|
2023-10-10 11:59:18 +00:00
|
|
|
test_env.jj_cmd_ok(&workspace_root, &["new", "-m", "non-empty description"]);
|
2023-08-21 20:11:40 +00:00
|
|
|
std::fs::write(workspace_root.join("file"), "file").unwrap();
|
2023-10-10 11:59:18 +00:00
|
|
|
let (stdout, stderr) = test_env.jj_cmd_ok(&workspace_root, &["git", "push"]);
|
2023-10-10 11:07:06 +00:00
|
|
|
insta::assert_snapshot!(stdout, @"");
|
|
|
|
insta::assert_snapshot!(stderr, @r###"
|
2022-10-20 21:18:34 +00:00
|
|
|
Branch changes to push to origin:
|
2022-12-21 04:47:10 +00:00
|
|
|
Force branch branch1 from 45a3aa29e907 to d47326d59ee1
|
2022-10-20 21:18:34 +00:00
|
|
|
"###);
|
|
|
|
}
|
|
|
|
|
2023-03-05 20:27:03 +00:00
|
|
|
#[test]
|
2023-08-21 20:11:40 +00:00
|
|
|
fn test_git_push_no_matching_branch() {
|
2023-03-05 20:27:03 +00:00
|
|
|
let (test_env, workspace_root) = set_up();
|
2023-10-10 11:59:18 +00:00
|
|
|
test_env.jj_cmd_ok(&workspace_root, &["new"]);
|
2023-08-21 20:11:40 +00:00
|
|
|
let (stdout, stderr) = test_env.jj_cmd_ok(&workspace_root, &["git", "push"]);
|
2023-10-10 11:07:06 +00:00
|
|
|
insta::assert_snapshot!(stdout, @"");
|
2023-03-05 20:27:03 +00:00
|
|
|
insta::assert_snapshot!(stderr, @r###"
|
2023-08-21 20:11:40 +00:00
|
|
|
No branches point to the specified revisions.
|
2023-10-10 11:07:06 +00:00
|
|
|
Nothing changed.
|
2023-03-05 20:27:03 +00:00
|
|
|
"###);
|
|
|
|
}
|
|
|
|
|
2022-07-13 04:14:02 +00:00
|
|
|
#[test]
|
2023-08-21 20:11:40 +00:00
|
|
|
fn test_git_push_matching_branch_unchanged() {
|
2022-07-13 04:14:02 +00:00
|
|
|
let (test_env, workspace_root) = set_up();
|
2023-10-10 11:59:18 +00:00
|
|
|
test_env.jj_cmd_ok(&workspace_root, &["co", "branch1"]);
|
2023-08-21 20:11:40 +00:00
|
|
|
let (stdout, stderr) = test_env.jj_cmd_ok(&workspace_root, &["git", "push"]);
|
2023-10-10 11:07:06 +00:00
|
|
|
insta::assert_snapshot!(stdout, @"");
|
2022-07-13 04:14:02 +00:00
|
|
|
insta::assert_snapshot!(stderr, @r###"
|
2023-08-21 20:11:40 +00:00
|
|
|
No branches point to the specified revisions.
|
2023-10-10 11:07:06 +00:00
|
|
|
Nothing changed.
|
2022-07-13 04:14:02 +00:00
|
|
|
"###);
|
|
|
|
}
|
|
|
|
|
2023-08-21 20:11:40 +00:00
|
|
|
/// Test that `jj git push` without arguments pushes a branch to the specified
|
|
|
|
/// remote even if it's already up to date on another remote
|
|
|
|
/// (`remote_branches(remote=<remote>)..@` vs. `remote_branches()..@`).
|
2023-01-30 03:46:29 +00:00
|
|
|
#[test]
|
2023-08-21 20:11:40 +00:00
|
|
|
fn test_git_push_other_remote_has_branch() {
|
2023-01-30 03:46:29 +00:00
|
|
|
let (test_env, workspace_root) = set_up();
|
cli: make set of immutable commits configurable
This adds a new `revset-aliases.immutable_heads()s` config for
defining the set of immutable commits. The set is defined as the
configured revset, as well as its ancestors, and the root commit
commit (even if the configured set is empty).
This patch also adds enforcement of the config where we already had
checks preventing rewrite of the root commit. The working-copy commit
is implicitly assumed to be writable in most cases. Specifically, we
won't prevent amending the working copy even if the user includes it
in the config but we do prevent `jj edit @` in that case. That seems
good enough to me. Maybe we should emit a warning when the working
copy is in the set of immutable commits.
Maybe we should add support for something more like [Mercurial's
phases](https://wiki.mercurial-scm.org/Phases), which is propagated on
push and pull. There's already some affordance for that in the view
object's `public_heads` field. However, this is simpler, especially
since we can't propagate the phase to Git remotes, and seems like a
good start. Also, it lets you say that commits authored by other users
are immutable, for example.
For now, the functionality is in the CLI library. I'm not sure if we
want to move it into the library crate. I'm leaning towards letting
library users do whatever they want without being restricted by
immutable commits. I do think we should move the functionality into a
future `ui-lib` or `ui-util` crate. That crate would have most of the
functionality in the current `cli_util` module (but in a
non-CLI-specific form).
2023-09-02 02:12:01 +00:00
|
|
|
test_env.add_config(r#"revset-aliases."immutable_heads()" = "none()""#);
|
2023-08-21 20:11:40 +00:00
|
|
|
// Create another remote (but actually the same)
|
|
|
|
let other_remote_path = test_env
|
|
|
|
.env_root()
|
|
|
|
.join("origin")
|
|
|
|
.join(".jj")
|
|
|
|
.join("repo")
|
|
|
|
.join("store")
|
|
|
|
.join("git");
|
2023-10-10 11:59:18 +00:00
|
|
|
test_env.jj_cmd_ok(
|
2023-08-21 20:11:40 +00:00
|
|
|
&workspace_root,
|
|
|
|
&[
|
|
|
|
"git",
|
|
|
|
"remote",
|
|
|
|
"add",
|
|
|
|
"other",
|
|
|
|
other_remote_path.to_str().unwrap(),
|
|
|
|
],
|
|
|
|
);
|
|
|
|
// Modify branch1 and push it to `origin`
|
2023-10-10 11:59:18 +00:00
|
|
|
test_env.jj_cmd_ok(&workspace_root, &["edit", "branch1"]);
|
|
|
|
test_env.jj_cmd_ok(&workspace_root, &["describe", "-m=modified"]);
|
2023-08-21 20:11:40 +00:00
|
|
|
let (stdout, stderr) = test_env.jj_cmd_ok(&workspace_root, &["git", "push"]);
|
2023-10-10 11:07:06 +00:00
|
|
|
insta::assert_snapshot!(stdout, @"");
|
|
|
|
insta::assert_snapshot!(stderr, @r###"
|
2023-08-21 20:11:40 +00:00
|
|
|
Branch changes to push to origin:
|
|
|
|
Force branch branch1 from 45a3aa29e907 to 50421a29358a
|
|
|
|
"###);
|
|
|
|
// Since it's already pushed to origin, nothing will happen if push again
|
|
|
|
let (stdout, stderr) = test_env.jj_cmd_ok(&workspace_root, &["git", "push"]);
|
2023-10-10 11:07:06 +00:00
|
|
|
insta::assert_snapshot!(stdout, @"");
|
2023-08-21 20:11:40 +00:00
|
|
|
insta::assert_snapshot!(stderr, @r###"
|
|
|
|
No branches point to the specified revisions.
|
2023-10-10 11:07:06 +00:00
|
|
|
Nothing changed.
|
2023-08-21 20:11:40 +00:00
|
|
|
"###);
|
|
|
|
// But it will still get pushed to another remote
|
|
|
|
let (stdout, stderr) = test_env.jj_cmd_ok(&workspace_root, &["git", "push", "--remote=other"]);
|
2023-10-10 11:07:06 +00:00
|
|
|
insta::assert_snapshot!(stdout, @"");
|
|
|
|
insta::assert_snapshot!(stderr, @r###"
|
2023-08-21 20:11:40 +00:00
|
|
|
Branch changes to push to other:
|
|
|
|
Add branch branch1 to 50421a29358a
|
|
|
|
"###);
|
2023-01-30 03:46:29 +00:00
|
|
|
}
|
|
|
|
|
2023-08-13 22:41:53 +00:00
|
|
|
#[test]
|
|
|
|
fn test_git_push_not_fast_forward() {
|
|
|
|
let (test_env, workspace_root) = set_up();
|
|
|
|
|
|
|
|
// Move branch1 forward on the remote
|
|
|
|
let origin_path = test_env.env_root().join("origin");
|
2023-10-10 11:59:18 +00:00
|
|
|
test_env.jj_cmd_ok(&origin_path, &["new", "branch1", "-m=remote"]);
|
2023-08-13 22:41:53 +00:00
|
|
|
std::fs::write(origin_path.join("remote"), "remote").unwrap();
|
2023-10-10 11:59:18 +00:00
|
|
|
test_env.jj_cmd_ok(&origin_path, &["branch", "set", "branch1"]);
|
|
|
|
test_env.jj_cmd_ok(&origin_path, &["git", "export"]);
|
2023-08-13 22:41:53 +00:00
|
|
|
|
|
|
|
// Move branch1 forward to another commit locally
|
2023-10-10 11:59:18 +00:00
|
|
|
test_env.jj_cmd_ok(&workspace_root, &["new", "branch1", "-m=local"]);
|
2023-08-13 22:41:53 +00:00
|
|
|
std::fs::write(workspace_root.join("local"), "local").unwrap();
|
2023-10-10 11:59:18 +00:00
|
|
|
test_env.jj_cmd_ok(&workspace_root, &["branch", "set", "branch1"]);
|
2023-08-13 22:41:53 +00:00
|
|
|
|
|
|
|
// Pushing should fail
|
|
|
|
let assert = test_env
|
|
|
|
.jj_cmd(&workspace_root, &["git", "push"])
|
|
|
|
.assert()
|
|
|
|
.code(1);
|
2023-10-10 11:07:06 +00:00
|
|
|
insta::assert_snapshot!(get_stdout_string(&assert), @"");
|
|
|
|
insta::assert_snapshot!(get_stderr_string(&assert), @r###"
|
2023-08-13 22:41:53 +00:00
|
|
|
Branch changes to push to origin:
|
|
|
|
Move branch branch1 from 45a3aa29e907 to c35839cb8e8c
|
|
|
|
Error: The push conflicts with changes made on the remote (it is not fast-forwardable).
|
|
|
|
Hint: Try fetching from the remote, then make the branch point to where you want it to be, and push again.
|
|
|
|
"###);
|
|
|
|
}
|
|
|
|
|
2023-10-14 14:54:35 +00:00
|
|
|
#[test]
|
|
|
|
fn test_git_push_locally_created_and_rewritten() {
|
|
|
|
let (test_env, workspace_root) = set_up();
|
|
|
|
// Ensure that remote branches aren't tracked automatically
|
|
|
|
test_env.add_config("git.auto-local-branch = false");
|
|
|
|
|
|
|
|
// Push locally-created branch
|
|
|
|
test_env.jj_cmd_ok(&workspace_root, &["new", "root()", "-mlocal 1"]);
|
2023-11-10 00:56:18 +00:00
|
|
|
test_env.jj_cmd_ok(&workspace_root, &["branch", "create", "my"]);
|
2023-10-14 14:54:35 +00:00
|
|
|
let (_stdout, stderr) = test_env.jj_cmd_ok(&workspace_root, &["git", "push"]);
|
|
|
|
insta::assert_snapshot!(stderr, @r###"
|
|
|
|
Branch changes to push to origin:
|
|
|
|
Add branch my to fcc999921ce9
|
|
|
|
"###);
|
|
|
|
|
|
|
|
// Rewrite it and push again, which would fail if the pushed branch weren't
|
|
|
|
// set to "tracking"
|
|
|
|
test_env.jj_cmd_ok(&workspace_root, &["describe", "-mlocal 2"]);
|
2023-10-18 06:12:17 +00:00
|
|
|
let stdout = test_env.jj_cmd_success(&workspace_root, &["branch", "list", "--all"]);
|
2023-10-14 14:54:35 +00:00
|
|
|
insta::assert_snapshot!(stdout, @r###"
|
|
|
|
branch1: lzmmnrxq 45a3aa29 (empty) description 1
|
2023-10-18 06:12:17 +00:00
|
|
|
@origin: lzmmnrxq 45a3aa29 (empty) description 1
|
2023-10-14 14:54:35 +00:00
|
|
|
branch2: rlzusymt 8476341e (empty) description 2
|
2023-10-18 06:12:17 +00:00
|
|
|
@origin: rlzusymt 8476341e (empty) description 2
|
2023-10-14 14:54:35 +00:00
|
|
|
my: vruxwmqv bde1d2e4 (empty) local 2
|
2023-10-24 01:43:12 +00:00
|
|
|
@origin (ahead by 1 commits, behind by 1 commits): vruxwmqv hidden fcc99992 (empty) local 1
|
2023-10-14 14:54:35 +00:00
|
|
|
"###);
|
|
|
|
let (_stdout, stderr) = test_env.jj_cmd_ok(&workspace_root, &["git", "push"]);
|
|
|
|
insta::assert_snapshot!(stderr, @r###"
|
|
|
|
Branch changes to push to origin:
|
|
|
|
Force branch my from fcc999921ce9 to bde1d2e44b2a
|
|
|
|
"###);
|
|
|
|
}
|
|
|
|
|
2022-07-13 04:14:02 +00:00
|
|
|
#[test]
|
2022-12-17 22:31:12 +00:00
|
|
|
fn test_git_push_multiple() {
|
2022-07-02 02:50:51 +00:00
|
|
|
let (test_env, workspace_root) = set_up();
|
2023-10-10 11:59:18 +00:00
|
|
|
test_env.jj_cmd_ok(&workspace_root, &["branch", "delete", "branch1"]);
|
|
|
|
test_env.jj_cmd_ok(
|
2022-07-02 02:50:51 +00:00
|
|
|
&workspace_root,
|
|
|
|
&["branch", "set", "--allow-backwards", "branch2"],
|
|
|
|
);
|
2023-10-10 11:59:18 +00:00
|
|
|
test_env.jj_cmd_ok(&workspace_root, &["branch", "create", "my-branch"]);
|
|
|
|
test_env.jj_cmd_ok(&workspace_root, &["describe", "-m", "foo"]);
|
2022-07-02 02:50:51 +00:00
|
|
|
// Check the setup
|
2023-10-18 06:12:17 +00:00
|
|
|
let stdout = test_env.jj_cmd_success(&workspace_root, &["branch", "list", "--all"]);
|
2022-07-02 02:50:51 +00:00
|
|
|
insta::assert_snapshot!(stdout, @r###"
|
|
|
|
branch1 (deleted)
|
2023-07-11 01:46:38 +00:00
|
|
|
@origin: lzmmnrxq 45a3aa29 (empty) description 1
|
2023-12-15 12:50:35 +00:00
|
|
|
(this branch will be *deleted permanently* on the remote on the next `jj git push`. Use `jj branch forget` to prevent this)
|
2023-07-11 01:46:38 +00:00
|
|
|
branch2: yqosqzyt 15dcdaa4 (empty) foo
|
|
|
|
@origin (ahead by 1 commits, behind by 1 commits): rlzusymt 8476341e (empty) description 2
|
|
|
|
my-branch: yqosqzyt 15dcdaa4 (empty) foo
|
2022-07-02 02:50:51 +00:00
|
|
|
"###);
|
2022-06-29 02:10:45 +00:00
|
|
|
// First dry-run
|
2023-10-10 11:59:18 +00:00
|
|
|
let (stdout, stderr) =
|
|
|
|
test_env.jj_cmd_ok(&workspace_root, &["git", "push", "--all", "--dry-run"]);
|
2023-10-10 11:07:06 +00:00
|
|
|
insta::assert_snapshot!(stdout, @"");
|
|
|
|
insta::assert_snapshot!(stderr, @r###"
|
2022-06-29 02:10:45 +00:00
|
|
|
Branch changes to push to origin:
|
2022-12-21 04:47:10 +00:00
|
|
|
Delete branch branch1 from 45a3aa29e907
|
|
|
|
Force branch branch2 from 8476341eb395 to 15dcdaa4f12f
|
|
|
|
Add branch my-branch to 15dcdaa4f12f
|
2022-06-29 02:10:45 +00:00
|
|
|
Dry-run requested, not pushing.
|
|
|
|
"###);
|
2022-12-17 22:31:12 +00:00
|
|
|
// Dry run requesting two specific branches
|
2023-10-10 11:59:18 +00:00
|
|
|
let (stdout, stderr) = test_env.jj_cmd_ok(
|
2022-12-17 22:31:12 +00:00
|
|
|
&workspace_root,
|
|
|
|
&["git", "push", "-b=branch1", "-b=my-branch", "--dry-run"],
|
|
|
|
);
|
2023-10-10 11:07:06 +00:00
|
|
|
insta::assert_snapshot!(stdout, @"");
|
|
|
|
insta::assert_snapshot!(stderr, @r###"
|
2022-12-17 22:31:12 +00:00
|
|
|
Branch changes to push to origin:
|
2022-12-21 04:47:10 +00:00
|
|
|
Delete branch branch1 from 45a3aa29e907
|
|
|
|
Add branch my-branch to 15dcdaa4f12f
|
2022-12-17 22:31:12 +00:00
|
|
|
Dry-run requested, not pushing.
|
|
|
|
"###);
|
2022-12-19 02:25:04 +00:00
|
|
|
// Dry run requesting two specific branches twice
|
2023-10-10 11:59:18 +00:00
|
|
|
let (stdout, stderr) = test_env.jj_cmd_ok(
|
2022-12-19 02:25:04 +00:00
|
|
|
&workspace_root,
|
|
|
|
&[
|
|
|
|
"git",
|
|
|
|
"push",
|
|
|
|
"-b=branch1",
|
|
|
|
"-b=my-branch",
|
|
|
|
"-b=branch1",
|
2023-10-24 06:31:26 +00:00
|
|
|
"-b=glob:my-*",
|
2022-12-19 02:25:04 +00:00
|
|
|
"--dry-run",
|
|
|
|
],
|
|
|
|
);
|
2023-10-10 11:07:06 +00:00
|
|
|
insta::assert_snapshot!(stdout, @"");
|
|
|
|
insta::assert_snapshot!(stderr, @r###"
|
2022-12-19 02:25:04 +00:00
|
|
|
Branch changes to push to origin:
|
2022-12-21 04:47:10 +00:00
|
|
|
Delete branch branch1 from 45a3aa29e907
|
|
|
|
Add branch my-branch to 15dcdaa4f12f
|
2022-12-19 02:25:04 +00:00
|
|
|
Dry-run requested, not pushing.
|
|
|
|
"###);
|
2023-10-24 06:31:26 +00:00
|
|
|
// Dry run with glob pattern
|
|
|
|
let (stdout, stderr) = test_env.jj_cmd_ok(
|
|
|
|
&workspace_root,
|
|
|
|
&["git", "push", "-b=glob:branch?", "--dry-run"],
|
|
|
|
);
|
|
|
|
insta::assert_snapshot!(stdout, @"");
|
|
|
|
insta::assert_snapshot!(stderr, @r###"
|
|
|
|
Branch changes to push to origin:
|
|
|
|
Delete branch branch1 from 45a3aa29e907
|
|
|
|
Force branch branch2 from 8476341eb395 to 15dcdaa4f12f
|
|
|
|
Dry-run requested, not pushing.
|
|
|
|
"###);
|
|
|
|
|
|
|
|
// Unmatched branch name is error
|
|
|
|
let stderr = test_env.jj_cmd_failure(&workspace_root, &["git", "push", "-b=foo"]);
|
|
|
|
insta::assert_snapshot!(stderr, @r###"
|
|
|
|
Error: No such branch: foo
|
|
|
|
"###);
|
|
|
|
let stderr = test_env.jj_cmd_failure(
|
|
|
|
&workspace_root,
|
|
|
|
&["git", "push", "-b=foo", "-b=glob:?branch"],
|
|
|
|
);
|
|
|
|
insta::assert_snapshot!(stderr, @r###"
|
|
|
|
Error: No matching branches for patterns: foo, ?branch
|
|
|
|
"###);
|
|
|
|
|
2023-10-10 11:59:18 +00:00
|
|
|
let (stdout, stderr) = test_env.jj_cmd_ok(&workspace_root, &["git", "push", "--all"]);
|
2023-10-10 11:07:06 +00:00
|
|
|
insta::assert_snapshot!(stdout, @"");
|
|
|
|
insta::assert_snapshot!(stderr, @r###"
|
2022-06-29 02:10:45 +00:00
|
|
|
Branch changes to push to origin:
|
2022-12-21 04:47:10 +00:00
|
|
|
Delete branch branch1 from 45a3aa29e907
|
|
|
|
Force branch branch2 from 8476341eb395 to 15dcdaa4f12f
|
|
|
|
Add branch my-branch to 15dcdaa4f12f
|
2022-06-29 02:10:45 +00:00
|
|
|
"###);
|
2023-10-18 06:12:17 +00:00
|
|
|
let stdout = test_env.jj_cmd_success(&workspace_root, &["branch", "list", "--all"]);
|
2022-07-02 02:50:51 +00:00
|
|
|
insta::assert_snapshot!(stdout, @r###"
|
2023-07-11 01:46:38 +00:00
|
|
|
branch2: yqosqzyt 15dcdaa4 (empty) foo
|
2023-10-18 06:12:17 +00:00
|
|
|
@origin: yqosqzyt 15dcdaa4 (empty) foo
|
2023-07-11 01:46:38 +00:00
|
|
|
my-branch: yqosqzyt 15dcdaa4 (empty) foo
|
2023-10-18 06:12:17 +00:00
|
|
|
@origin: yqosqzyt 15dcdaa4 (empty) foo
|
2022-07-02 02:50:51 +00:00
|
|
|
"###);
|
2023-10-14 19:27:44 +00:00
|
|
|
let stdout = test_env.jj_cmd_success(&workspace_root, &["log", "-rall()"]);
|
|
|
|
insta::assert_snapshot!(stdout, @r###"
|
|
|
|
@ yqosqzyt test.user@example.com 2001-02-03 04:05:17.000 +07:00 branch2 my-branch 15dcdaa4
|
|
|
|
│ (empty) foo
|
|
|
|
│ ◉ rlzusymt test.user@example.com 2001-02-03 04:05:10.000 +07:00 8476341e
|
|
|
|
├─╯ (empty) description 2
|
|
|
|
│ ◉ lzmmnrxq test.user@example.com 2001-02-03 04:05:08.000 +07:00 45a3aa29
|
|
|
|
├─╯ (empty) description 1
|
|
|
|
◉ zzzzzzzz root() 00000000
|
|
|
|
"###);
|
2022-07-02 02:50:51 +00:00
|
|
|
}
|
|
|
|
|
2022-12-17 22:31:12 +00:00
|
|
|
#[test]
|
|
|
|
fn test_git_push_changes() {
|
|
|
|
let (test_env, workspace_root) = set_up();
|
2023-10-10 11:59:18 +00:00
|
|
|
test_env.jj_cmd_ok(&workspace_root, &["describe", "-m", "foo"]);
|
2022-12-17 22:31:12 +00:00
|
|
|
std::fs::write(workspace_root.join("file"), "contents").unwrap();
|
2023-10-10 11:59:18 +00:00
|
|
|
test_env.jj_cmd_ok(&workspace_root, &["new", "-m", "bar"]);
|
2022-12-17 22:31:12 +00:00
|
|
|
std::fs::write(workspace_root.join("file"), "modified").unwrap();
|
|
|
|
|
2023-10-10 11:59:18 +00:00
|
|
|
let (stdout, stderr) = test_env.jj_cmd_ok(&workspace_root, &["git", "push", "--change", "@"]);
|
2023-10-10 11:07:06 +00:00
|
|
|
insta::assert_snapshot!(stdout, @"");
|
|
|
|
insta::assert_snapshot!(stderr, @r###"
|
2023-02-12 19:49:05 +00:00
|
|
|
Creating branch push-yostqsxwqrlt for revision @
|
2022-12-17 22:31:12 +00:00
|
|
|
Branch changes to push to origin:
|
2023-02-12 19:49:05 +00:00
|
|
|
Add branch push-yostqsxwqrlt to 28d7620ea63a
|
2022-12-17 22:31:12 +00:00
|
|
|
"###);
|
2022-12-17 22:31:12 +00:00
|
|
|
// test pushing two changes at once
|
|
|
|
std::fs::write(workspace_root.join("file"), "modified2").unwrap();
|
2023-10-10 11:59:18 +00:00
|
|
|
let (stdout, stderr) = test_env.jj_cmd_ok(&workspace_root, &["git", "push", "-c=@", "-c=@-"]);
|
2023-10-10 11:07:06 +00:00
|
|
|
insta::assert_snapshot!(stdout, @"");
|
|
|
|
insta::assert_snapshot!(stderr, @r###"
|
2023-02-12 19:49:05 +00:00
|
|
|
Creating branch push-yqosqzytrlsw for revision @-
|
2022-12-17 22:31:12 +00:00
|
|
|
Branch changes to push to origin:
|
2023-02-12 19:49:05 +00:00
|
|
|
Force branch push-yostqsxwqrlt from 28d7620ea63a to 48d8c7948133
|
|
|
|
Add branch push-yqosqzytrlsw to fa16a14170fb
|
2022-12-17 22:31:12 +00:00
|
|
|
"###);
|
2022-12-19 02:25:04 +00:00
|
|
|
// specifying the same change twice doesn't break things
|
|
|
|
std::fs::write(workspace_root.join("file"), "modified3").unwrap();
|
2023-10-10 11:59:18 +00:00
|
|
|
let (stdout, stderr) = test_env.jj_cmd_ok(&workspace_root, &["git", "push", "-c=@", "-c=@"]);
|
2023-10-10 11:07:06 +00:00
|
|
|
insta::assert_snapshot!(stdout, @"");
|
|
|
|
insta::assert_snapshot!(stderr, @r###"
|
2022-12-19 02:25:04 +00:00
|
|
|
Branch changes to push to origin:
|
2023-02-12 19:49:05 +00:00
|
|
|
Force branch push-yostqsxwqrlt from 48d8c7948133 to b5f030322b1d
|
2023-01-11 18:30:31 +00:00
|
|
|
"###);
|
2023-08-07 22:41:42 +00:00
|
|
|
// Test changing `git.push-branch-prefix`. It causes us to push again.
|
2023-10-10 11:59:18 +00:00
|
|
|
let (stdout, stderr) = test_env.jj_cmd_ok(
|
2023-08-07 22:41:42 +00:00
|
|
|
&workspace_root,
|
|
|
|
&[
|
|
|
|
"git",
|
|
|
|
"push",
|
|
|
|
"--config-toml",
|
|
|
|
r"git.push-branch-prefix='test-'",
|
|
|
|
"--change=@",
|
|
|
|
],
|
|
|
|
);
|
2023-10-10 11:07:06 +00:00
|
|
|
insta::assert_snapshot!(stdout, @"");
|
|
|
|
insta::assert_snapshot!(stderr, @r###"
|
2023-08-07 22:41:42 +00:00
|
|
|
Creating branch test-yostqsxwqrlt for revision @
|
|
|
|
Branch changes to push to origin:
|
|
|
|
Add branch test-yostqsxwqrlt to b5f030322b1d
|
|
|
|
"###);
|
2023-01-11 18:30:31 +00:00
|
|
|
}
|
|
|
|
|
2023-06-03 05:39:33 +00:00
|
|
|
#[test]
|
|
|
|
fn test_git_push_revisions() {
|
|
|
|
let (test_env, workspace_root) = set_up();
|
2023-10-10 11:59:18 +00:00
|
|
|
test_env.jj_cmd_ok(&workspace_root, &["describe", "-m", "foo"]);
|
2023-06-03 05:39:33 +00:00
|
|
|
std::fs::write(workspace_root.join("file"), "contents").unwrap();
|
2023-10-10 11:59:18 +00:00
|
|
|
test_env.jj_cmd_ok(&workspace_root, &["new", "-m", "bar"]);
|
|
|
|
test_env.jj_cmd_ok(&workspace_root, &["branch", "create", "branch-1"]);
|
2023-06-03 05:39:33 +00:00
|
|
|
std::fs::write(workspace_root.join("file"), "modified").unwrap();
|
2023-10-10 11:59:18 +00:00
|
|
|
test_env.jj_cmd_ok(&workspace_root, &["new", "-m", "baz"]);
|
|
|
|
test_env.jj_cmd_ok(&workspace_root, &["branch", "create", "branch-2a"]);
|
|
|
|
test_env.jj_cmd_ok(&workspace_root, &["branch", "create", "branch-2b"]);
|
2023-06-03 05:39:33 +00:00
|
|
|
std::fs::write(workspace_root.join("file"), "modified again").unwrap();
|
|
|
|
|
|
|
|
// Push an empty set
|
|
|
|
let stderr = test_env.jj_cmd_failure(&workspace_root, &["git", "push", "-r=none()"]);
|
|
|
|
insta::assert_snapshot!(stderr, @r###"
|
|
|
|
Error: Empty revision set
|
|
|
|
"###);
|
|
|
|
// Push a revision with no branches
|
2023-08-22 05:34:58 +00:00
|
|
|
let (stdout, stderr) = test_env.jj_cmd_ok(&workspace_root, &["git", "push", "-r=@--"]);
|
2023-10-10 11:07:06 +00:00
|
|
|
insta::assert_snapshot!(stdout, @"");
|
2023-06-03 05:39:33 +00:00
|
|
|
insta::assert_snapshot!(stderr, @r###"
|
2023-08-22 05:34:58 +00:00
|
|
|
No branches point to the specified revisions.
|
2023-10-10 11:07:06 +00:00
|
|
|
Nothing changed.
|
2023-06-03 05:39:33 +00:00
|
|
|
"###);
|
|
|
|
// Push a revision with a single branch
|
2023-10-10 11:59:18 +00:00
|
|
|
let (stdout, stderr) =
|
|
|
|
test_env.jj_cmd_ok(&workspace_root, &["git", "push", "-r=@-", "--dry-run"]);
|
2023-10-10 11:07:06 +00:00
|
|
|
insta::assert_snapshot!(stdout, @"");
|
|
|
|
insta::assert_snapshot!(stderr, @r###"
|
2023-06-03 05:39:33 +00:00
|
|
|
Branch changes to push to origin:
|
|
|
|
Add branch branch-1 to 7decc7932d9c
|
|
|
|
Dry-run requested, not pushing.
|
|
|
|
"###);
|
|
|
|
// Push multiple revisions of which some have branches
|
2023-10-10 11:59:18 +00:00
|
|
|
let (stdout, stderr) = test_env.jj_cmd_ok(
|
2023-06-03 05:39:33 +00:00
|
|
|
&workspace_root,
|
|
|
|
&["git", "push", "-r=@--", "-r=@-", "--dry-run"],
|
|
|
|
);
|
2023-10-10 11:07:06 +00:00
|
|
|
insta::assert_snapshot!(stdout, @"");
|
|
|
|
insta::assert_snapshot!(stderr, @r###"
|
2023-06-03 05:39:33 +00:00
|
|
|
Branch changes to push to origin:
|
|
|
|
Add branch branch-1 to 7decc7932d9c
|
|
|
|
Dry-run requested, not pushing.
|
|
|
|
"###);
|
|
|
|
// Push a revision with a multiple branches
|
2023-10-10 11:59:18 +00:00
|
|
|
let (stdout, stderr) =
|
|
|
|
test_env.jj_cmd_ok(&workspace_root, &["git", "push", "-r=@", "--dry-run"]);
|
2023-10-10 11:07:06 +00:00
|
|
|
insta::assert_snapshot!(stdout, @"");
|
|
|
|
insta::assert_snapshot!(stderr, @r###"
|
2023-06-03 05:39:33 +00:00
|
|
|
Branch changes to push to origin:
|
|
|
|
Add branch branch-2a to 1b45449e18d0
|
|
|
|
Add branch branch-2b to 1b45449e18d0
|
|
|
|
Dry-run requested, not pushing.
|
|
|
|
"###);
|
|
|
|
// Repeating a commit doesn't result in repeated messages about the branch
|
2023-10-10 11:59:18 +00:00
|
|
|
let (stdout, stderr) = test_env.jj_cmd_ok(
|
2023-06-03 05:39:33 +00:00
|
|
|
&workspace_root,
|
|
|
|
&["git", "push", "-r=@-", "-r=@-", "--dry-run"],
|
|
|
|
);
|
2023-10-10 11:07:06 +00:00
|
|
|
insta::assert_snapshot!(stdout, @"");
|
|
|
|
insta::assert_snapshot!(stderr, @r###"
|
2023-06-03 05:39:33 +00:00
|
|
|
Branch changes to push to origin:
|
|
|
|
Add branch branch-1 to 7decc7932d9c
|
|
|
|
Dry-run requested, not pushing.
|
|
|
|
"###);
|
|
|
|
}
|
|
|
|
|
2023-06-03 06:24:28 +00:00
|
|
|
#[test]
|
|
|
|
fn test_git_push_mixed() {
|
|
|
|
let (test_env, workspace_root) = set_up();
|
2023-10-10 11:59:18 +00:00
|
|
|
test_env.jj_cmd_ok(&workspace_root, &["describe", "-m", "foo"]);
|
2023-06-03 06:24:28 +00:00
|
|
|
std::fs::write(workspace_root.join("file"), "contents").unwrap();
|
2023-10-10 11:59:18 +00:00
|
|
|
test_env.jj_cmd_ok(&workspace_root, &["new", "-m", "bar"]);
|
|
|
|
test_env.jj_cmd_ok(&workspace_root, &["branch", "create", "branch-1"]);
|
2023-06-03 06:24:28 +00:00
|
|
|
std::fs::write(workspace_root.join("file"), "modified").unwrap();
|
2023-10-10 11:59:18 +00:00
|
|
|
test_env.jj_cmd_ok(&workspace_root, &["new", "-m", "baz"]);
|
|
|
|
test_env.jj_cmd_ok(&workspace_root, &["branch", "create", "branch-2a"]);
|
|
|
|
test_env.jj_cmd_ok(&workspace_root, &["branch", "create", "branch-2b"]);
|
2023-06-03 05:39:33 +00:00
|
|
|
std::fs::write(workspace_root.join("file"), "modified again").unwrap();
|
2023-06-03 06:24:28 +00:00
|
|
|
|
2023-10-10 11:59:18 +00:00
|
|
|
let (stdout, stderr) = test_env.jj_cmd_ok(
|
2023-06-03 06:24:28 +00:00
|
|
|
&workspace_root,
|
2023-06-03 05:39:33 +00:00
|
|
|
&["git", "push", "--change=@--", "--branch=branch-1", "-r=@"],
|
2023-06-03 06:24:28 +00:00
|
|
|
);
|
2023-10-10 11:07:06 +00:00
|
|
|
insta::assert_snapshot!(stdout, @"");
|
|
|
|
insta::assert_snapshot!(stderr, @r###"
|
2023-06-03 05:39:33 +00:00
|
|
|
Creating branch push-yqosqzytrlsw for revision @--
|
2023-06-03 06:24:28 +00:00
|
|
|
Branch changes to push to origin:
|
2023-06-03 05:39:33 +00:00
|
|
|
Add branch branch-1 to 7decc7932d9c
|
2023-06-03 06:24:28 +00:00
|
|
|
Add branch push-yqosqzytrlsw to fa16a14170fb
|
2023-06-03 05:39:33 +00:00
|
|
|
Add branch branch-2a to 1b45449e18d0
|
|
|
|
Add branch branch-2b to 1b45449e18d0
|
2023-06-03 06:24:28 +00:00
|
|
|
"###);
|
|
|
|
}
|
|
|
|
|
2023-01-11 18:30:31 +00:00
|
|
|
#[test]
|
|
|
|
fn test_git_push_existing_long_branch() {
|
|
|
|
let (test_env, workspace_root) = set_up();
|
2023-10-10 11:59:18 +00:00
|
|
|
test_env.jj_cmd_ok(&workspace_root, &["describe", "-m", "foo"]);
|
2023-01-11 18:30:31 +00:00
|
|
|
std::fs::write(workspace_root.join("file"), "contents").unwrap();
|
2023-10-10 11:59:18 +00:00
|
|
|
test_env.jj_cmd_ok(
|
2023-01-11 18:30:31 +00:00
|
|
|
&workspace_root,
|
2023-01-14 04:50:45 +00:00
|
|
|
&["branch", "create", "push-19b790168e73f7a73a98deae21e807c0"],
|
2023-01-11 18:30:31 +00:00
|
|
|
);
|
|
|
|
|
2023-10-10 11:59:18 +00:00
|
|
|
let (stdout, stderr) = test_env.jj_cmd_ok(&workspace_root, &["git", "push", "--change=@"]);
|
2023-10-10 11:07:06 +00:00
|
|
|
insta::assert_snapshot!(stdout, @"");
|
|
|
|
insta::assert_snapshot!(stderr, @r###"
|
2023-01-11 18:30:31 +00:00
|
|
|
Branch changes to push to origin:
|
2023-01-14 04:50:45 +00:00
|
|
|
Add branch push-19b790168e73f7a73a98deae21e807c0 to fa16a14170fb
|
2022-12-19 02:25:04 +00:00
|
|
|
"###);
|
2022-12-17 22:31:12 +00:00
|
|
|
}
|
|
|
|
|
2022-07-05 06:14:39 +00:00
|
|
|
#[test]
|
|
|
|
fn test_git_push_unsnapshotted_change() {
|
|
|
|
let (test_env, workspace_root) = set_up();
|
2023-10-10 11:59:18 +00:00
|
|
|
test_env.jj_cmd_ok(&workspace_root, &["describe", "-m", "foo"]);
|
2022-07-05 06:14:39 +00:00
|
|
|
std::fs::write(workspace_root.join("file"), "contents").unwrap();
|
2023-10-10 11:59:18 +00:00
|
|
|
test_env.jj_cmd_ok(&workspace_root, &["git", "push", "--change", "@"]);
|
2022-07-05 06:14:39 +00:00
|
|
|
std::fs::write(workspace_root.join("file"), "modified").unwrap();
|
2023-10-10 11:59:18 +00:00
|
|
|
test_env.jj_cmd_ok(&workspace_root, &["git", "push", "--change", "@"]);
|
2022-07-05 06:14:39 +00:00
|
|
|
}
|
|
|
|
|
2022-05-27 15:54:47 +00:00
|
|
|
#[test]
|
|
|
|
fn test_git_push_conflict() {
|
|
|
|
let (test_env, workspace_root) = set_up();
|
2022-03-09 23:57:12 +00:00
|
|
|
std::fs::write(workspace_root.join("file"), "first").unwrap();
|
2023-10-10 11:59:18 +00:00
|
|
|
test_env.jj_cmd_ok(&workspace_root, &["commit", "-m", "first"]);
|
2022-03-09 23:57:12 +00:00
|
|
|
std::fs::write(workspace_root.join("file"), "second").unwrap();
|
2023-10-10 11:59:18 +00:00
|
|
|
test_env.jj_cmd_ok(&workspace_root, &["commit", "-m", "second"]);
|
2022-03-09 23:57:12 +00:00
|
|
|
std::fs::write(workspace_root.join("file"), "third").unwrap();
|
2023-10-10 11:59:18 +00:00
|
|
|
test_env.jj_cmd_ok(&workspace_root, &["rebase", "-r", "@", "-d", "@--"]);
|
2023-11-10 00:56:18 +00:00
|
|
|
test_env.jj_cmd_ok(&workspace_root, &["branch", "create", "my-branch"]);
|
2023-10-10 11:59:18 +00:00
|
|
|
test_env.jj_cmd_ok(&workspace_root, &["describe", "-m", "third"]);
|
2022-07-13 04:14:02 +00:00
|
|
|
let stderr = test_env.jj_cmd_failure(&workspace_root, &["git", "push", "--all"]);
|
2022-04-28 23:32:18 +00:00
|
|
|
insta::assert_snapshot!(stderr, @r###"
|
2023-10-05 04:30:29 +00:00
|
|
|
Error: Won't push commit 1973d389875c since it has conflicts
|
2022-05-27 15:54:47 +00:00
|
|
|
"###);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_git_push_no_description() {
|
|
|
|
let (test_env, workspace_root) = set_up();
|
2023-10-10 11:59:18 +00:00
|
|
|
test_env.jj_cmd_ok(&workspace_root, &["branch", "create", "my-branch"]);
|
|
|
|
test_env.jj_cmd_ok(&workspace_root, &["describe", "-m="]);
|
2022-05-27 15:54:47 +00:00
|
|
|
let stderr =
|
|
|
|
test_env.jj_cmd_failure(&workspace_root, &["git", "push", "--branch", "my-branch"]);
|
|
|
|
insta::assert_snapshot!(stderr, @r###"
|
2022-11-04 18:25:11 +00:00
|
|
|
Error: Won't push commit 5b36783cd11c since it has no description
|
2022-05-27 15:54:47 +00:00
|
|
|
"###);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_git_push_missing_author() {
|
|
|
|
let (test_env, workspace_root) = set_up();
|
|
|
|
let run_without_var = |var: &str, args: &[&str]| {
|
|
|
|
test_env
|
|
|
|
.jj_cmd(&workspace_root, args)
|
|
|
|
.env_remove(var)
|
|
|
|
.assert()
|
|
|
|
.success();
|
|
|
|
};
|
2023-09-03 03:47:23 +00:00
|
|
|
run_without_var("JJ_USER", &["checkout", "root()", "-m=initial"]);
|
2022-05-27 15:54:47 +00:00
|
|
|
run_without_var("JJ_USER", &["branch", "create", "missing-name"]);
|
|
|
|
let stderr = test_env.jj_cmd_failure(
|
|
|
|
&workspace_root,
|
|
|
|
&["git", "push", "--branch", "missing-name"],
|
|
|
|
);
|
|
|
|
insta::assert_snapshot!(stderr, @r###"
|
2023-08-16 21:10:54 +00:00
|
|
|
Error: Won't push commit 944313939bbd since it has no author and/or committer set
|
2022-05-27 15:54:47 +00:00
|
|
|
"###);
|
2023-09-03 03:47:23 +00:00
|
|
|
run_without_var("JJ_EMAIL", &["checkout", "root()", "-m=initial"]);
|
2022-05-27 15:54:47 +00:00
|
|
|
run_without_var("JJ_EMAIL", &["branch", "create", "missing-email"]);
|
2022-11-05 00:15:35 +00:00
|
|
|
let stderr =
|
|
|
|
test_env.jj_cmd_failure(&workspace_root, &["git", "push", "--branch=missing-email"]);
|
2022-05-27 15:54:47 +00:00
|
|
|
insta::assert_snapshot!(stderr, @r###"
|
2023-08-16 21:10:54 +00:00
|
|
|
Error: Won't push commit 59354714f789 since it has no author and/or committer set
|
2022-05-27 15:54:47 +00:00
|
|
|
"###);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_git_push_missing_committer() {
|
|
|
|
let (test_env, workspace_root) = set_up();
|
|
|
|
let run_without_var = |var: &str, args: &[&str]| {
|
|
|
|
test_env
|
|
|
|
.jj_cmd(&workspace_root, args)
|
|
|
|
.env_remove(var)
|
|
|
|
.assert()
|
|
|
|
.success();
|
|
|
|
};
|
2023-10-10 11:59:18 +00:00
|
|
|
test_env.jj_cmd_ok(&workspace_root, &["branch", "create", "missing-name"]);
|
2022-11-05 00:15:35 +00:00
|
|
|
run_without_var("JJ_USER", &["describe", "-m=no committer name"]);
|
|
|
|
let stderr =
|
|
|
|
test_env.jj_cmd_failure(&workspace_root, &["git", "push", "--branch=missing-name"]);
|
2022-05-27 15:54:47 +00:00
|
|
|
insta::assert_snapshot!(stderr, @r###"
|
2023-08-16 21:10:54 +00:00
|
|
|
Error: Won't push commit 4fd190283d1a since it has no author and/or committer set
|
2022-05-27 15:54:47 +00:00
|
|
|
"###);
|
2023-10-10 11:59:18 +00:00
|
|
|
test_env.jj_cmd_ok(&workspace_root, &["checkout", "root()"]);
|
|
|
|
test_env.jj_cmd_ok(&workspace_root, &["branch", "create", "missing-email"]);
|
2022-11-05 00:15:35 +00:00
|
|
|
run_without_var("JJ_EMAIL", &["describe", "-m=no committer email"]);
|
|
|
|
let stderr =
|
|
|
|
test_env.jj_cmd_failure(&workspace_root, &["git", "push", "--branch=missing-email"]);
|
2022-05-27 15:54:47 +00:00
|
|
|
insta::assert_snapshot!(stderr, @r###"
|
2023-08-16 21:10:54 +00:00
|
|
|
Error: Won't push commit eab97428a6ec since it has no author and/or committer set
|
2022-05-27 15:54:47 +00:00
|
|
|
"###);
|
|
|
|
|
|
|
|
// Test message when there are multiple reasons (missing committer and
|
|
|
|
// description)
|
2022-11-05 00:15:35 +00:00
|
|
|
run_without_var("JJ_EMAIL", &["describe", "-m=", "missing-email"]);
|
|
|
|
let stderr =
|
|
|
|
test_env.jj_cmd_failure(&workspace_root, &["git", "push", "--branch=missing-email"]);
|
2022-05-27 15:54:47 +00:00
|
|
|
insta::assert_snapshot!(stderr, @r###"
|
2023-08-16 21:10:54 +00:00
|
|
|
Error: Won't push commit 1143ed607f54 since it has no description and it has no author and/or committer set
|
2022-04-28 23:32:18 +00:00
|
|
|
"###);
|
2022-03-09 23:57:12 +00:00
|
|
|
}
|
2023-02-19 12:08:24 +00:00
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_git_push_deleted() {
|
|
|
|
let (test_env, workspace_root) = set_up();
|
|
|
|
|
2023-10-10 11:59:18 +00:00
|
|
|
test_env.jj_cmd_ok(&workspace_root, &["branch", "delete", "branch1"]);
|
|
|
|
let (stdout, stderr) = test_env.jj_cmd_ok(&workspace_root, &["git", "push", "--deleted"]);
|
2023-10-10 11:07:06 +00:00
|
|
|
insta::assert_snapshot!(stdout, @"");
|
|
|
|
insta::assert_snapshot!(stderr, @r###"
|
2023-02-19 12:08:24 +00:00
|
|
|
Branch changes to push to origin:
|
|
|
|
Delete branch branch1 from 45a3aa29e907
|
2023-10-14 19:27:44 +00:00
|
|
|
"###);
|
|
|
|
let stdout = test_env.jj_cmd_success(&workspace_root, &["log", "-rall()"]);
|
|
|
|
insta::assert_snapshot!(stdout, @r###"
|
|
|
|
◉ rlzusymt test.user@example.com 2001-02-03 04:05:10.000 +07:00 branch2 8476341e
|
|
|
|
│ (empty) description 2
|
|
|
|
│ ◉ lzmmnrxq test.user@example.com 2001-02-03 04:05:08.000 +07:00 45a3aa29
|
|
|
|
├─╯ (empty) description 1
|
|
|
|
│ @ yqosqzyt test.user@example.com 2001-02-03 04:05:13.000 +07:00 5b36783c
|
|
|
|
├─╯ (empty) (no description set)
|
|
|
|
◉ zzzzzzzz root() 00000000
|
2023-02-19 12:08:24 +00:00
|
|
|
"###);
|
2023-10-10 11:59:18 +00:00
|
|
|
let (stdout, stderr) = test_env.jj_cmd_ok(&workspace_root, &["git", "push", "--deleted"]);
|
2023-10-10 11:07:06 +00:00
|
|
|
insta::assert_snapshot!(stdout, @"");
|
|
|
|
insta::assert_snapshot!(stderr, @r###"
|
2023-02-19 12:08:24 +00:00
|
|
|
Nothing changed.
|
|
|
|
"###);
|
|
|
|
}
|
2023-07-03 09:03:07 +00:00
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_git_push_conflicting_branches() {
|
|
|
|
let (test_env, workspace_root) = set_up();
|
2023-12-16 10:00:14 +00:00
|
|
|
test_env.add_config("git.auto-local-branch = true");
|
2023-07-03 09:03:07 +00:00
|
|
|
let git_repo = {
|
|
|
|
let mut git_repo_path = workspace_root.clone();
|
|
|
|
git_repo_path.extend([".jj", "repo", "store", "git"]);
|
|
|
|
git2::Repository::open(&git_repo_path).unwrap()
|
|
|
|
};
|
|
|
|
|
|
|
|
// Forget remote ref, move local ref, then fetch to create conflict.
|
|
|
|
git_repo
|
|
|
|
.find_reference("refs/remotes/origin/branch2")
|
|
|
|
.unwrap()
|
|
|
|
.delete()
|
|
|
|
.unwrap();
|
2023-10-10 11:59:18 +00:00
|
|
|
test_env.jj_cmd_ok(&workspace_root, &["git", "import"]);
|
|
|
|
test_env.jj_cmd_ok(&workspace_root, &["new", "root()", "-m=description 3"]);
|
2023-11-10 00:56:18 +00:00
|
|
|
test_env.jj_cmd_ok(&workspace_root, &["branch", "create", "branch2"]);
|
2023-10-10 11:59:18 +00:00
|
|
|
test_env.jj_cmd_ok(&workspace_root, &["git", "fetch"]);
|
2023-10-18 06:12:17 +00:00
|
|
|
insta::assert_snapshot!(
|
|
|
|
test_env.jj_cmd_success(&workspace_root, &["branch", "list", "--all"]), @r###"
|
2023-07-11 01:46:38 +00:00
|
|
|
branch1: lzmmnrxq 45a3aa29 (empty) description 1
|
2023-10-18 06:12:17 +00:00
|
|
|
@origin: lzmmnrxq 45a3aa29 (empty) description 1
|
2023-07-03 09:03:07 +00:00
|
|
|
branch2 (conflicted):
|
2023-07-11 01:46:38 +00:00
|
|
|
+ yostqsxw 8e670e2d (empty) description 3
|
|
|
|
+ rlzusymt 8476341e (empty) description 2
|
|
|
|
@origin (behind by 1 commits): rlzusymt 8476341e (empty) description 2
|
2023-07-03 09:03:07 +00:00
|
|
|
"###);
|
|
|
|
|
|
|
|
let bump_branch1 = || {
|
2023-10-10 11:59:18 +00:00
|
|
|
test_env.jj_cmd_ok(&workspace_root, &["new", "branch1", "-m=bump"]);
|
|
|
|
test_env.jj_cmd_ok(&workspace_root, &["branch", "set", "branch1"]);
|
2023-07-03 09:03:07 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
// Conflicting branch at @
|
2023-08-21 20:11:40 +00:00
|
|
|
let (stdout, stderr) = test_env.jj_cmd_ok(&workspace_root, &["git", "push"]);
|
2023-10-10 11:07:06 +00:00
|
|
|
insta::assert_snapshot!(stdout, @"");
|
2023-07-03 09:03:07 +00:00
|
|
|
insta::assert_snapshot!(stderr, @r###"
|
2023-08-21 20:11:40 +00:00
|
|
|
Branch branch2 is conflicted
|
2023-10-16 19:25:52 +00:00
|
|
|
Hint: Run `jj branch list` to inspect, and use `jj branch set` to fix it up.
|
2023-10-10 11:07:06 +00:00
|
|
|
Nothing changed.
|
2023-07-03 09:03:07 +00:00
|
|
|
"###);
|
|
|
|
|
|
|
|
// --branch should be blocked by conflicting branch
|
|
|
|
let stderr = test_env.jj_cmd_failure(&workspace_root, &["git", "push", "--branch", "branch2"]);
|
|
|
|
insta::assert_snapshot!(stderr, @r###"
|
|
|
|
Error: Branch branch2 is conflicted
|
2023-10-16 19:25:52 +00:00
|
|
|
Hint: Run `jj branch list` to inspect, and use `jj branch set` to fix it up.
|
2023-07-03 09:03:07 +00:00
|
|
|
"###);
|
|
|
|
|
|
|
|
// --all shouldn't be blocked by conflicting branch
|
|
|
|
bump_branch1();
|
2023-07-03 08:52:31 +00:00
|
|
|
let (stdout, stderr) = test_env.jj_cmd_ok(&workspace_root, &["git", "push", "--all"]);
|
2023-10-10 11:07:06 +00:00
|
|
|
insta::assert_snapshot!(stdout, @"");
|
2023-07-03 08:52:31 +00:00
|
|
|
insta::assert_snapshot!(stderr, @r###"
|
|
|
|
Branch branch2 is conflicted
|
2023-10-16 19:25:52 +00:00
|
|
|
Hint: Run `jj branch list` to inspect, and use `jj branch set` to fix it up.
|
2023-10-10 11:07:06 +00:00
|
|
|
Branch changes to push to origin:
|
|
|
|
Move branch branch1 from 45a3aa29e907 to fd1d63e031ea
|
2023-07-03 08:52:31 +00:00
|
|
|
"###);
|
2023-07-03 09:03:07 +00:00
|
|
|
|
|
|
|
// --revisions shouldn't be blocked by conflicting branch
|
|
|
|
bump_branch1();
|
2023-07-03 08:52:31 +00:00
|
|
|
let (stdout, stderr) = test_env.jj_cmd_ok(&workspace_root, &["git", "push", "-rall()"]);
|
2023-10-10 11:07:06 +00:00
|
|
|
insta::assert_snapshot!(stdout, @"");
|
2023-07-03 08:52:31 +00:00
|
|
|
insta::assert_snapshot!(stderr, @r###"
|
|
|
|
Branch branch2 is conflicted
|
2023-10-16 19:25:52 +00:00
|
|
|
Hint: Run `jj branch list` to inspect, and use `jj branch set` to fix it up.
|
2023-10-10 11:07:06 +00:00
|
|
|
Branch changes to push to origin:
|
|
|
|
Move branch branch1 from fd1d63e031ea to 8263cf992d33
|
2023-07-03 08:52:31 +00:00
|
|
|
"###);
|
2023-07-03 09:03:07 +00:00
|
|
|
}
|
2023-10-14 20:11:19 +00:00
|
|
|
|
2023-10-14 14:54:35 +00:00
|
|
|
#[test]
|
|
|
|
fn test_git_push_deleted_untracked() {
|
|
|
|
let (test_env, workspace_root) = set_up();
|
|
|
|
|
|
|
|
// Absent local branch shouldn't be considered "deleted" compared to
|
|
|
|
// non-tracking remote branch.
|
|
|
|
test_env.jj_cmd_ok(&workspace_root, &["branch", "delete", "branch1"]);
|
|
|
|
test_env.jj_cmd_ok(&workspace_root, &["branch", "untrack", "branch1@origin"]);
|
|
|
|
let (_stdout, stderr) = test_env.jj_cmd_ok(&workspace_root, &["git", "push", "--deleted"]);
|
|
|
|
insta::assert_snapshot!(stderr, @r###"
|
|
|
|
Nothing changed.
|
|
|
|
"###);
|
|
|
|
let stderr = test_env.jj_cmd_failure(&workspace_root, &["git", "push", "--branch=branch1"]);
|
|
|
|
insta::assert_snapshot!(stderr, @r###"
|
2023-10-24 06:31:26 +00:00
|
|
|
Error: No such branch: branch1
|
2023-10-14 14:54:35 +00:00
|
|
|
"###);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_git_push_moved_forward_untracked() {
|
|
|
|
let (test_env, workspace_root) = set_up();
|
|
|
|
|
|
|
|
test_env.jj_cmd_ok(&workspace_root, &["new", "branch1", "-mmoved branch1"]);
|
|
|
|
test_env.jj_cmd_ok(&workspace_root, &["branch", "set", "branch1"]);
|
|
|
|
test_env.jj_cmd_ok(&workspace_root, &["branch", "untrack", "branch1@origin"]);
|
|
|
|
let (_stdout, stderr) = test_env.jj_cmd_ok(&workspace_root, &["git", "push"]);
|
|
|
|
insta::assert_snapshot!(stderr, @r###"
|
2023-10-15 17:43:45 +00:00
|
|
|
Non-tracking remote branch branch1@origin exists
|
2023-10-16 19:25:52 +00:00
|
|
|
Hint: Run `jj branch track branch1@origin` to import the remote branch.
|
2023-10-15 17:43:45 +00:00
|
|
|
Nothing changed.
|
2023-10-14 14:54:35 +00:00
|
|
|
"###);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_git_push_moved_sideways_untracked() {
|
|
|
|
let (test_env, workspace_root) = set_up();
|
|
|
|
|
|
|
|
test_env.jj_cmd_ok(&workspace_root, &["new", "root()", "-mmoved branch1"]);
|
|
|
|
test_env.jj_cmd_ok(
|
|
|
|
&workspace_root,
|
|
|
|
&["branch", "set", "--allow-backwards", "branch1"],
|
|
|
|
);
|
|
|
|
test_env.jj_cmd_ok(&workspace_root, &["branch", "untrack", "branch1@origin"]);
|
2023-10-15 17:43:45 +00:00
|
|
|
let (_stdout, stderr) = test_env.jj_cmd_ok(&workspace_root, &["git", "push"]);
|
2023-10-14 14:54:35 +00:00
|
|
|
insta::assert_snapshot!(stderr, @r###"
|
2023-10-15 17:43:45 +00:00
|
|
|
Non-tracking remote branch branch1@origin exists
|
2023-10-16 19:25:52 +00:00
|
|
|
Hint: Run `jj branch track branch1@origin` to import the remote branch.
|
2023-10-15 17:43:45 +00:00
|
|
|
Nothing changed.
|
2023-10-14 14:54:35 +00:00
|
|
|
"###);
|
|
|
|
}
|
|
|
|
|
2023-10-14 20:11:19 +00:00
|
|
|
#[test]
|
|
|
|
fn test_git_push_to_remote_named_git() {
|
|
|
|
let (test_env, workspace_root) = set_up();
|
|
|
|
let git_repo = {
|
|
|
|
let mut git_repo_path = workspace_root.clone();
|
|
|
|
git_repo_path.extend([".jj", "repo", "store", "git"]);
|
|
|
|
git2::Repository::open(&git_repo_path).unwrap()
|
|
|
|
};
|
|
|
|
git_repo.remote_rename("origin", "git").unwrap();
|
|
|
|
|
|
|
|
let stderr =
|
|
|
|
test_env.jj_cmd_failure(&workspace_root, &["git", "push", "--all", "--remote=git"]);
|
|
|
|
insta::assert_snapshot!(stderr, @r###"
|
|
|
|
Branch changes to push to git:
|
|
|
|
Add branch branch1 to 45a3aa29e907
|
|
|
|
Add branch branch2 to 8476341eb395
|
|
|
|
Error: Git remote named 'git' is reserved for local Git repository
|
|
|
|
"###);
|
|
|
|
}
|