Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cli: add jj operation show and jj operation diff commands #3617

Open
wants to merge 3 commits into
base: main
Choose a base branch
from

Conversation

bnjmnt4n
Copy link
Collaborator

@bnjmnt4n bnjmnt4n commented May 3, 2024

Checklist

If applicable:

  • I have updated CHANGELOG.md
  • I have updated the documentation (README.md, docs/, demos/)
  • I have updated the config schema (cli/src/config-schema.json)
  • I have added tests to cover my changes

@bnjmnt4n bnjmnt4n force-pushed the bnjmnt4n/push-uzynoulwtlvz branch 3 times, most recently from 7e11943 to eb59a88 Compare May 4, 2024 20:56
@bnjmnt4n bnjmnt4n changed the title cli: add jj operation diff command cli: add jj operation show and jj operation diff commands May 4, 2024
lib/src/revset_graph.rs Outdated Show resolved Hide resolved
@bnjmnt4n bnjmnt4n force-pushed the bnjmnt4n/push-uzynoulwtlvz branch from eb59a88 to c82584f Compare May 4, 2024 21:02
lib/src/revset_graph.rs Show resolved Hide resolved
lib/src/revset_graph.rs Outdated Show resolved Hide resolved
lib/src/revset_graph.rs Outdated Show resolved Hide resolved
@bnjmnt4n bnjmnt4n force-pushed the bnjmnt4n/push-uzynoulwtlvz branch 2 times, most recently from 7ae89e3 to c3343eb Compare May 6, 2024 11:24
@bnjmnt4n bnjmnt4n marked this pull request as ready for review May 6, 2024 11:25
@bnjmnt4n
Copy link
Collaborator Author

bnjmnt4n commented May 6, 2024

I'm not particularly sure what to test, any suggestions on test cases to add? Maybe some common operations like squash, rebase, git fetch and push?

@bnjmnt4n
Copy link
Collaborator Author

bnjmnt4n commented May 6, 2024

I'm also thinking that templates are a good idea, maybe something like ModifiedChange nodes and ModifiedBranch nodes if that makes sense? Although the commit summary is a good starting point, seeing things like hidden repeatedly on removed commits isn't particularly useful. I'm not sure if the branch status is useful as well since, it will also be shown in the modified branches section.

@joyously
Copy link

joyously commented May 6, 2024

I'm not particularly sure what to test, any suggestions on test cases to add? Maybe some common operations like squash, rebase, git fetch and push?

I think you need to exercise the code for each option that the command handles.
If you expect edge cases for different operations, test that. I expect undo to work the same as other commands, but a test should prove it. Maybe abandon or branch create would be good to test that not just the commits but the meta data of the operation is shown or diffed correctly.

@bnjmnt4n bnjmnt4n force-pushed the bnjmnt4n/push-uzynoulwtlvz branch from c3343eb to dbb9cec Compare May 15, 2024 01:44
@martinvonz
Copy link
Owner

@bnjmnt4n bnjmnt4n marked this pull request as ready for review 2 weeks ago

Sorry, I missed this event. GitHub doesn't send an email for it. I'll try to remember to review this later today.

@bnjmnt4n bnjmnt4n force-pushed the bnjmnt4n/push-uzynoulwtlvz branch from dbb9cec to 33ee8dd Compare May 18, 2024 18:29
@martinvonz
Copy link
Owner

I think this really should have some tests. I'll review the code now.

@bnjmnt4n
Copy link
Collaborator Author

I'll try to add some testcases when I have the time. Here's the list of operations I think we should test (feel free to suggest more):

  • new
  • abandon
  • squash
  • rebase
  • branch create
  • git fetch
  • git push
  • op undo
  • op restore

I'm not sure how to structure it though: I guess I should add a single test beginning from an empty repo for each of these operations?

Copy link
Collaborator

@yuja yuja left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems useful, but I haven't reviewed the last patch thoroughly. It's a bit hard to comment on the features without snapshot tests.

Missing,
Direct,
Indirect,
}

fn reachable_targets(edges: &[RevsetGraphEdge]) -> impl DoubleEndedIterator<Item = &CommitId> {
fn reachable_targets<N: Clone>(edges: &[GraphEdge<N>]) -> impl DoubleEndedIterator<Item = &N> {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: N: Clone isn't needed here

pub fn new(input: impl IntoIterator<Item = (CommitId, Vec<RevsetGraphEdge>)>) -> Self {
impl<N> ReverseGraphIterator<N>
where
N: Hash + Eq + PartialEq + Clone,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: PartialEq is implied by Eq
(two more places that can be simplified)

_ => None,
};
let op = op_walk::resolve_op_for_load(repo_loader, &args.operation)?;
let parent_op = merge_operations(repo_loader, command.settings(), op.parents())?;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we can simply error out if the operation is a merge?

Since operation can't be merged manually by user, auto-merge result would be identical to the merge operation.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here was the quick question I asked on Discord:

bnjmnt4n (04/05/2024 19:43)

What should jj op show with an operation with multiple parents be? Should it merge the parents and attempt to diff with the child? afaik the result of this diff would always be empty, but perhaps that might be different if there are operations which are manually merged?

banana (04/05/2024 20:06)

the operation log isn't really a general purpose tree, i think it would be ok to tailor the output to the assumption that the merges are ones created by jj merging op heads

Martin von Zweigbergk (04/05/2024 20:14)

What should jj op show with an operation with multiple parents be? Should it merge the parents and attempt to diff with the child? afaik the result of this diff would always be empty, but perhaps that might be different if there are operations which are manually merged?

I think so. That would be consistent with what we do for the commit log

I guess it's also possible for a user to manually merge operations using jj_lib, which is why it might be useful to diff with the merged operation parents.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, that's technically correct. I was just wondering how we can reduce the amount of the custom code. Maybe we can make RepoLoader::_resolve_op_heads() public in some form?

// Create a new transaction starting from `to_repo`.
let mut workspace_command =
command.for_loaded_repo(ui, command.load_workspace()?, to_repo.clone())?;
let mut tx = workspace_command.start_transaction();
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It might be better to use low-level repo.start_transaction(). WorkspaceCommandHelper assumes that the loaded repo is synchronized with the working copy, and things might get weird if we committed the transaction by mistake.

let mut tx = workspace_command.start_transaction();
// Merge index from `from_repo` to `to_repo`, so commits in `from_repo` are
// accessible.
tx.mut_repo().merge_index(from_repo);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps, we can use the current (head) repo.index()? It should contain all historical commits.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OTOH, doing it the current way means it works even if --from or --to point to an operation that was never "published" (made an op head).

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

doing it the current way means it works even if --from or --to point to an operation that was never "published" (made an op head).

I don't know if such functionality is needed, but there might be (current_repo, from_repo, to_repo) tuple instead of (from_repo, to_repo). The current_repo provides a context (or visible heads + index) where repo-level templates will be evaluated.

I'm not sure if current_repo should be selected by --at-op or --to, but jj op show doesn't need to merge indexes. jj op diff will have to merge if visible heads are controlled by --to, not by --at-op.

@bnjmnt4n
Copy link
Collaborator Author

Thanks for taking a look @yuja. I'll try to work on adding some tests to make it easier to see what the expected output is like, perhaps further reviews can be put on hold if you'd like.

I'm also thinking that templates are a good idea, maybe something like ModifiedChange nodes and ModifiedBranch nodes if that makes sense? Although the commit summary is a good starting point, seeing things like hidden repeatedly on removed commits isn't particularly useful. I'm not sure if the branch status is useful as well since, it will also be shown in the modified branches section.

I'd also like to see if there's any desire to change the output displayed.

@martinvonz
Copy link
Owner

I'll try to add some testcases when I have the time. Here's the list of operations I think we should test (feel free to suggest more):

  • new
  • abandon
  • squash
  • rebase
  • branch create
  • git fetch
  • git push

As @joyously said, it's probably best to instead focus on what the code does and the different cases it handles. For example, there's some logic for displaying how refs moved, so there should be some tests demonstrating that, and ideally some including conflicted refs. It doesn't matter which commands you use to create the refs, so use whatever is easiest for that (for creating conflicted branches, it's probably easiest to use jj branch set --at-op=...).

  • op undo
  • op restore

I don't think these two need to be tested. They don't do much you can't test by making the same changes explicitly.

I'm not sure how to structure it though: I guess I should add a single test beginning from an empty repo for each of these operations?

SGTM.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(If this makes your life easier): I would consider splitting this commit into a separate PR, finishing it up, and merging it, so that you don't have to worry about merge conflicts if somebody else edits the renamed files. At least, that's what I tend to do. (I'm assuming this is a good change on its own, @yuja can correct me if I'm wrong)

pub struct OperationShowArgs {
/// Show repository changes in this operation, compared to its parent(s)
#[arg(default_value = "@")]
operation: String,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've been using these (thank you!), but I always want to use --op instead of --operation. I think it'd be good to add an alias visible_alias="op" for --operation. (Also for op diff)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

6 participants