Skip to content

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

@nickbroon

Description

@nickbroon

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions