forked from mirrors/jj
cli: search @- for branches to push when @ has none
This commit is contained in:
parent
b009019d8d
commit
305cb3a7ee
3 changed files with 59 additions and 15 deletions
|
@ -12,6 +12,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||||
* The new `jj git remote rename` command allows git remotes to be renamed
|
* The new `jj git remote rename` command allows git remotes to be renamed
|
||||||
in-place.
|
in-place.
|
||||||
|
|
||||||
|
* `jj git push` will search `@-` for branches to push if `@` has none.
|
||||||
|
|
||||||
## [0.5.1] - 2022-10-17
|
## [0.5.1] - 2022-10-17
|
||||||
|
|
||||||
No changes (just trying to get automated GitHub release to work).
|
No changes (just trying to get automated GitHub release to work).
|
||||||
|
|
|
@ -33,7 +33,7 @@ use jujutsu_lib::files::DiffLine;
|
||||||
use jujutsu_lib::git::{GitFetchError, GitRefUpdate};
|
use jujutsu_lib::git::{GitFetchError, GitRefUpdate};
|
||||||
use jujutsu_lib::index::IndexEntry;
|
use jujutsu_lib::index::IndexEntry;
|
||||||
use jujutsu_lib::matchers::{EverythingMatcher, Matcher};
|
use jujutsu_lib::matchers::{EverythingMatcher, Matcher};
|
||||||
use jujutsu_lib::op_store::{RefTarget, WorkspaceId};
|
use jujutsu_lib::op_store::{BranchTarget, RefTarget, WorkspaceId};
|
||||||
use jujutsu_lib::operation::Operation;
|
use jujutsu_lib::operation::Operation;
|
||||||
use jujutsu_lib::refs::{classify_branch_push_action, BranchPushAction, BranchPushUpdate};
|
use jujutsu_lib::refs::{classify_branch_push_action, BranchPushAction, BranchPushUpdate};
|
||||||
use jujutsu_lib::repo::{ReadonlyRepo, RepoRef};
|
use jujutsu_lib::repo::{ReadonlyRepo, RepoRef};
|
||||||
|
@ -899,9 +899,10 @@ struct GitCloneArgs {
|
||||||
|
|
||||||
/// Push to a Git remote
|
/// Push to a Git remote
|
||||||
///
|
///
|
||||||
/// By default, pushes any branches pointing to `@`. Use `--branch` to push a
|
/// By default, pushes any branches pointing to `@`, or `@-` if no branches
|
||||||
/// specific branch. Use `--all` to push all branches. Use `--change` to
|
/// point to `@`. Use `--branch` to push a specific branch. Use `--all` to push
|
||||||
/// generate a branch name based on a specific commit's change ID.
|
/// all branches. Use `--change` to generate a branch name based on a specific
|
||||||
|
/// commit's change ID.
|
||||||
#[derive(clap::Args, Clone, Debug)]
|
#[derive(clap::Args, Clone, Debug)]
|
||||||
#[command(group(ArgGroup::new("what").args(&["branch", "all", "change"])))]
|
#[command(group(ArgGroup::new("what").args(&["branch", "all", "change"])))]
|
||||||
struct GitPushArgs {
|
struct GitPushArgs {
|
||||||
|
@ -4239,17 +4240,41 @@ fn cmd_git_push(
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
Some(checkout) => {
|
Some(checkout) => {
|
||||||
let desired_target = Some(RefTarget::Normal(checkout.clone()));
|
fn find_branches_targeting<'a>(
|
||||||
for (branch_name, branch_target) in workspace_command.repo().view().branches() {
|
view: &'a View,
|
||||||
if branch_target.local_target == desired_target {
|
target: &RefTarget,
|
||||||
let push_action = classify_branch_push_action(branch_target, &args.remote);
|
) -> Vec<(&'a String, &'a BranchTarget)> {
|
||||||
match push_action {
|
view.branches()
|
||||||
BranchPushAction::AlreadyMatches => {}
|
.iter()
|
||||||
BranchPushAction::LocalConflicted => {}
|
.filter(|(_, branch_target)| {
|
||||||
BranchPushAction::RemoteConflicted => {}
|
branch_target.local_target.as_ref() == Some(target)
|
||||||
BranchPushAction::Update(update) => {
|
})
|
||||||
branch_updates.push((branch_name.clone(), update));
|
.collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Search for branches targeting @
|
||||||
|
let mut branches = find_branches_targeting(
|
||||||
|
workspace_command.repo().view(),
|
||||||
|
&RefTarget::Normal(checkout.clone()),
|
||||||
|
);
|
||||||
|
if branches.is_empty() {
|
||||||
|
// Try @- instead if it has exactly one parent, such as after `jj squash`
|
||||||
|
let commit = workspace_command.repo().store().get_commit(checkout)?;
|
||||||
|
if let [parent] = commit.parent_ids() {
|
||||||
|
branches = find_branches_targeting(
|
||||||
|
workspace_command.repo().view(),
|
||||||
|
&RefTarget::Normal(parent.clone()),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (branch_name, branch_target) in branches {
|
||||||
|
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));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -115,6 +115,23 @@ fn test_git_push_current_branch() {
|
||||||
"###);
|
"###);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_git_push_parent_branch() {
|
||||||
|
let (test_env, workspace_root) = set_up();
|
||||||
|
test_env.jj_cmd_success(&workspace_root, &["edit", "branch1"]);
|
||||||
|
test_env.jj_cmd_success(
|
||||||
|
&workspace_root,
|
||||||
|
&["describe", "-m", "modified branch1 commit"],
|
||||||
|
);
|
||||||
|
test_env.jj_cmd_success(&workspace_root, &["new"]);
|
||||||
|
let stdout = test_env.jj_cmd_success(&workspace_root, &["git", "push", "--dry-run"]);
|
||||||
|
insta::assert_snapshot!(stdout, @r###"
|
||||||
|
Branch changes to push to origin:
|
||||||
|
Force branch branch1 from a3ccc578ea7b to ad7201b22c46
|
||||||
|
Dry-run requested, not pushing.
|
||||||
|
"###);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_git_push_no_current_branch() {
|
fn test_git_push_no_current_branch() {
|
||||||
let (test_env, workspace_root) = set_up();
|
let (test_env, workspace_root) = set_up();
|
||||||
|
|
Loading…
Reference in a new issue