Fixed git fetch - Raise error when git command fails
What does this MR do and why?
Describe in detail what your merge request does and why.
Content
This MR is similar to the MR !3366 (merged), which was reverted because of failing git fetch
. The only difference is the addition of the option --update-head-ok
to git fetch
. See below for more explanation.
Ref: gitlab-com/gl-infra/delivery#20390
git fetch
without --update-head-ok
a problem?
How is From the man page of git fetch
:
-u, --update-head-ok By default git fetch refuses to update the head which corresponds to the current branch. This flag disables the check.
I mean normally git fetch
does not allow updating the current branch. We can test it locally on any repository. For example in the gitlab
repo:
$ git fetch origin master:master
fatal: refusing to fetch into branch 'refs/heads/master' checked out at '/Users/dattang/git/gitlab-org/gitlab'
If I add the --update-head-ok
option, nothing is returned:
$╰─ git fetch --update-head-ok origin master:master
$
git fetch
without --update-head-ok
is a problem, why didn't we see it before?
If Because we didn't return on git error.
The line that causes it is: https://gitlab.com/gitlab-org/release-tools/-/blob/ccc76807927a1bb7922fdf4d30c849fa79cfd14c/lib/release_tools/remote_repository.rb#L73
The line after it works well, thus we didn't know that the previous one failed: https://gitlab.com/gitlab-org/release-tools/-/blob/ccc76807927a1bb7922fdf4d30c849fa79cfd14c/lib/release_tools/remote_repository.rb#L74
If we print out the output
, we see the same error:
2024-08-15 22:05:12.071107 I [security] ReleaseTools::RemoteRepository -- run_git -- {:command=>"git fetch --quiet --depth=50 dev 17-3-stable:17-3-stable"}
2024-08-15 22:05:15.868554 I [security] ReleaseTools::RemoteRepository -- fatal: refusing to fetch into branch 'refs/heads/17-3-stable' checked out at '/private/var/folders/1z/fj_9_75965n596lchr336cy80000gn/T/gitaly'
fatal: the remote end hung up unexpectedly
remote:
remote: ========================================================================
remote:
remote: rpc error: code = Canceled desc = running upload-pack: user canceled the request
remote:
remote: ========================================================================
remote:
-- pid 9251 exit 128
2024-08-15 22:05:15.869098 I [security] ReleaseTools::RemoteRepository -- run_git -- {:command=>"git fetch --quiet --depth=50 dev 17-3-stable"}
=> true
2024-08-15 22:05:19.219613 I [security] ReleaseTools::RemoteRepository -- -- pid 9260 exit 0
2024-08-15 22:05:19.219646 I [security] ReleaseTools::RemoteRepository -- Successfully fetched from repository -- {:remote=>:dev, :ref=>"17-3-stable", :depth=>50}
Testing
You can try the below tests from your local machine.
Without adding --update-head-ok
, we can reproduce the issue:
[4] pry(main)> repository = ReleaseTools::RemoteRepository.get(ReleaseTools::Project::Gitaly::REMOTES, global_depth: 50, branch: '17-3-stable')
=> #<ReleaseTools::RemoteRepository:0x000000012effdc58
@branch="17-3-stable",
@canonical_remote=#<struct ReleaseTools::RemoteRepository::CanonicalRemote name=:canonical, url="git@gitlab.com:gitlab-org/gitaly.git">,
@global_depth=50,
@path="/var/folders/1z/fj_9_75965n596lchr336cy80000gn/T/gitaly",
@remotes={:canonical=>"git@gitlab.com:gitlab-org/gitaly.git", :dev=>"git@dev.gitlab.org:gitlab/gitaly.git", :security=>"git@gitlab.com:gitlab-org/security/gitaly.git"},
@semantic_logger=#<SemanticLogger::Logger:0x000000012fc728a8 @filter=nil, @level=nil, @level_index=nil, @name="ReleaseTools::RemoteRepository">>
[6] pry(main)> repository.fetch('17-3-stable', remote: :dev)
2024-08-15 21:44:52.065794 W [security] ReleaseTools::RemoteRepository -- run_git -- {:command=>"git fetch --quiet --depth=50 dev 17-3-stable:17-3-stable", :output=>"fatal: refusing to fetch into branch 'refs/heads/17-3-stable' checked out at '/private/var/folders/1z/fj_9_75965n596lchr336cy80000gn/T/gitaly'\nfatal: the remote end hung up unexpectedly\nremote: \nremote: ========================================================================\nremote: \nremote: rpc error: code = Canceled desc = running upload-pack: user canceled the request\nremote: \nremote: ========================================================================\nremote: \n", :status=>128}
2024-08-15 21:45:02.337684 W [security] ReleaseTools::RemoteRepository -- run_git -- {:command=>"git fetch --quiet --depth=50 dev 17-3-stable:17-3-stable", :output=>"fatal: refusing to fetch into branch 'refs/heads/17-3-stable' checked out at '/private/var/folders/1z/fj_9_75965n596lchr336cy80000gn/T/gitaly'\nfatal: the remote end hung up unexpectedly\nremote: \nremote: ========================================================================\nremote: \nremote: rpc error: code = Canceled desc = running upload-pack: user canceled the request\nremote: \nremote: ========================================================================\nremote: \n", :status=>128}
ReleaseTools::RemoteRepository::RemoteConnectionError: An error occurred on the remote connection
fatal: refusing to fetch into branch 'refs/heads/17-3-stable' checked out at '/private/var/folders/1z/fj_9_75965n596lchr336cy80000gn/T/gitaly'
fatal: the remote end hung up unexpectedly
remote:
remote: ========================================================================
remote:
remote: rpc error: code = Canceled desc = running upload-pack: user canceled the request
remote:
remote: ========================================================================
remote:
from /Users/dattang/git/gitlab-org/release-tools/lib/release_tools/remote_repository.rb:178:in `block in run_git'
2024-08-15 21:45:06.884249 W [security] ReleaseTools::RemoteRepository -- run_git -- {:command=>"git fetch --quiet --depth=50 dev 17-3-stable:17-3-stable", :output=>"fatal: refusing to fetch into branch 'refs/heads/17-3-stable' checked out at '/private/var/folders/1z/fj_9_75965n596lchr336cy80000gn/T/gitaly'\nfatal: the remote end hung up unexpectedly\nremote: \nremote: ========================================================================\nremote: \nremote: rpc error: code = Canceled desc = running upload-pack: user canceled the request\nremote: \nremote: ========================================================================\nremote: \n", :status=>128}
After adding the option, the command succeeds:
[1] pry(main)> repository = ReleaseTools::RemoteRepository.get(ReleaseTools::Project::Gitaly::REMOTES, global_depth: 50, branch: '17-3-stable')
=> #<ReleaseTools::RemoteRepository:0x00000001251f2540
@branch="17-3-stable",
@canonical_remote=#<struct ReleaseTools::RemoteRepository::CanonicalRemote name=:canonical, url="git@gitlab.com:gitlab-org/gitaly.git">,
@global_depth=50,
@path="/var/folders/1z/fj_9_75965n596lchr336cy80000gn/T/gitaly",
@remotes={:canonical=>"git@gitlab.com:gitlab-org/gitaly.git", :dev=>"git@dev.gitlab.org:gitlab/gitaly.git", :security=>"git@gitlab.com:gitlab-org/security/gitaly.git"},
@semantic_logger=#<SemanticLogger::Logger:0x000000012572f558 @filter=nil, @level=nil, @level_index=nil, @name="ReleaseTools::RemoteRepository">>
[2] pry(main)> repository.fetch('17-3-stable', remote: :dev)
=> true
2024-08-15 22:40:41.287678 I [security] ReleaseTools::RemoteRepository -- Successfully fetched from repository -- {:remote=>:dev, :ref=>"17-3-stable", :depth=>50}
Author Check-list
-
Has documentation been updated?