project.files.save() fails due to start_branch being a URL query parameter and not a body attribute

Description of the problem, including code/CLI snippet

Attempting to modify a file and save it a new branch using the start_branch attribute

file = project.files.get(file_path=FILE_PATH, ref=project.default_branch)

file.content = "Modified contents"

file.save(
    start_branch=self.default_branch,
    branch=f"{NEW_BRANCH_NAME}",
    commit_message=f"File was modified for this new branch",
)

fails with with a 400 error GitlabUpdateError('You can only create or edit files when you are on a branch')

Enabling debugging its apparent that start_branch is being sent using a URL query string while everything else a body attribute.

send: b'PUT /api/v4/projects/12345678/repository/files/readme.txt?start_branch=main HTTP/1.1\r\nHost: gitlab.com\r\nUser-Agent: python-gitlab/7.1.0\r\nAccept-Encoding: gzip, deflate\r\nAccept: */*\r\nConnection: keep-alive\r\nContent-type: application/json\r\nPRIVATE-TOKEN: glpat-HIDDEN_TOKEN\r\n'

send: b'{"file_path": "readme.txt", "branch": "new_branch", "content": "Modified contents", "commit_message": "File was modified for this new branch"}'

which would correspond to the following curl command:

$ curl --request PUT \
       --url "https://gitlab.com/api/v4/projects/12345678/repository/files/readme.txt?start_branch=main" \
       --header "PRIVATE-TOKEN: ${GITLAB_PRIVATE_TOKEN}" \
       --header "Content-Type: application/json" \
       --data '{"file_path": "readme.txt", "branch": "new_branch", "content": "Modified contents", "commit_message": "File was modified for this new branch"}'

{"message":"You can only create or edit files when you are on a branch"}

Not specifying start_branch fails in the same way. However in the curl command if start_branch is moved from being a URL query parameter to a body attribute then it succeeds:

$ curl --request PUT \
       --url "https://gitlab.com/api/v4/projects/12345678/repository/files/readme.txt" \
       --header "PRIVATE-TOKEN: ${GITLAB_PRIVATE_TOKEN}" \
       --header "Content-Type: application/json" \
       --data '{"file_path": "readme.txt", "start_branch": "main", "branch": "new_branch", "content": "Modified contents", "commit_message": "File was modified for this new branch"}'

{"file_path":"readme.txt","branch":"new_branch"}

So question is how is start_branch used with the python project.files.save() such that its passed as a body attribute and not a URL query parameter?

Expected Behavior

Able to update a file using project.files save() with start_branch attribute.

Actual Behavior

It fails with a 400 error GitlabUpdateError('You can only create or edit files when you are on a branch'), and it does not seem possible to use the save() api.

Links

Specifications

  • python-gitlab version: 7.1.0
  • Gitlab server version (or gitlab.com): gitlab.com