You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
This repository was archived by the owner on Mar 27, 2026. It is now read-only.
Copy file name to clipboardExpand all lines: README.md
+21-6Lines changed: 21 additions & 6 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -40,14 +40,28 @@ The compiled binary will be available at `target/release/repodiff.exe` (Windows)
40
40
41
41
## Usage
42
42
43
-
### Compare Latest Commit with Another Branch
43
+
### Compare Branches
44
44
45
-
To compare the latest commit in the current branch with the latest common commit in another branch:
45
+
To compare the latest commit on the current branch (`HEAD`) with the latest commit on another branch (`<target_branch>`):
46
46
47
47
```bash
48
-
repodiff -b main -o output.txt
48
+
# Default: Compare HEAD with <target_branch>'s HEAD
49
+
repodiff -b <target_branch> -o output.txt
49
50
```
50
51
52
+
This shows all changes on the current branch since it diverged from the target branch, *plus* any changes that occurred on the target branch after the divergence point.
53
+
54
+
To compare the latest commit on the current branch (`HEAD`) with the *common ancestor* (merge-base) commit between the current branch and the target branch:
55
+
56
+
```bash
57
+
# Use --merge-base: Compare HEAD with the merge-base of HEAD and <target_branch>
This is often more useful for reviewing changes specific to the current branch, as it excludes changes made on the target branch after the branches diverged.
64
+
51
65
### Compare Two Specific Commits
52
66
53
67
To compare a specific commit with an earlier commit:
*`-b`, `--branch`: Branch to compare the current branch's latest commit against (finds the common ancestor).
69
-
*`-c`, `--commit`: The newer commit hash to include in the comparison.
82
+
*`-b`, `--branch <target_branch>`: Specify the target branch for comparison. By default, compares the current branch's `HEAD` with the `<target_branch>`'s `HEAD`. Use with `--merge-base` to compare against the common ancestor instead.
83
+
*`-a`, `--merge-base`: When used with `-b`, compare the current branch's `HEAD` against the common ancestor (merge-base) commit of the current branch and the `<target_branch>`, instead of the `<target_branch>`'s `HEAD`.
84
+
*`-c`, `--commit <commit_hash>`: The newer commit hash to include in the comparison.
70
85
*`-p`, `--previous [PREVIOUS_COMMIT_HASH]`: Compare the commit specified by `-c` with a previous commit. If `PREVIOUS_COMMIT_HASH` is provided, compare against that specific hash. If omitted, compare against the parent of the commit specified by `-c`.
71
-
*`-o`, `--output_file`: (Optional) Path to the output file. If not provided, the diff will be written to `repodiff_output.txt` in the current directory.
86
+
*`-o`, `--output_file <path>`: (Optional) Path to the output file. If not provided, the diff will be written to `repodiff_output.txt` in the current directory.
72
87
*`-v`, `--version`: Display the current version of RepoDiff
if args.branch.is_none() && args.commit.is_none(){
51
+
eprintln!("You must specify either a branch to compare (--branch [-a]) or a commit to compare (--commit -p).");
52
+
process::exit(1);
53
+
}
54
+
if args.commit.is_some() && args.previous.is_none(){
55
+
// This specific combination (--commit without --previous) is invalid
56
+
eprintln!("Missing comparison target. Use --previous (-p) to compare with a parent or specific commit when using --commit, or use --branch (-b) to compare with another branch.");
57
+
process::exit(1);
58
+
}
59
+
60
+
// Determine the commit hashes based on validated arguments
let commit1 = git_ops.get_latest_common_commit_with_branch(&branch)?;
43
-
let commit2 = git_ops.get_latest_commit()?;
44
-
45
-
println!(
46
-
"Comparing latest common commit with branch '{}' ({}) and the latest commit on the current branch ({}).",
47
-
branch,
48
-
&commit1[..12.min(commit1.len())],
49
-
&commit2[..12.min(commit2.len())]
50
-
);
51
-
(commit1, commit2)
63
+
let head_commit = git_ops.get_latest_commit()?;
52
64
53
-
}elseifletSome(commit_to_compare) = args.commit{
54
-
// Commit comparison logic (using --commit and --previous)
55
-
match args.previous{
56
-
Some(Some(prev_commit_hash)) => {
65
+
if args.merge_base{
66
+
// Compare HEAD with merge-base
67
+
let base_commit = git_ops.find_merge_base(&branch)?;
68
+
println!(
69
+
"Comparing merge-base with branch '{}' ({}) and current HEAD ({}).",
70
+
branch,
71
+
short_hash(&base_commit),
72
+
short_hash(&head_commit)
73
+
);
74
+
(base_commit, head_commit)
75
+
}else{
76
+
// Compare HEAD with target branch HEAD
77
+
let branch_head_commit = git_ops.get_branch_head(&branch)?;
78
+
println!(
79
+
"Comparing target branch '{}' HEAD ({}) and current HEAD ({}).",
80
+
branch,
81
+
short_hash(&branch_head_commit),
82
+
short_hash(&head_commit)
83
+
);
84
+
(branch_head_commit, head_commit)
85
+
}
86
+
}else{
87
+
// Commit comparison logic (--commit is guaranteed to be Some here,
88
+
// and --previous is also guaranteed to be Some due to the check above)
89
+
let commit_to_compare = args.commit.unwrap();// Safe due to initial check
90
+
match args.previous.unwrap(){// Safe due to initial check
91
+
Some(prev_commit_hash) => {
57
92
// -p <hash> provided: Compare commit_to_compare with prev_commit_hash
58
-
let commit1 = prev_commit_hash;
59
-
let commit2 = commit_to_compare;
60
93
println!(
61
94
"Comparing specified commit {} with previous commit {}.",
62
-
&commit2[..12.min(commit2.len())],
63
-
&commit1[..12.min(commit1.len())]
95
+
short_hash(&commit_to_compare),
96
+
short_hash(&prev_commit_hash)
64
97
);
65
-
(commit1, commit2)
98
+
(prev_commit_hash, commit_to_compare)
66
99
}
67
-
Some(None) => {
100
+
None => {
68
101
// -p flag provided without value: Compare commit_to_compare with its parent
69
-
let commit2 = commit_to_compare;
70
-
let commit1 = git_ops.get_previous_commit(&commit2)?;
102
+
let parent_commit = git_ops.get_previous_commit(&commit_to_compare)?;
71
103
println!(
72
104
"Comparing specified commit {} with its parent commit {}.",
73
-
&commit2[..12.min(commit2.len())],
74
-
&commit1[..12.min(commit1.len())]
105
+
short_hash(&commit_to_compare),
106
+
short_hash(&parent_commit)
75
107
);
76
-
(commit1, commit2)
77
-
}
78
-
None => {
79
-
// Only -c provided, which is not enough for comparison.
80
-
eprintln!("Missing comparison target. Use --previous (-p) to compare with a parent or specific commit when using --commit, or use --branch (-b) to compare with another branch.");
81
-
process::exit(1);
108
+
(parent_commit, commit_to_compare)
82
109
}
83
110
}
84
-
}else{
85
-
// Neither --branch nor --commit specified.
86
-
eprintln!("You must specify either a branch to compare (--branch) or a commit to compare (--commit) along with a comparison target (--previous).");
let output = run_repodiff(&["-b","main"],&repo.dir.path().to_path_buf())?;
115
+
116
+
let expected_output = format!(
117
+
"Comparing target branch 'main' HEAD ({}) and current HEAD ({})",
118
+
short_hash(&repo.main_head),
119
+
short_hash(&repo.feature_head)
120
+
);
121
+
122
+
assert!(output.contains(&expected_output),"Output did not contain expected branch head comparison message.\nExpected: {}\nGot: {}", expected_output, output);
123
+
assert!(repo.dir.path().join("repodiff_output.txt").exists(),"Output file was not created.");
0 commit comments