-
Notifications
You must be signed in to change notification settings - Fork 34
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
git_push()
silently succeeds with protected branches, expecting failure
#236
Comments
Is this something that can be done with libgit2? https://libgit2.org/libgit2/#HEAD/search |
Pushing a conflicting commit fails, but not with the technology GitHub uses (perhaps some hook on the remote repo?). # Demo for failing push with conflicts
system("git init --bare remote-repo")
system("git clone remote-repo local-repo")
system("git -C local-repo commit --allow-empty -m 'Initial commit'")
system("git -C local-repo push")
system("git clone remote-repo local-repo2")
writeLines("This is a test file", "local-repo/test.txt")
system("git -C local-repo add test.txt")
system("git -C local-repo commit -m 'Add test file'")
system("git -C local-repo push")
writeLines("This is a conflicting test file", "local-repo2/test.txt")
system("git -C local-repo2 add test.txt")
system("git -C local-repo2 commit -m 'Add conflicting test file'")
# Fails
system("git -C local-repo2 push", intern = TRUE)
#> Warning in system("git -C local-repo2 push", intern = TRUE): running command
#> 'git -C local-repo2 push' had status 1
#> character(0)
#> attr(,"status")
#> [1] 1
# Fails too
withr::with_dir("local-repo2", gert::git_push())
#> Error in libgit2::git_remote_push: cannot push because a reference that you are trying to update on the remote contains commits that are not present locally. Created on 2024-08-18 with reprex v2.1.0 |
I don't know too much about libgit2 to be helpful here, but could the above example be extended by such a hook in the remote repo? |
Perhaps "Server-side hooks" in https://git-scm.com/book/en/v2/Customizing-Git-Git-Hooks ? |
It's interesting that I can't even create an example with gert and hooks, these seem to be circumvented: # Demo for failing push with conflicts
unlink("remote-repo", recursive = TRUE, force = TRUE)
unlink("local-repo", recursive = TRUE, force = TRUE)
run <- function(cmd, args) {
invisible(processx::run(cmd, args, echo = TRUE))
}
run("git", c("init", "--bare", "remote-repo"))
#> Initialized empty Git repository in /private/var/folders/dj/yhk9rkx97wn_ykqtnmk18xvc0000gn/T/RtmpnNkFOo/reprex-c4aa7a5fbe6e-stout-scaup/remote-repo/
run("git", c("clone", "remote-repo", "local-repo"))
#> Cloning into 'local-repo'...
#> warning: You appear to have cloned an empty repository.
#> done.
run("git", c("-C", "local-repo", "commit", "--allow-empty", "-m", "Initial commit"))
#> [main (root-commit) 4cfc8d2] Initial commit
run("git", c("-C", "local-repo", "push", "-u", "origin", "HEAD"))
#> To /private/var/folders/dj/yhk9rkx97wn_ykqtnmk18xvc0000gn/T/RtmpnNkFOo/reprex-c4aa7a5fbe6e-stout-scaup/remote-repo
#> * [new branch] HEAD -> main
#> branch 'main' set up to track 'origin/main'.
writeLines(c("#!/bin/sh", "exit 1"), "remote-repo/hooks/update")
Sys.chmod("remote-repo/hooks/update", mode = as.octmode("755"))
writeLines("This is a test file", "local-repo/test.txt")
run("git", c("-C", "local-repo", "add", "test.txt"))
run("git", c("-C", "local-repo", "commit", "-m", "Add test file"))
#> [main d37ccf9] Add test file
#> 1 file changed, 1 insertion(+)
#> create mode 100644 test.txt
# Fails as expected
run("git", c("-C", "local-repo", "push"))
#> remote: error: hook declined to update refs/heads/main
#> To /private/var/folders/dj/yhk9rkx97wn_ykqtnmk18xvc0000gn/T/RtmpnNkFOo/reprex-c4aa7a5fbe6e-stout-scaup/remote-repo
#> ! [remote rejected] main -> main (hook declined)
#> error: failed to push some refs to '/private/var/folders/dj/yhk9rkx97wn_ykqtnmk18xvc0000gn/T/RtmpnNkFOo/reprex-c4aa7a5fbe6e-stout-scaup/remote-repo'
#> Error in "processx::run(cmd, args, echo = TRUE)": ! System command 'git' failed
# Succeeds
withr::with_dir("local-repo", gert::git_push())
# WAT?
run("git", c("-C", "local-repo", "push"))
#> Everything up-to-date Created on 2024-08-19 with reprex v2.1.0 |
Add a ruleset indicating that a status check must pass, or that PRs are required, for the main branch. Then:
Created on 2024-08-18 with reprex v2.1.0
In interactive mode (can't reprex), I'm seeing:
I can work around by checking if
<remote>/<branch>
is the same as the local branch, but it would be better IMO ifgit_push()
did that for me.The text was updated successfully, but these errors were encountered: