Fix push rules validation on initial push
What does this MR do and why?
Contributes to #356094 (closed)
Problem
Push rules validations for files don't work on the first push to the empty repository.
The root cause is a git diff-tree
behavior for an initial commit. It
returns an empty result if we provide a sha of the initial commit, but
it works correctly for all following commits.
Solution
Use tree ids to get the diff of the initial commit. Git has a special
empty tree id 4b825dc642cb6eb9a060e54bf8d69288fbee4904
that
corresponds to the empty repository state.
Instead of git diff-tree <commit_id>
we can request a diff between two
trees: git diff-tree <empty_tree_id> <commit_tree_id>
.
This approach returns a correct diff for the initial commit.
How to set up and validate locally
- Enable feature flag:
Feature.enable(:verify_push_rules_for_first_commit)
- Create an empty project (with empty repository)
- Go to Project Settings -> Repository -> Push Rules
- Enable "Prevent pushing secret files"
Then clone empty project, create file id_rsa
, create a commit and push changes.
git clone ssh://git@gdk.test:2222/root/empty-repo.git
cd empty-repo
touch id_rsa
git add .
git commit -am 'Test'
git push
You should see a rejected message
remote: GitLab: File name id_rsa was prohibited by the pattern "id_rsa$".
To ssh://gdk.test:2222/root/empty-repo.git
! [remote rejected] main -> main (pre-receive hook declined)
error: failed to push some refs to 'ssh://gdk.test:2222/root/empty-repo.git'
When feature flag is disabled, it allows to push the restricted file.
Writing objects: 100% (3/3), 230 bytes | 230.00 KiB/s, done.
Total 3 (delta 0), reused 0 (delta 0), pack-reused 0
To ssh://gdk.test:2222/root/empty-repo.git
* [new branch] main -> main
Numbered steps to set up and validate the change are strongly suggested.
MR acceptance checklist
This checklist encourages us to confirm any changes have been analyzed to reduce risks in quality, performance, reliability, security, and maintainability.
-
I have evaluated the MR acceptance checklist for this MR.