'Rename a file with github api?

I thought that the update file method of the Github API could be used to rename a file (by providing the new path as parameter) but it does not seem to work.

The only way to rename is to delete the file and to create a similar one with the new name?



Solution 1:[1]

I thought that the update file method of the Github API could be used to rename a file (by providing the new path as parameter) but it does not seem to work.

There's no way to rename a file with a single request to the API.

The only way to rename is to delete the file and to create a similar one with the new name?

That's one way, but the downside is that you get two commits in the history (one for the delete, and one for the create).

A different way is to use the low-level Git API:

https://developer.github.com/v3/git/

With that, you can modify the tree entry containing the blob to list it under a different name, then create a new commit for that tree, and finally update the branch to point to that new commit. The whole process requires more API requests, but you get a single commit for the rename.

Solution 2:[2]

With the help of the following articles, I figured out how to rename a file with Github API.

First, find and store the tree that latest commit.

# Gem octokir.rb 4.2.0 and Github API v3
api = Octokit::Client.new(access_token: "")
ref = 'heads/master'
repo = 'repo/name'
master_ref = api.ref repo, ref
last_commit = api.commit(repo, master_ref[:object][:sha])
last_tree = api.tree(repo, last_commit[:sha], recursive: true)

Use The harder way described in article Commit a file with the GitHub API to create a new tree. Then, do the rename just like the nodeJs version does and create a new tree based on the below changes.

changed_tree = last_tree[:tree].map(&:to_hash).reject { |blob| blob[:type] == 'tree' }
changed_tree.each { |blob| blob[:path] = new_name if blob[:path] == old_name }
changed_tree.each { |blob| blob.delete(:url) && blob.delete(:size) }
new_tree = api.create_tree(repo, changed_tree)

Create a new commit then point the HEAD to it.

new_commit = api.create_commit(repo, "Rename #{File.basename(old_name)} to #{File.basename(new_name)}", new_tree[:sha], last_commit[:sha])
api.update_ref(repo, ref, new_commit.sha)

That's all.

Solution 3:[3]

For those who end up here looking for more options, there is a better way to rename a file/folder. Please refer to the below link: Rename a file using GitHub api

Works for folder rename as well. There you would need to specify the folder path for new and old using the same payload structure as in the sample request in above link.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Ivan Zuzak
Solution 2 yaodong
Solution 3 maicalal