Keep upstream files on false rename/delete; add no-vendor go modules hook - #100
Keep upstream files on false rename/delete; add no-vendor go modules hook#100RadekManak wants to merge 2 commits into
Conversation
Raise cherry-pick rename similarity to find-renames=70 and only git-rm delete-shaped conflicts when the path is in the picked commit's no-rename diff-tree; otherwise restore from HEAD. Skip empty resolutions.
Provide _BUILTIN_/update_go_modules_no_vendor.sh for vendorless downstream repos: tidy/sync only, with README and tests.
|
[APPROVALNOTIFIER] This PR is APPROVED This pull-request has been approved by: RadekManak The full list of commands accepted by this bot can be found here. The pull request process is described here DetailsNeeds approval from an approver in each of these files:
Approvers can indicate their approval by writing |
WalkthroughThe PR updates cherry-pick rename handling and conflict recovery. It adds a post-rebase hook for Go repositories without a ChangesCherry-pick conflict handling
No-vendor Go module hook
Estimated code review effort: 3 (Moderate) | ~25 minutes Sequence Diagram(s)sequenceDiagram
participant RebaseHook
participant SourceBranch
participant GoToolchain
participant GitRepository
RebaseHook->>SourceBranch: restore Go module files
RebaseHook->>GoToolchain: run workspace sync or module tidy
GoToolchain-->>RebaseHook: return command result
RebaseHook->>GitRepository: stage and commit changes
Suggested reviewers: 🚥 Pre-merge checks | ✅ 11✅ Passed checks (11 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@rebasebot/bot.py`:
- Around line 404-417: Update _unescape_git_path to encode quoted Git path
content as UTF-8 instead of ASCII before unicode_escape decoding, preserving
literal non-ASCII characters when core.quotePath=false. Add a regression test
covering a quoted path containing non-ASCII characters and verify
_picked_commit_paths completes without raising.
In `@rebasebot/builtin-hooks/update_go_modules_no_vendor.sh`:
- Around line 14-16: Update the hook’s staging and commit guard to scope changes
to the affected go.mod, go.sum, go.work, and go.work.sum paths instead of the
full worktree. Check the scoped index after staging and commit only when those
files have changes, preserving unrelated modifications and avoiding empty
UPSTREAM commits. Add a regression test covering an unrelated worktree change.
🪄 Autofix
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository: openshift-eng/coderabbit/.coderabbit.yaml
Review profile: CHILL
Plan: Enterprise
Run ID: 39994a29-de0b-4846-b5bf-08135192c49d
📒 Files selected for processing (5)
README.mdrebasebot/bot.pyrebasebot/builtin-hooks/update_go_modules_no_vendor.shtests/test_bot.pytests/test_conflict_policy.py
| def _unescape_git_path(path: str) -> str: | ||
| """Decode a git C-quoted path from --name-only / status --porcelain output.""" | ||
| if path.startswith('"') and path.endswith('"'): | ||
| path = path[1:-1] | ||
| path = path.encode("ascii").decode("unicode_escape").encode("latin1").decode(git.compat.defenc) | ||
| return path | ||
|
|
||
|
|
||
| def _picked_commit_paths(gitwd: git.Repo, sha: str) -> set[str]: | ||
| """Return paths touched by sha with rename detection disabled.""" | ||
| output = gitwd.git.diff_tree("--no-renames", "--no-commit-id", "--name-only", "-r", sha) | ||
| return {_unescape_git_path(line) for line in output.splitlines() if line} | ||
|
|
||
|
|
There was a problem hiding this comment.
🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -eu
printf '%s\n' '--- relevant source ---'
sed -n '380,430p' rebasebot/bot.py
sed -n '680,730p' rebasebot/bot.py
printf '%s\n' '--- usages and tests ---'
rg -n --hidden --glob '!node_modules' '_unescape_git_path|_picked_commit_paths|quotePath|diff_tree|name-only|status --porcelain' .
printf '%s\n' '--- tracked files near tests ---'
git ls-files | rg '(^|/)(test|tests|spec|.*test.*|.*spec.*)' | head -100
printf '%s\n' '--- file metadata ---'
wc -l rebasebot/bot.pyRepository: openshift-eng/rebasebot
Length of output: 5584
🏁 Script executed:
#!/bin/bash
set -eu
sed -n '395,420p' rebasebot/bot.py
sed -n '690,722p' rebasebot/bot.py
rg -n --hidden --glob '!node_modules' '_unescape_git_path|_picked_commit_paths|quotePath|diff_tree|name-only|status --porcelain' .
python3 - <<'PY'
for value in ['"café file.txt"', r'"caf\303\251 file.txt"', r'"caf\351 file.txt"']:
print('input:', repr(value))
try:
result = value[1:-1].encode('ascii').decode('unicode_escape').encode('latin1').decode('utf-8')
print('ascii conversion result:', repr(result))
except Exception as exc:
print('ascii conversion error:', type(exc).__name__, str(exc))
try:
result = value[1:-1].encode('utf-8').decode('unicode_escape').encode('latin1').decode('utf-8')
print('utf8 conversion result:', repr(result))
except Exception as exc:
print('utf8 conversion error:', type(exc).__name__, str(exc))
PYRepository: openshift-eng/rebasebot
Length of output: 4090
Parse quoted Git paths without an ASCII-only conversion.
When core.quotePath=false, Git can emit quoted paths with literal non-ASCII characters. _unescape_git_path then raises UnicodeEncodeError and stops automatic conflict resolution. Use UTF-8 for the conversion and add a regression test for this configuration.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@rebasebot/bot.py` around lines 404 - 417, Update _unescape_git_path to encode
quoted Git path content as UTF-8 instead of ASCII before unicode_escape
decoding, preserving literal non-ASCII characters when core.quotePath=false. Add
a regression test covering a quoted path containing non-ASCII characters and
verify _picked_commit_paths completes without raising.
| if [[ -n $(git status --porcelain) ]]; then | ||
| git add -A | ||
| git commit "${author_flag[@]}" -q -m "UPSTREAM: <drop>: Updating go modules after an upstream rebase" |
There was a problem hiding this comment.
🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win
Stage only files owned by this hook.
git status --porcelain and git add -A use the full worktree. If unrelated files are modified or untracked, this hook commits them in the UPSTREAM commit. This can also create a commit when go mod tidy or go work sync made no change.
Stage only the affected go.mod, go.sum, go.work, and go.work.sum paths. Check the scoped index before committing. Add a regression test with an unrelated worktree change.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@rebasebot/builtin-hooks/update_go_modules_no_vendor.sh` around lines 14 - 16,
Update the hook’s staging and commit guard to scope changes to the affected
go.mod, go.sum, go.work, and go.work.sum paths instead of the full worktree.
Check the scoped index after staging and commit only when those files have
changes, preserving unrelated modifications and avoiding empty UPSTREAM commits.
Add a regression test covering an unrelated worktree change.
Summary
vendor/)._BUILTIN_/update_go_modules_no_vendor.shfor vendorless repos (tidy/sync only).Cause
Cherry-picking a mass delete (commonly
rm -r vendor) onto a newer upstream tip, git rename detection can treat unrelated new upstream files as renames of deleted vendor paths. Rebasebot then auto-resolved those UD/AU-style conflicts withgit rm.Consequence
Real upstream packages disappeared from the rebase branch. Post-rebase
go mod tidy(or builds) failed on missing in-repo imports—even though the picked commit never listed those paths. Vendorless downstreams were especially exposed.Fix
find-renames=70(keep highmerge.renameLimit).git rmonly if the path is indiff-tree --no-renames --name-only -r <picked-sha>; otherwise restore from HEAD and stage.cherry-pick --skip._BUILTIN_/update_go_modules_no_vendor.sh(tidy/sync, no vendor) for hermetic/vendorless consumers.Result
False rename/delete carries keep upstream files; intentional deletes still apply; empty vendor picks skip cleanly. Vendorless repos can tidy modules without recreating
vendor/. Verified on anmcp-lifecycle-operatordry-run rebase.Summary by CodeRabbit
New Features
Bug Fixes
Documentation
vendor/directory.Tests