Skip to content

Commit

Permalink
cli: push only branches pointing to @ by default
Browse files Browse the repository at this point in the history
Since we now allow pushing open commits, we can implement support for
pushing the "current" branch by defining a "current" branch as any
branch pointing to `@`. That definition of a current/active seems to
have been the consensus in discussion #411.

Closes #246.
  • Loading branch information
martinvonz committed Jul 13, 2022
1 parent f2de0c5 commit 1269172
Show file tree
Hide file tree
Showing 3 changed files with 92 additions and 7 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
* `jj git push` no longer aborts if you attempt to push an open commit (but it
now aborts if a commit does not have a description).

* `jj git push` now pushes only branches pointing to the `@` by default. Use
`--all` to push all branches.

### New features

* `jj rebase` now accepts a `--branch/-b <revision>` argument, which can be used
Expand Down
41 changes: 38 additions & 3 deletions src/commands.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1858,16 +1858,21 @@ struct GitCloneArgs {

/// Push to a Git remote
///
/// By default, all branches are pushed. Use `--branch` if you want to push only
/// one branch.
/// By default, pushes any branches pointing to `@`. Use `--branch` to push a
/// specific branch. Use `--all` to push all branches. Use `--change` to
/// generate a branch name based on a specific commit's change ID.
#[derive(clap::Args, Clone, Debug)]
#[clap(group(ArgGroup::new("what").args(&["branch", "all", "change"])))]
struct GitPushArgs {
/// The remote to push to (only named remotes are supported)
#[clap(long, default_value = "origin")]
remote: String,
/// Push only this branch
#[clap(long)]
branch: Option<String>,
/// Push all branches
#[clap(long)]
all: bool,
/// Push this commit by creating a branch based on its change ID
#[clap(long)]
change: Option<String>,
Expand Down Expand Up @@ -5123,7 +5128,7 @@ fn cmd_git_push(
branch_name, &args.remote, branch_name
)?;
}
} else {
} else if args.all {
// TODO: Is it useful to warn about conflicted branches?
for (branch_name, branch_target) in workspace_command.repo().view().branches() {
let push_action = classify_branch_push_action(branch_target, &args.remote);
Expand All @@ -5138,6 +5143,36 @@ fn cmd_git_push(
}
tx = workspace_command
.start_transaction(&format!("push all branches to git remote {}", &args.remote));
} else {
match workspace_command
.repo()
.view()
.get_checkout(&workspace_command.workspace_id())
{
None => {
return Err(UserError("No current branch.".to_string()));
}
Some(checkout) => {
let desired_target = Some(RefTarget::Normal(checkout.clone()));
for (branch_name, branch_target) in workspace_command.repo().view().branches() {
if branch_target.local_target == desired_target {
let push_action = classify_branch_push_action(branch_target, &args.remote);
match push_action {
BranchPushAction::AlreadyMatches => {}
BranchPushAction::LocalConflicted => {}
BranchPushAction::RemoteConflicted => {}
BranchPushAction::Update(update) => {
branch_updates.push((branch_name.clone(), update));
}
}
}
}
}
}
tx = workspace_command.start_transaction(&format!(
"push current branch(es) to git remote {}",
&args.remote
));
}

if branch_updates.is_empty() {
Expand Down
55 changes: 51 additions & 4 deletions tests/test_git_push.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,54 @@ fn test_git_push_nothing() {
}

#[test]
fn test_git_push_success() {
fn test_git_push_current() {
let (test_env, workspace_root) = set_up();
// Update some branches. `branch1` is not a current branch, but `branch2` and
// `my-branch` are.
test_env.jj_cmd_success(
&workspace_root,
&["describe", "branch1", "-m", "modified branch1 commit"],
);
test_env.jj_cmd_success(
&workspace_root,
&["branch", "set", "--allow-backwards", "branch2"],
);
test_env.jj_cmd_success(&workspace_root, &["branch", "create", "my-branch"]);
test_env.jj_cmd_success(&workspace_root, &["describe", "-m", "foo"]);
// Check the setup
let stdout = test_env.jj_cmd_success(&workspace_root, &["branch", "list"]);
insta::assert_snapshot!(stdout, @r###"
branch1: 5d0d85ed3da7 modified branch1 commit
@origin (ahead by 1 commits, behind by 1 commits): 545acdb23f70 description
branch2: 7840c9885676 foo
@origin (ahead by 1 commits, behind by 1 commits): 545acdb23f70 description
my-branch: 7840c9885676 foo
"###);
// First dry-run. `branch1` should not get pushed.
let stdout = test_env.jj_cmd_success(&workspace_root, &["git", "push", "--dry-run"]);
insta::assert_snapshot!(stdout, @r###"
Branch changes to push to origin:
Move branch branch2 from 545acdb23f70 to 7840c9885676
Add branch my-branch to 7840c9885676
Dry-run requested, not pushing.
"###);
let stdout = test_env.jj_cmd_success(&workspace_root, &["git", "push"]);
insta::assert_snapshot!(stdout, @r###"
Branch changes to push to origin:
Move branch branch2 from 545acdb23f70 to 7840c9885676
Add branch my-branch to 7840c9885676
"###);
let stdout = test_env.jj_cmd_success(&workspace_root, &["branch", "list"]);
insta::assert_snapshot!(stdout, @r###"
branch1: 5d0d85ed3da7 modified branch1 commit
@origin (ahead by 1 commits, behind by 1 commits): 545acdb23f70 description
branch2: 7840c9885676 foo
my-branch: 7840c9885676 foo
"###);
}

#[test]
fn test_git_push_all() {
let (test_env, workspace_root) = set_up();
test_env.jj_cmd_success(&workspace_root, &["branch", "delete", "branch1"]);
test_env.jj_cmd_success(
Expand All @@ -90,15 +137,15 @@ fn test_git_push_success() {
my-branch: 7840c9885676 foo
"###);
// First dry-run
let stdout = test_env.jj_cmd_success(&workspace_root, &["git", "push", "--dry-run"]);
let stdout = test_env.jj_cmd_success(&workspace_root, &["git", "push", "--all", "--dry-run"]);
insta::assert_snapshot!(stdout, @r###"
Branch changes to push to origin:
Delete branch branch1 from 545acdb23f70
Move branch branch2 from 545acdb23f70 to 7840c9885676
Add branch my-branch to 7840c9885676
Dry-run requested, not pushing.
"###);
let stdout = test_env.jj_cmd_success(&workspace_root, &["git", "push"]);
let stdout = test_env.jj_cmd_success(&workspace_root, &["git", "push", "--all"]);
insta::assert_snapshot!(stdout, @r###"
Branch changes to push to origin:
Delete branch branch1 from 545acdb23f70
Expand Down Expand Up @@ -133,7 +180,7 @@ fn test_git_push_conflict() {
test_env.jj_cmd_success(&workspace_root, &["rebase", "-r", "@", "-d", "@--"]);
test_env.jj_cmd_success(&workspace_root, &["branch", "set", "my-branch"]);
test_env.jj_cmd_success(&workspace_root, &["close", "-m", "third"]);
let stderr = test_env.jj_cmd_failure(&workspace_root, &["git", "push"]);
let stderr = test_env.jj_cmd_failure(&workspace_root, &["git", "push", "--all"]);
insta::assert_snapshot!(stderr, @r###"
Error: Won't push commit 50ccff1aeab0 since it has conflicts
"###);
Expand Down

0 comments on commit 1269172

Please sign in to comment.