How to Search for Commits in Bitbucket Server and Data Center

April 1, 2023
#Bitbucket#Reporting#Analytics#How To
14 min

Bitbucket has greatly improved the development workflow of teams and companies that use Git with its friendly interface and features. However, sometimes it lacks opportunities for convenient work with commits. Have you ever wasted time scrolling the mouse wheel trying to find some of the old commits? Luckily, there are some ways to make your life easier and search for commits in Bitbucket. In this article, you will learn how to find:

  • projects and repositories in your Bitbucket that a certain user contributed to (filter by author)
  • commits that were made long ago to a repository with high activity (filter by time)
  • the commits of a user made to a repository or project (filter by author and project/repo)
  • all the commits made to a project (filter by project).

We’ll also show you how to automate the process using the Bitbucket REST API, as well as the Awesome Graphs REST API and the Export to CSV feature.

Sourcetree search opportunities

Sourcetree is an Atlassian desktop client for working with Git and Mercurial repositories. It provides an opportunity to search for commits by an author, a commit message, and a file.

search for commits by an author, a commit message, and a file in Sourcetree

Its user-friendly interface helps find commits easier, but it’s impossible to look at them for all repositories at once as you need to go to each repo manually. Besides, it needs to be installed on each computer separately and is not available for Linux.

Use Awesome Graphs to search commits in Bitbucket

Awesome Graphs for Bitbucket helps engineering leaders and software teams improve their processes and deliver products faster by transforming invisible development activities into easy-to-understand insights and reports. Convenient search for commits isn’t its main purpose, but a nice bonus.

This app indexes information about commits, which makes searching by author, time, or repository faster and does not affect even huge Bitbucket instances (70,000+ repositories).

The Contributions graph shows the activity of each developer during a year as a calendar. So it’s an easy way to find all the commits made by a person to all projects and repositories. Here you can also filter the commits of a particular user by time period (up to a year) and by project or repository.

Below the calendar, there is a list of all commits and pull requests made during the selected time span. By default, it’s a year, but it’s possible to choose any period to display.

In order to find the commits made to a certain repository regardless of their author, use the Activity graph. It shows all commits for the last year or a shorter time span in the Activity section below the charts.

And if you need to find commits made long ago, the Top Committers Report can be a good solution. In general, its use-case is to find the most active contributors of the project or repository, but you can configure the Period of time and choose Authors of the commits you’re searching for.

As a result, it shows the list of all commits for the selected time span in the Activity section below as well as their distribution in time.

Export commit data to CSV

Awesome Graphs for Bitbucket also gives you the capability to export commit data to CSV in different ways. As a result, you’ll get a list of commits with their details:

To export raw commit data to CSV directly from Bitbucket, you need to go to the People page. There you’ll notice the Export menu at the top-right corner, where you can choose CSV.

Another way to export commit data to CSV is to use the Awesome Graphs REST API, which allows you to automate the processes and retrieve this data easier using the dedicated resources.

You can access the in-app documentation (accessible to Awesome Graphs’ users) by choosing Export → REST API on the People page or go to our documentation website.

Search for commits in Bitbucket via REST API

Bitbucket REST API provides a possibility to get the list of all commits in the repository using this request.

https://example.com/rest/api/1.0/projects/exampleprojectkey/repos/example-repository-slug/commits

The request can be extended by specific parameters to receive a more accurate result. For instance, since and until options help to get the commits made after or before a certain commit, or between two commits defined by their IDs. Merges parameter controls how to handle merge commits – exclude merge commits, include both merge commits and non-merge commits, or only return merge commits.

https://example.com/rest/api/1.0/projects/exampleprojectkey/repos/example-repository-slug/commits?merges=exclude&since=ea3eea9dcbd&until=f4240bf022a

As a result, you receive a JSON response with the list of the commits and their IDs, author’s names and email addresses, commit messages, and parents.

{
    "values": [
        {
            "id": "f4240bf022a69815241a883c03645444b58ac553",
            "displayId": "f4240bf022a",
            "author": {
                "name": "Max Desiatov",
                "emailAddress": "max@desiatov.com"
            },
            "authorTimestamp": 1557113671000,
            "committer": {
                "name": "Tomer Doron",
                "emailAddress": "tomer@apple.com"
            },
            "committerTimestamp": 1557113671000,
            "message": "Add internal section link to README.md (#71)",
            "parents": [
                {
                    "id": "ea3eea9dcbd46887d846696261f54b3d2f74fecd",
                    "displayId": "ea3eea9dcbd"
                }
            ]
        },

Alternatively, you can use the Awesome Graphs REST API that provides global, user, project, and repository data. The solution allows you to retrieve data faster while decreasing the load on the instance compared to Bitbucket REST API. 

Use this request to get a list of commits from the specified repository.

https://example.com/rest/awesome-graphs-api/latest/projects/exampleprojectkey/repos/example-repository-slug/commits

The response will look as follows:

{
  "values": [
    {
      "user": {
        "emailAddress": "yorlov@stiltsoft.com",
        "displayName": "Administrator",
        "name": "admin"
      },
      "author": {
        "displayName": "admin",
        "emailAddress": "yorlov@stiltsoft.com"
      },
      "authorTimestamp": "2020-03-05T22:58:18Z",
      "linesOfCode": {
        "added": 1,
        "deleted": 0
      },
      "parents": [],
      "repository": {
        "slug": "Commit Hook",
        "name": "commit-hook",
        "project": {
          "key": "TESTCONTAINERS",
          "name": "Testcontainers",
          "type": "NORMAL"
        }
      },
      "id": "9f2e24a147bb8f5a5a3d10b692703cc5784df8b5"
    },
  ],
}

Learn more about the available REST API resources.

Find out what works best for you

We’ve described different ways to work with commits effectively:

  • Sourcetree as a free application that is suitable for searching among a small number of repositories.
  • Awesome Graphs for Bitbucket add-on as a tool with wide search opportunities and various analytical features.
  • Bitbucket REST API as a more advanced and technically demanding option.

Try them all and find the best solution!

You can also read how other teams benefit from using Bitbucket in a bundle with Awesome Graphs:

 

Related posts

    How to Export Commit and Pull Request Data from Bitbucket to CSV

    November 26, 2022
    #Bitbucket#Reporting#How To
    11 min

    Being a universal file type, CSV serves as a go-to format for integrations between the applications. It allows for transferring a large amount of data across the systems, blending it, and building custom reports. To export commit and pull request data from Bitbucket, you can use the Awesome Graphs for Bitbucket app, which gives you the capability to export to CSV in different ways.

    In this article, we’ll show you how to use the app to export engineering data to CSV for further integration, organization, and processing in analytics tools and custom solutions.

    What you will get

    The described ways of exporting will give you two kinds of generated CSV files, depending on the type of data exported. 

    In the case of commit data, you’ll get a list of commits with their details:

    commits export

    And the resulting CSV with a list of pull requests will look like this:

    pr export

    Exporting from the People page

    You can export raw commit and pull request data to CSV directly from Bitbucket. When you click All users in the People dropdown menu at the header, you’ll get to the People page with a global overview of developers’ activity in terms of commits or pull requests.

    At the top-right corner, you’ll notice the Export menu, where you can choose CSV.

    Export Commit and Pull Request Data from Bitbucket

    By default, the page shows contributions made within a month, but you can choose a longer period up to a quarter. The filtering applies not only to the GUI but also to the data exported, so if you don’t change the timespan, you’ll get a list of commits or pull requests for the last 30 days.

    Exporting via the REST API resources

    Beginning with version 5.5.0, Awesome Graphs REST API allows you to retrieve and export commit and pull request data to CSV on global, project, repository, and user levels, using the dedicated resources. This functionality is aimed to automate the processes you used to handle manually and streamline the existing workflows.

    You can access the in-app documentation (accessible to Awesome Graphs’ users) by choosing Export → REST API on the People page or go to our documentation website.

    We’ll show you two examples of the resources and how they work: one for exporting commits and another for pull requests. You’ll be able to use the rest of the resources as they follow the model.

    Export commits to CSV

    This resource exports a list of commits with their details from all Bitbucket projects and repositories to a CSV file.

    Here is the curl request example:

    curl -X GET -u username:password "https://bitbucket.your-company-name.com/rest/awesome-graphs-api/latest/commits/export/csv" --output commits.csv

    Alternatively, you can use any REST API client like Postman or put the URL directly into your browser’s address bar (you need to be authenticated in Bitbucket in this browser), and you’ll get a generated CSV file.

    By default, it exports the data for the last 30 days. You can set a timeframe for exported data up to one year (366 days) with sinceDate / untilDate parameters:

    curl -X GET -u username:password "https://bitbucket.your-company-name.com/rest/awesome-graphs-api/latest/commits/export/csv?sinceDate=2020-10-01&untilDate=2020-10-13" --output commits.csv

    For commit resources, you can also use the query parameters such as merges to filter merge/non-merge commits or order to specify the order to return commits in.

    Read more about the resource and its parameters.

    Export pull requests to CSV

    The pull request resources work similarly, so to export a list of pull requests with their details from all Bitbucket projects and repositories to a CSV file, make the following curl request:

    curl -X GET -u username:password "https://bitbucket.your-company-name.com/rest/awesome-graphs-api/latest/pull-requests/export/csv" --output pullrequests.csv

    The sinceDate / untilDate parameters can also be applied to state the timespan up to a year, but here you have an additional parameter dateType, allowing you to choose either the creation date or the date of the last update as a filtering criterion. So, if you set dateType to created, only the pull requests created during the stated period will be returned, while dateType set to updated will include the pull requests that were updated within the time frame.

    Another pull request specific parameter is state, which allows you to filter the response to only include openmerged, or declined pull requests.

    For example, the following request will return a list of open pull requests, which were updated between October 1st and October 13th:

    curl -X GET -u username:password "https://bitbucket.your-company-name.com/rest/awesome-graphs-api/latest/commits/export/csv?dateType=updated&state=open&sinceDate=2020-10-01&untilDate=2020-10-13" --output pullrequests.csv

    Learn more about this resource.

    Integrate intelligently

    While CSV is supported by many systems and is quite comfortable to manage, it is not the only way for software integrations the Awesome Graphs for Bitbucket app offers. Using the REST API, you can make the data flow between the applications and automate the workflow, eliminating manual work. And we want to make it easier for you and save your time.
    Let us know what integrations you are interested in, and we’ll try to bring them to you, so you don’t have to spend time and energy creating workarounds.

    Related posts

      Analyze How Code Review is Going in Bitbucket Data Center

      September 27, 2021
      #Analytics#How To#Bitbucket
      9 min

      Awesome Graphs is one of our most popular apps. It’s a solution that extends Bitbucket, a platform that teams use to host Git repositories and collaborate on code.

      Awesome Graphs helps engineering leaders and software teams improve their own processes and deliver products faster by transforming invisible development activities into easy-to-understand insights and reports.

      One of the keys focuses of the app is the code review processes analytics. We would like to tell you which features support this use case and how you can benefit from the app. Keep reading if you are interested in:

      • Seeing how actively your team members review code
      • Analyzing what developers may need to improve their work patterns and who’s doing a great job
      • Learning what reviewers are most active and diligent
      • Knowing the average time taken to resolve pull requests.

      Code review analysis

      code review analysis in bitbucket

      The Contributions Report analyzes activity in pull requests (tasks, comments, needs work/approved/declined statuses). It helps you understand:

      • What developers create high-quality code and who might need to improve their approach to work. E.g. when an engineer has fewer taskscomments, and needs work flags in their pull requests, it suggests his work is approved as it is or with minor changes and he creates code of high quality.
      • What reviewers are thorough when they review the work of developers. E.g. diligent reviewers come up with suggestions and improvements, so they have more tasks and comments than others.
      • How the dynamics of code review changes over time. E.g. you can see if the number of pull requests with Needs work flags is getting bigger or smaller if the number of tasks in pull requests is increasing or decreasing over time.

      Learn more

      The average time taken to resolve pull requests

      pull requests resolution time report in bitbucket

      Another report, Resolution Time Report, shows the average time taken to resolve pull requests. This is helpful to capture trends in resolution time. It displays resolution times of merged and declined pull requests separately. With this report you can:

      • Notice spikes in resolution time and then dive in to see what went wrong
      • See if an average resolution time is high for a long period of time – it can be a signal to look into your code review process and determine what causes delays
      • Monitor how changes in your processes affect the speed of code review.

      Learn more

      Knowledge sharing indicators

      reviewers of pull requests report in bitbucket

      The Pie Chart Report is a handy way to check if all developers in your team are involved in the code review. This report shows the breakdown of pull requests by different statistics types.

      Grouped by reviewer, the Pie Chart Report shows the following:

      • How many pull requests each person reviewed. These metrics help understand how much everyone contributes to the project.
      • Whether all people review code or there are one or two who are doing all job. This is an indicator of poor knowledge sharing.
      • Who is too busy reviewing all pull requests of their team. These people can become a bottleneck that slows the delivery time, because they’re not available for immediate review.

      Learn more

      Pull requests with a too long or too short resolution time

      pull requests resolution time report in bitbucket

      The Resolution Time Distribution Report visualizes pull requests grouped by the time taken to merge or decline them and gives an idea of the most frequent resolution times on your project. Using this report. you can easily:

      • find pull requests with the longest resolution time to check the reasons for the delay
      • see pull requests with the shortest time to resolve them to investigate whether they were checked as appropriate
      • predict the resolution time for the future pull requests.

      Learn more

      Exporting pull requests for the future processing

      With Awesome Graphs, the historical data can be exported to a CSV file right on the People page.

      exporting pull requests from bitbucket

      As a result of the exporting, you receive the CSV file with the list of pull requests (alternatively, the list of commits) with their details about the author, reviewers, state, the date they were created and last updated. The files can be processed in Excel or integrated with analytics tools like Tableau, Power BI, etc. to create custom graphs and dashboards and merge with the data from other apps.

      Learn more

      What other reports do you need?

      Awesome Graphs already has a wide range of graphs and reports that help you answer various questions about project development and the work of your team in Bitbucket. We are open to your feedback and appreciate hearing about what you need. So if you have a problem that you think Awesome Graphs can help you with, contact us – we actually listen.

      Try Awesome Graphs for free

       

      Pull Request vs. Merge Request

      June 28, 2021
      #How To#Bitbucket#Analytics
      7 min

      When it comes to choosing a Git management tool, you need to consider various factors as it significantly affects the workflow. One of the most important aspects is how collaboration is organized in this application. Pull Request in Bitbucket and GitHub or Merge Request in GitLab are the features made for more convenient code review. These features are equivalent as they both do the same git merge command to merge feature branches or forks with the existing code.

      You probably want to ask why you need to use a special tool for something that a git command can do, but convenience and efficiency are what makes a difference here:

      • Your team ends up having a much higher quality code in your project as everyone on your team can check it and merge branches only after the code is good enough and meets your coding standards.
      • You get a well-organized process where you can leave comments and see the changes in one tool. So there’s no need to use emails and other communication channels to discuss features. It works perfectly, especially for distributed teams, no matter whether they are located – in different rooms or cities.
      • This feature allows you to get some insights into how effective your team is.

      Working with Pull Requests in Bitbucket

      Let’s look at how to use pull requests in Bitbucket and what information about your team performance you can get from it.

      For instance, one of your developers has just finished working on a feature in a dedicated branch. Now, this feature should be merged with the development branch. But first, other team members should review it.

      So, your developer navigates to Create pull request, chooses the feature branch as Source and the development branch as Destination. The developer can add the Title and Description of the pull request and choose who will be Reviewers of it or leave it without a particular reviewer.

      create pull request in Bitbucket

      Then a discussion of the feature begins. Each reviewer can:

      • see what files have been edited, what commits have been made
      • see what’s been changed since they last reviewed so that there’s no need to re-review everything again
      • add comments to the whole pull request or a particular code line and discuss it

      comment pull request or code line in Bitbucket

      • decline a pull request or set Needs work status
      • merge a pull request and delete the source branch if needed.

      merge pull request in Bitbucket

      Working with Merge Requests in GitLab

      Now let’s find out how to use the Merge Request feature in GitLab to improve the code review process.

      Navigate to Merge Requests and click New merge request. 

      create merge request in GitLab

      Choose the Source branch that you want to merge and the Target branch which will be the destination.

      merge source branch with target branch

      Same as Bitbucket, GitLab allows you to choose who will review this request. It’s also possible to see the changes in edited files, the commits included in the merge request, discuss the feature, and make suggestions.

      When reviewers approve the changes, click Merge to merge branches.

      how to merge branches in GitLab

      Insights on Your Team Performance in Bitbucket

      While working in Bitbucket, you can also evaluate your team performance using the Awesome Graphs for Bitbucket app. It is possible to:

      contributions report in Bitbucket

      Improve your development process

      Such collaboration while working on the project positively affects the quality of the code your team produces. Moreover, pull requests definitely reduce the number of bugs in the code.

      As a result, the quality of your product gets better, and your customers become much more satisfied. Thanks to the detailed analysis of your team’s performance using Awesome Graphs for Bitbucket app, it’s possible to improve it and increase the speed of the development process.

      Try it for your team!

      Related posts

        Pull Request Analytics: How to Visualize Cycle Time / Lead Time and Get Insights for Improvement

        March 30, 2021
        #Reporting#How To#Bitbucket
        12 min

        Cycle Time / Lead Time is one of the most important metrics for software development. It can tell a lot about the efficiency of the development process and the teams’ speed and capacity. In the previous article, we showed you how to get a detailed report with the pull request statistics and Cycle Time / Lead Time calculated on the repository level. 

        Today we’ll tell you how to use this report:

        • How to visualize the pull request data.
        • What things to pay attention to.
        • What insights you can get to improve performance.

        Please note that we define Cycle Time / Lead Time as the time between the developer’s first commit and the time it’s merged and will refer to it as Cycle Time throughout the article.

        Analyzing your codebase

        First, you need to understand the current state of affairs and how it compares to the industry standards. According to the Code Climate’s research, the industry-wide median for Cycle Time is 3.4 days, with only the top 25% managing to keep it as low as 1.8 days and the bottom 25% having a Cycle Time of 6.2 days.

        © Code Climate

        To get a better understanding of the development process, it might be helpful to look at the teams’ dynamics and monitor the changes over time. The following chart shows how the average Cycle Time changes month after month with a trend line, so you can see objectively whether the development process is getting faster or slower and check how your rates compare to the industry average. Follow the instructions to build this chart.

        For a more precise analysis and evaluation of the current code base, you can also use the Cycle Time distribution chart that provides pull request statistics aggregated by their Cycle time value, making it easy to spot the outliers for further investigation. Learn how to build this chart.

        In addition to the Cycle Time, Awesome Graphs for Bitbucket lets you analyze the pull request resolution time out-of-the-box. Using the Resolution Time Distribution report, you can see how long it takes pull requests to merge or decline, find the shortest and longest pull requests, and predict the resolution time of future pull requests with the historical data.

        While Cycle Time serves as a great indicator of success and, keeping it low, you can increase the output and efficiency of your teams, it’s not diagnostic by itself and can’t really tell what you are doing right or wrong. To understand why it is high or low, you’ll need to dig deeper into the metrics it consists of. The chart below gives you a general overview of the pull requests on the repository level and shows the Cycle Time with the percentage of the stages it’s comprised of (which we’ll discuss in detail in the following paragraphs). You can build a chart like this using the Chart from Table macro, available in the Table Filter and Charts app.

        Breaking down the Cycle Time

        We break down Cycle Time into four stages:

        • Time to open (from the first commit to open)
        • Time waiting for review (from open to the first comment)
        • Time to approve (from the first comment to approved)
        • Time to merge (from approved to merge)

        Now we’ll go through each of these stages, discussing the things to pay attention to.

        Time to Open

        This metric is arguably the most important of all, as it influences all the later stages and, according to the research, pull requests that open faster tend to merge faster.

        Long Time to Open might indicate that the developer had to switch tasks and/or that code was rewritten, which might also result in large batch sizes. In one of the previous articles, we described how you can check the size of your pull requests in Bitbucket, so you can also use it for a deeper analysis.

        One of the things you can do to improve your Time to Open is to decrease the pull request size to be no more than 200 to 400 lines of code. Thus you’ll influence each stage of the cycle, as the smaller pull requests are more likely to be reviewed more thoroughly and be approved sooner.

        Time to Review

        Time to Review is a great metric to understand if your teams adopted Code Review as part of the daily routine. If it’s high, then it might not be part of their habit, and you’ll need to foster this culture. Another reason might be that the pull requests are not review-friendly and the reviewers procrastinate dealing with them. You can change this, once again, by keeping the pull request size small and by writing a reasonable description so it’s easier to get started with them. If the long Time to Review rate is caused by organizational issues, then it might require reprioritization.

        Time to Approve

        This is the stage you don’t really want to minimize but rather make it consistent by reducing inefficiencies in the code review process. While there are many strategies for Code Review, there is hardly any industry standard for Code Review metrics, so you’ll need to focus on the organization of the process and try to find a way to get constructive feedback.

        Time to Merge

        Long Time to Merge might be an indicator that there are obstacles in the delivery workflow. To improve it, you need to find out if there are any blockers in the process, including manual deployment, and check if your tooling satisfies your current needs.

        Wrapping up

        Cycle Time’s importance is difficult to overestimate, as this metric can tell a lot about the way you work, and controlling it, you can optimize the development process and deliver faster.

        Once again, we built the initial pull request report with the help of the Awesome Graphs for Bitbucket app as a data provider and used the Table Filter and Charts for Confluence app to aggregate and visualize the data.

        These are just a few examples, but you can get much more even from this one report. Check out the other guides for charts based on data from Bitbucket. Share your feedback and ideas in the comments, and we’ll try to cover them in future posts.

        Related posts

          Pull Request Analytics: How to Get Pull Request Cycle Time / Lead Time for Bitbucket

          March 23, 2021
          #How To#Bitbucket#Reporting
          13 min

          What Cycle Time is and why it is important

          Pull Request Cycle Time / Lead Time is a powerful metric to look at while evaluating the engineering teams’ productivity. It helps track the development process from the first moment the code was written in a developer’s IDE and up to the time it’s deployed to production.

          Please note that we define Cycle Time / Lead Time as the time between the developer’s first commit and the time it’s merged and will refer to it as Cycle Time throughout the article.

          Having this information, you can get an unbiased view of the engineering department’s speed and capacity and find the points to drive improvement. It can also be an indicator of business success as, by controlling the Cycle Time, you can increase the output and efficiency to deliver products faster.

          This article will show you how to get a detailed pull request report with the Cycle Time and the related metrics calculated on the repository level. The metrics include:

          • Time to open (from the first commit to open)
          • Time waiting for review (from open to the first comment)
          • Time to approve (from the first comment to approved)
          • Time to merge (from approved to merge)

          How to get Time to Open, Time to Review, Time to Approve, and Time to Merge metrics

          We can get all the necessary pull request data from Awesome Graphs for Bitbucket and its REST API combined with Bitbucket’s REST API resources. We’ll use Python to make requests into the APIs, calculate and aggregate this data and then save it as a CSV file, like this:

          The following script will do all this work for us:

          </p>
          import sys
          import requests
          import csv
          from dateutil import parser
          from datetime import datetime
           
          bitbucket_url = sys.argv[1]
          login = sys.argv[2]
          password = sys.argv[3]
          project = sys.argv[4]
          repository = sys.argv[5]
          since = sys.argv[6]
          until = sys.argv[7]
           
          s = requests.Session()
          s.auth = (login, password)
           
           
          class PullRequest:
           
              def __init__(self, pr_id, title, author, state, created, closed):
                  self.pr_id = pr_id
                  self.title = title
                  self.author = author
                  self.state = state
                  self.created = created
                  self.closed = closed
           
           
          def parse_date_ag_rest(date):
              return parser.isoparse(date).replace(tzinfo=None, microsecond=0)
           
           
          def get_date_from_timestamp(timestamp):
              return datetime.fromtimestamp(timestamp / 1000).replace(microsecond=0)
           
           
          def subtract_dates(minuend, subtrahend):
              if minuend is None or subtrahend is None:
                  return None
              else:
                  return round(((minuend - subtrahend).total_seconds() / 86400), 2)
           
           
          def get_pull_requests():
           
              pull_request_list = []
           
              get_prs_url = bitbucket_url + '/rest/awesome-graphs-api/latest/projects/' + project + '/repos/' + repository \
                  + '/pull-requests'
           
              is_last_page = False
           
              while not is_last_page:
           
                  response = s.get(get_prs_url, params={'start': len(pull_request_list), 'limit': 1000,
                                                        'sinceDate': since, 'untilDate': until}).json()
           
                  for pr_details in response['values']:
           
                      pd_id = pr_details['id']
                      title = pr_details['title']
                      author = pr_details['author']['user']['emailAddress']
                      state = pr_details['state']
                      created = parse_date_ag_rest(pr_details['createdDate'])
           
                      if pr_details['closed'] is True:
                          closed = parse_date_ag_rest(pr_details['closedDate'])
                      else:
                          closed = None
           
                      pull_request_list.append(PullRequest(pd_id, title, author, state, created, closed))
           
                  is_last_page = response['isLastPage']
           
              return pull_request_list
           
           
          def get_first_commit_time(pull_request):
           
              commit_dates = []
           
              commits_url = bitbucket_url + '/rest/api/latest/projects/' + project + '/repos/' + repository + '/pull-requests/' \
                  + str(pull_request.pr_id) + '/commits'
           
              is_last_page = False
           
              while not is_last_page:
           
                  commits_response = s.get(commits_url, params={'start': len(commit_dates), 'limit': 500}).json()
           
                  for commit in commits_response['values']:
                      commit_timestamp = commit['authorTimestamp']
                      commit_dates.append(get_date_from_timestamp(commit_timestamp))
           
                  is_last_page = commits_response['isLastPage']
           
              if not commit_dates:
                  first_commit = None
              else:
                  first_commit = commit_dates[-1]
           
              return first_commit
           
           
          def get_pr_activities(pull_request):
           
              counter = 0
              comment_dates = []
              approval_dates = []
           
              pr_url = bitbucket_url + '/rest/api/latest/projects/' + project + '/repos/' + repository + '/pull-requests/' \
                  + str(pull_request.pr_id) + '/activities'
           
              is_last_page = False
           
              while not is_last_page:
           
                  pr_response = s.get(pr_url, params={'start': counter, 'limit': 500}).json()
           
                  for pr_activity in pr_response['values']:
           
                      counter += 1
           
                      if pr_activity['action'] == 'COMMENTED':
                          comment_timestamp = pr_activity['comment']['createdDate']
                          comment_dates.append(get_date_from_timestamp(comment_timestamp))
                      elif pr_activity['action'] == 'APPROVED':
                          approval_timestamp = pr_activity['createdDate']
                          approval_dates.append(get_date_from_timestamp(approval_timestamp))
           
                      is_last_page = pr_response['isLastPage']
           
              if not comment_dates:
                  first_comment_date = None
              else:
                  first_comment_date = comment_dates[-1]
           
              if not approval_dates:
                  approval_time = None
              else:
                  approval_time = approval_dates[0]
           
              return first_comment_date, approval_time
           
           
          print('Collecting a list of pull requests from the repository', repository)
           
          with open(f'{project}_{repository}_prs_cycle_time_{since}_{until}.csv', mode='a', newline='') as report_file:
              report_writer = csv.writer(report_file, delimiter=',', quotechar='"', quoting=csv.QUOTE_MINIMAL)
              report_writer.writerow(['id',
                                      'title',
                                      'author',
                                      'state',
                                      'first_commit',
                                      'created',
                                      'first_comment',
                                      'approved',
                                      'closed',
                                      'cycle_time_d',
                                      'time_to_open_d',
                                      'time_to_review_d',
                                      'time_to_approve_d',
                                      'time_to_merge_d'])
           
              for pull_request in get_pull_requests():
           
                  print('Processing pull request', pull_request.pr_id)
           
                  first_commit_time = get_first_commit_time(pull_request)
           
                  first_comment, approval = get_pr_activities(pull_request)
           
                  cycle_time = subtract_dates(pull_request.closed, first_commit_time)
           
                  time_to_open = subtract_dates(pull_request.created, first_commit_time)
           
                  time_to_review = subtract_dates(first_comment, pull_request.created)
           
                  time_to_approve = subtract_dates(approval, first_comment)
           
                  time_to_merge = subtract_dates(pull_request.closed, approval)
           
                  report_writer.writerow([pull_request.pr_id,
                                          pull_request.title,
                                          pull_request.author,
                                          pull_request.state,
                                          first_commit_time,
                                          pull_request.created,
                                          first_comment,
                                          approval,
                                          pull_request.closed,
                                          cycle_time,
                                          time_to_open,
                                          time_to_review,
                                          time_to_approve,
                                          time_to_merge])
           
          print('The resulting CSV file is saved to the current folder.')
          <p>

          To make this script work, you’ll need to pre-install the requests and dateutil modules. The csvsys, and datetime modules are available in Python out of the box. You need to pass the following arguments to the script when executed:

          • the URL of your Bitbucket, 
          • login, 
          • password, 
          • project key, 
          • repository slug, 
          • since date (to include PRs created after), 
          • until date (to include PRs created before).

          Here’s an example:

          py script.py https://bitbucket.your-company-name.com login password PRKEY repo-slug 2020-11-30 2021-02-01

          Once the script’s executed, the resulting file will be saved to the same folder as the script.

          What to do with the report

          After you generated a CSV file, you can process it in analytics tools such as Tableau, PowerBI, Qlik, Looker, visualize this data on your Confluence pages with the Table Filter and Charts for Confluence app, or integrate it in any custom solution of your choice for further analysis. 

          An example of the data visualized with Table Filter and Charts for Confluence.

          By measuring Cycle Time, you can:

          • See objectively whether the development process is getting faster or slower.
          • Analyze the correlation of the specific metrics with the overall cycle time (e.g., pull requests that open faster, merge faster).
          • Compare the results of the particular teams and users within the organization or across the industry.

          What’s next?

          The report described in this article is built with the help of the Awesome Graphs for Bitbucket app as a data provider, available for Bitbucket Server and Data Center. Using it, you can gain more visibility into the development process to analyze patterns and find bottlenecks.

          If you want to learn more about how to use Cycle Time and the related metrics, write in the comments below and upvote this post, and we’ll show you how to visualize the data, what to look at and how to get insights from it in the future posts!

          Related posts