Getting 500 when calling last-modified

I am trying to call last-modified for each file in a repo. I have tried both sending branch name and latest commit for the branch as parameter “at”. I get a 500 response both for branch name and commit id.

I have not been able to get my hands on the server logs yet because of vacations.

Any help would be appreciated

The server version is 7.2.3.

This is the call I am attempting: https://docs.atlassian.com/bitbucket-server/rest/7.2.3/bitbucket-rest.html#idp261

Example urls:

bitbucket.secret.se/rest/api/1.0/projects/APPII_FUSE_KUI/repos/koder-bankdagar-api/last-modified/.gitignore?at=refs/heads/develop
bitbucket.secret.se/rest/api/1.0/projects/APPII_FUSE_KUI/repos/koder-bankdagar-api/last-modified/.gitignore?at=3be139148c45d30c66a24bad45360725d996b8b0

Mårten

Hi @marten.gustafsson,

Thanks for bring this to our attention. I’ve raised the bug BSERV-12510. Please follow it for updates.

Regards,
Kristy
Developer on Bitbucket Server

1 Like

Hi @marten.gustafsson,

Upon further investigation it seems like the path is expected to be a directory, not a file.
So your request without the ‘/.gitignore’ should work.

Hope that helps,
Kristy

@marten.gustafsson,

Perhaps the “files in the requested path” in the documentation is not clear enough, but the endpoint you’re using isn’t for files; it’s for directories. The server should fail with a clear message for files, rather than the 500 you’re getting, but files are not what that endpoint is for and it’s not a bug that they don’t work. (Getting a 500 is a bug; it should be a 400 with a message that says the endpoint requires a directory.)

Retrieving last modified details for every individual file in a repository via REST is going to be an extremely inefficient operation. The best approach, in terms of not potentially overloading your server (which I’d assume is shared by many devs) would be to clone the repository and then use local git commands to come up with the details you need. If you must do it via REST, working directory-by-directory is going to be much more efficient for the server–not to mention making the overall task much faster.

So, given your .gitignore example, the request would be /rest/api/1.0/projects/APPII_FUSE_KUI/repos/koder-bankdagar-api/last-modified?at=refs/heads/develop. That will stream the last modified details for every file in the root directory in a single request, and you can parse out the various files. You can then traverse down into subdirectories with separate requests as necessary.

Hope this helps,
Bryan Turner
Atlassian Bitbucket

Thanks for replies.

To ask for a single file seemed logical since the last-modified request is not paged.

I am using files to get all the files in a repo. This one is paged.

If last-modified was paged I could use that one instead of files, but I will not substitute one lesser evil for a bigger one.

The way forward is for each file ask for its directory and then find the file in the result list. Despite the complexity (guarding the cache with a mutex) I added caching.

Looking at the response I get, only one catalog is returned. This is not obvious from the documentation. But I guess paging is not so important.

Also it is not stated that the at parameter accepts a repo.

This works really great now! Thanks for the help!

If last-modified was paged I could use that one instead of files, but I will not substitute one lesser evil for a bigger one.

I’m not entirely sure what this means. It’s not paged, but on the server it doesn’t load everything into memory; it streams directly from git. So for the server, it’s substantially more efficient than a paging endpoint, because you can get the last modification details for any number of files using exactly one request. Of course, the client would also need to handle a potentially large response gracefully, but on the server we don’t “control” that aspect. Assuming whatever tooling you’re using can read streaming input, it should be possible for it to handle a response of any size.

Looking at the response I get, only one catalog is returned.

I’m guessing you mean it only lists the direct children for a single directory, rather than every file in the entire repository regardless of depth. If so, yes, that’s how it works.

Also it is not stated that the at parameter accepts a repo.

I’m not sure what this means either. at accepts a ref ID or a commit ID, not a repository (at least, not a “repository” in my parlance). at means you can start from point in history and figure out what the last modification was for the files that exist at that commit.

This works really great now! Thanks for the help!

Glad you were able to get everything sorted out.

Best regards,
Bryan Turner
Atlassian Bitbucket

I’m not sure what this means either. at accepts a ref ID or a commit ID , not a repository (at least, not a “repository” in my parlance). at means you can start from point in history and figure out what the last modification was for the files that exist at that commit.

It is a “typo”, I thought branch but wrote repo.

The documentation can be improved.