Skip to content

Fixed git fetch - Raise error when git command fails

Dat Tang requested to merge dattang/fix-raise-error-when-git-command-fails into master

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

How is git fetch without --update-head-ok a problem?

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

$

If git fetch without --update-head-ok is a problem, why didn't we see it before?

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?
Edited by Dat Tang

Merge request reports