-
-
Notifications
You must be signed in to change notification settings - Fork 14.3k
Tweak "conflict markers" diagnostic by detecting git state #150233
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
base: main
Are you sure you want to change the base?
Conversation
|
rustbot has assigned @petrochenkov. Use |
c38cd37 to
8e52082
Compare
| format!("code you had in commit `{orig_head_sha}` that you are rebasing"); | ||
| } | ||
| if let Ok(output) = | ||
| Command::new("git").args(["branch", "--points-at", onto_sha.trim()]).output() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Both calls to git branch --points-at (locals only and remotes) will incur a linear cost on the number of branches that exist in the repo. This can be a problem as there are some projects with lots of branches. We have the time cost of filtering them and the potential of lots branches pointing to the same tip, which is handled somewhat already.
The decision on whether the risk is acceptable, or we should not even try, is one I am flip-flopping and keep arguing with myself.
I reached out to the git mailing list to see if they could add the equivalent of branch-name so that this is unnecessary.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changed to work only if the current directory cargo was invoked from is the root git repo and git has a default path configuration.
This comment has been minimized.
This comment has been minimized.
| // conflict might not have been caused by a git rebase, and we'll fall-back on the default | ||
| // diagnostic. | ||
| let git = |path: &str| { | ||
| std::fs::read_to_string(format!(".git/{path}")) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
now this is definitely broken, certainly on worktrees and submodules and likely in other cases too. the fallback is to just not emit the diagnostic, which is ok i guess, but it will make UI tests very fragile and generally i don’t think this behaves how you expect.
i would rather you run git —rev-parse tbh.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i would rather you run git —rev-parse tbh
I'll look into potentially using the appropriate sub-crate from gitoxide for this (if not just taking the appropriate logic), given how unlikely it will be for people to accept us shelling out to git.
Edit: it looks like it'd be https://crates.io/crates/gix-discover.
Edit 2: the list of new deps this would add is not ideal:
byteorder@1.5.0
gix-actor@0.36.1
gix-hashtable@0.11.0
gix-date@0.11.1
same-file@1.0.6
dunce@1.0.5
hash32@0.3.1
gix-object@0.53.0
gix-lock@20.0.0
walkdir@2.5.0
gix-utils@0.3.1
winapi-util@0.1.11
jiff-tzdb-platform@0.1.3
gix-validate@0.10.1
gix-trace@0.1.16
winnow@0.7.14
gix-fs@0.18.0
sha1-checked@0.10.0
prodash@30.0.1
gix-discover@0.44.0
faster-hex@0.10.0
gix-ref@0.56.0
gix-features@0.45.0
heapless@0.8.0
jiff-tzdb@0.1.5
gix-hash@0.21.0
gix-path@0.10.22
gix-sec@0.12.2
gix-tempfile@20.0.0
When detecting "diff markers", inspect the current `git` repo's state to see if there is an active rebase. If that is the case, we try to identify whether the rebase is caused by `git rebase` or implicitly by `git pull`. In order to do that we query `git` to ask for the path of `.git/rebase-merge` and then inspect the files `orig-head` (the commit we are rebasing from), `onto` (the commit we are rebasing onto) and `head-name` (the branch being rebased). We modify the labels pointing at the markers to be clear on where each section of code is coming from.
`git rebase` case:
```
error: encountered diff marker
--> src/main.rs:2:1
|
2 | <<<<<<< HEAD
| ^^^^^^^ between this marker and `=======` is the code from branch `master` we're rebasing onto
3 | println!("Hello, main!");
4 | =======
| ------- between this marker and `>>>>>>>` is the code you had in branch `branch-2` that you are rebasing
5 | println!("Hello, branch!");
6 | >>>>>>> e644375 (branch)
| ^^^^^^^ this marker concludes the conflict region
|
= note: conflict markers indicate that a merge was started but could not be completed due to merge conflicts
to resolve a conflict, keep only the code you want and then delete the lines containing conflict markers
= note: for an explanation on these markers from the `git` documentation:
visit <https://git-scm.com/book/en/v2/Git-Tools-Advanced-Merging#_checking_out_conflicts>
```
`git pull` case:
```
error: encountered diff marker
--> src/main.rs:2:1
|
2 | <<<<<<< HEAD
| ^^^^^^^ between this marker and `=======` is the code from the remote branch `origin/main` we're rebasing onto
3 | println!("Hello, 1!");
4 | =======
| ------- between this marker and `>>>>>>>` is the code you had in branch `main` that you are rebasing
5 | println!("Hello, 2!");
6 | >>>>>>> ebbeec7 (second)
| ^^^^^^^ this marker concludes the conflict region
|
= note: conflict markers indicate that a merge was started but could not be completed due to merge conflicts
to resolve a conflict, keep only the code you want and then delete the lines containing conflict markers
= note: for an explanation on these markers from the `git` documentation:
visit <https://git-scm.com/book/en/v2/Git-Tools-Advanced-Merging#_checking_out_conflicts>
```
Also, the generic `help` description had the `git pull` case flipped from what it should have been.
The logic now only works if `cargo` is called from the git root, otherwise it won't find where the git metadata is. We rely purely on inspecting the files with rebase metadata and don't attempt to resolve a rebase target SHA to a branch name. Reword slightly the labels.
d84c2d6 to
7deca7a
Compare
|
This PR was rebased onto a different main commit. Here's a range-diff highlighting what actually changed. Rebasing is a normal part of keeping PRs up to date, so no action is needed—this note is just to help reviewers. |
|
☔ The latest upstream changes (presumably #150575) made this pull request unmergeable. Please resolve the merge conflicts. |
|
☔ The latest upstream changes made this pull request unmergeable. Please resolve the merge conflicts. |



When detecting "diff markers", inspect the current
gitrepo's state to see if there is an active rebase. If that is the case, we try to identify whether the rebase is caused bygit rebaseor implicitly bygit pull. In order to do that we querygitto ask for the path of.git/rebase-mergeand then inspect the filesorig-head(the commit we are rebasing from),onto(the commit we are rebasing onto) andhead-name(the branch being rebased). We modify the labels pointing at the markers to be clear on where each section of code is coming from.git rebasecase:git mergecase:git pull --rebasecase:git pull --no-rebasecase:Also, the generic
helpdescription is now removed.