Change a path in file update [Solved]


#1

Hi,

How do I change a path of a file/folder structure? So file is at repo/someFolder/someFile.txt - lets say i want to move the file to repo/someOtherFolder/someFile.txt. How do I do this? I have been trying to use the update a file here, but not having much luck. In essense, using a bit of code like so:

a. get list of dirPaths and filePaths, and the new name i need.
b. Get the original contents of the file which is being changed.
c. Update the file, but this time with the same content but different path in the data object below.
d. I get a 200 back from the update, but the path does not change?

Is what I am trying to do even possible? Or is it just a delete old copy and put in new copy the only option? Does this mean, effectively, on creation of a new file, the history will be lost?

Thanks so much.

tat

async renameItems(dirPaths, filePaths, repoCode, oldName, newName) {
    getAccessToken()
      .then((result) => {
        if (result.statusCode === 201) {
          const token = result.data.token;
          const name = getUserName(this.props.rootStore.userId);
          const email = getUserEmails(this.props.rootStore.userId)[0].address;

          filePaths.map((filePath) => {
            getContentsPromise(token, repoCode, filePath)
              .then((result) => {
                if (result.statusCode === 200) {
                  console.log(result);

                  let headers = {
                    repoCode: repoCode,
                    filePath: filePath,
                  };

                  let data = {
                    path: filePath.replace(oldName, newName),
                    message: `New Path: ${filePath.replace(oldName, newName)}:${name}:${email}:${(new Date()).toJSON()}`,
                    content: result.data.content,
                    committer: {
                      name: name,
                      email: email,
                    },
                    sha: result.data.sha,
                  };

                  console.log(headers);
                  console.log(data);

                  updateFilePromise(token, headers, data)
                    .then((result) => {
                      console.log(result);
                    });
                }
              });
          });
        }
      });

    return await true;
  }

#2

To anyone else who sees this, it appears impossible. It is simpler to just make a new file and delete the old file.


#3

Hi @tathagatbanerjee :wave:

I just wanted to mention two things. First, this forum should be used for questions and feedback related to the GitHub Apps feature. It should not be used for general GitHub API questions (or anything unrelated to the GitHub Apps feature). If you have general API questions – please contact Support via https://github.com/contact

Second, there’s no concept of moving files in Git. In Git, the structure of your repository is structured as a tree. Each commit points to a root tree for the root folder of the repository, and each sub-folder has a sub-tree for it. The files in those folders are leaves in the tree and point to Git blob objects. So, if you want to move a file from one position to another, you basically need to construct a new tree which doesn’t have the pointer to the blob at the old location in the tree structure and does have a pointer to the blob in the new location in the tree structure.

With the GitHub API, there are two ways to do this:

  1. delete the file and then create it at a new location, using the Repo Contents API. This is what you did. This process creates two commits in the repository’s history – one for the delete and one for the create. You can’t update the path of a file via the Repo Contents API with a single API call, you can only update the contents of a file at a specific path.
  2. if you want to keep the history clean, you can do this with a single commit, but using the low-level Git Data API: https://developer.github.com/v3/git/. This would involve multiple GitHub API calls (to create the new trees, create a new commit pointing to the new root tree, and then updating the ref to point to the new commit), but it will result in a single new commit in the repository’s history.

If you have any further questions about this, please followup with GitHub Support.