Shorten the git push branch when possible using the short change ID hash.

This commit is contained in:
Vamsi Avula 2023-01-12 00:00:31 +05:30 committed by Vamsi Avula
parent ba7016788f
commit 1aad250420
3 changed files with 64 additions and 15 deletions

View file

@ -27,7 +27,7 @@ use clap::builder::{NonEmptyStringValueParser, TypedValueParser, ValueParserFact
use clap::{Arg, ArgAction, ArgMatches, Command, Error, FromArgMatches};
use git2::{Oid, Repository};
use itertools::Itertools;
use jujutsu_lib::backend::{BackendError, CommitId, ObjectId, TreeId};
use jujutsu_lib::backend::{BackendError, ChangeId, CommitId, ObjectId, TreeId};
use jujutsu_lib::commit::Commit;
use jujutsu_lib::git::{GitExportError, GitImportError};
use jujutsu_lib::gitignore::GitIgnoreFile;
@ -1385,6 +1385,10 @@ pub fn short_commit_hash(commit_id: &CommitId) -> String {
commit_id.hex()[0..12].to_string()
}
pub fn short_change_hash(change_id: &ChangeId) -> String {
change_id.hex()[0..12].to_string()
}
pub fn short_operation_hash(operation_id: &OperationId) -> String {
operation_id.hex()[0..12].to_string()
}

View file

@ -51,7 +51,7 @@ use pest::Parser;
use crate::cli_util::{
self, check_stale_working_copy, print_checkout_stats, print_failed_git_export,
resolve_base_revs, short_commit_description, short_commit_hash, user_error,
resolve_base_revs, short_change_hash, short_commit_description, short_commit_hash, user_error,
user_error_with_hint, write_commit_summary, write_config_entry, Args, CommandError,
CommandHelper, DescriptionArg, RevisionArg, WorkspaceCommandHelper,
};
@ -4179,7 +4179,7 @@ fn cmd_git_push(
&args.remote
));
for (change_str, commit) in std::iter::zip(args.change.iter(), commits) {
let branch_name = format!(
let mut branch_name = format!(
"{}{}",
command.settings().push_branch_prefix(),
commit.change_id().hex()
@ -4193,12 +4193,39 @@ fn cmd_git_push(
.get_local_branch(&branch_name)
.is_none()
{
writeln!(
ui,
"Creating branch {} for revision {}",
branch_name,
change_str.deref()
)?;
// A local branch with the full change ID doesn't exist already, so use the
// short ID if it's not ambiguous (which it shouldn't be most of the time).
let short_change_id = short_change_hash(commit.change_id());
let new_branch_name = match workspace_command.resolve_single_rev(&short_change_id) {
Ok(_) => {
// Short change ID is not ambiguous but we do need to check if
// a branch already exists with the short ID.
branch_name = format!(
"{}{}",
command.settings().push_branch_prefix(),
short_change_id
);
if workspace_command
.repo()
.view()
.get_local_branch(&branch_name)
.is_none()
{
Some(&branch_name)
} else {
None
}
}
Err(_) => Some(&branch_name),
};
if let Some(branch_name) = new_branch_name {
writeln!(
ui,
"Creating branch {} for revision {}",
branch_name,
change_str.deref()
)?;
}
}
tx.mut_repo()
.set_local_branch(branch_name.clone(), RefTarget::Normal(commit.id().clone()));

View file

@ -211,9 +211,9 @@ fn test_git_push_changes() {
let stdout = test_env.jj_cmd_success(&workspace_root, &["git", "push", "--change", "@"]);
insta::assert_snapshot!(stdout, @r###"
Creating branch push-1b76972398e6449e8e0701307e57d55a for revision @
Creating branch push-1b76972398e6 for revision @
Branch changes to push to origin:
Add branch push-1b76972398e6449e8e0701307e57d55a to 28d7620ea63a
Add branch push-1b76972398e6 to 28d7620ea63a
"###);
// test pushing two changes at once
std::fs::write(workspace_root.join("file"), "modified2").unwrap();
@ -222,10 +222,10 @@ fn test_git_push_changes() {
&["git", "push", "--change", "@", "--change", "@-"],
);
insta::assert_snapshot!(stdout, @r###"
Creating branch push-19b790168e7347a7ba98deae21e807c0 for revision @-
Creating branch push-19b790168e73 for revision @-
Branch changes to push to origin:
Force branch push-1b76972398e6449e8e0701307e57d55a from 28d7620ea63a to 48d8c7948133
Add branch push-19b790168e7347a7ba98deae21e807c0 to fa16a14170fb
Force branch push-1b76972398e6 from 28d7620ea63a to 48d8c7948133
Add branch push-19b790168e73 to fa16a14170fb
"###);
// specifying the same change twice doesn't break things
std::fs::write(workspace_root.join("file"), "modified3").unwrap();
@ -235,7 +235,25 @@ fn test_git_push_changes() {
);
insta::assert_snapshot!(stdout, @r###"
Branch changes to push to origin:
Force branch push-1b76972398e6449e8e0701307e57d55a from 48d8c7948133 to b5f030322b1d
Force branch push-1b76972398e6 from 48d8c7948133 to b5f030322b1d
"###);
}
#[test]
fn test_git_push_existing_long_branch() {
let (test_env, workspace_root) = set_up();
test_env.jj_cmd_success(&workspace_root, &["describe", "-m", "foo"]);
std::fs::write(workspace_root.join("file"), "contents").unwrap();
test_env.jj_cmd_success(
&workspace_root,
&["branch", "create", "push-19b790168e7347a7ba98deae21e807c0"],
);
let stdout = test_env.jj_cmd_success(&workspace_root, &["git", "push", "--change=@"]);
insta::assert_snapshot!(stdout, @r###"
Branch changes to push to origin:
Add branch push-19b790168e7347a7ba98deae21e807c0 to fa16a14170fb
"###);
}