Confused by user info, timestamps, and urls in Commit objects

Dear GitHub Support Community,

As I continue to learn the GitHub GraphQL API, I have used the following sample query with the gql library for Python:

query {
  repository(owner: "github", name: "linguist") {
    refs(query: "dev", refPrefix: "refs/heads/", first: 1) {
      edges {
        node {
          target {
            ... on Commit {
              history(first: 5, after: null) {
                edges {
                  node {
                    oid
                    commitUrl
                    url
                    authoredByCommitter
                    authoredDate
                    author {
                      user {
                        email
                        login
                        name
                        twitterUsername
                      }
                      date
                    }
                    committedDate
                    committer {
                      user {
                        email
                        login
                        name
                        twitterUsername
                      }
                      date
                    }
                  }
                }
                pageInfo {
                  hasNextPage
                  endCursor
                }
              }
            }
          }
        }
      }
    }
  }
}

And here is the API response:

Click to expand API response
{
  "data": {
    "repository": {
      "refs": {
        "edges": [
          {
            "node": {
              "target": {
                "history": {
                  "edges": [
                    {
                      "node": {
                        "oid": "994bc1f13560661f94c880845c967c91116e2f87",
                        "commitUrl": "https://github.com/github/linguist/commit/994bc1f13560661f94c880845c967c91116e2f87",
                        "url": "https://github.com/github/linguist/commit/994bc1f13560661f94c880845c967c91116e2f87",
                        "authoredByCommitter": false,
                        "authoredDate": "2017-05-03T13:49:26Z",
                        "author": {
                          "user": {
                            "email": "",
                            "login": "lildude",
                            "name": "Colin Seymour",
                            "twitterUsername": null
                          },
                          "date": "2017-05-03T14:49:26+01:00"
                        },
                        "committedDate": "2017-05-03T13:49:26Z",
                        "committer": {
                          "user": null,
                          "date": "2017-05-03T14:49:26+01:00"
                        }
                      }
                    },
                    {
                      "node": {
                        "oid": "44f03e64c1f79dc03f67a1e63192c59932ed7147",
                        "commitUrl": "https://github.com/github/linguist/commit/44f03e64c1f79dc03f67a1e63192c59932ed7147",
                        "url": "https://github.com/github/linguist/commit/44f03e64c1f79dc03f67a1e63192c59932ed7147",
                        "authoredByCommitter": false,
                        "authoredDate": "2017-04-29T09:15:39Z",
                        "author": {
                          "user": {
                            "email": "gardnerjohng@gmail.com",
                            "login": "Alhadis",
                            "name": "John Gardner",
                            "twitterUsername": null
                          },
                          "date": "2017-04-29T19:15:39+10:00"
                        },
                        "committedDate": "2017-04-29T09:15:39Z",
                        "committer": {
                          "user": {
                            "email": "paul.chaignon@gmail.com",
                            "login": "pchaigno",
                            "name": "Paul Chaignon",
                            "twitterUsername": "pchaigno"
                          },
                          "date": "2017-04-29T11:15:39+02:00"
                        }
                      }
                    },
                    {
                      "node": {
                        "oid": "4166f2e89d3e0d0d21e67ac5677a56a4efaa8221",
                        "commitUrl": "https://github.com/github/linguist/commit/4166f2e89d3e0d0d21e67ac5677a56a4efaa8221",
                        "url": "https://github.com/github/linguist/commit/4166f2e89d3e0d0d21e67ac5677a56a4efaa8221",
                        "authoredByCommitter": false,
                        "authoredDate": "2017-04-28T23:20:22Z",
                        "author": {
                          "user": {
                            "email": "",
                            "login": "jelder",
                            "name": "Jacob Elder",
                            "twitterUsername": null
                          },
                          "date": "2017-04-28T19:20:22-04:00"
                        },
                        "committedDate": "2017-04-28T23:20:22Z",
                        "committer": {
                          "user": {
                            "email": "",
                            "login": "lildude",
                            "name": "Colin Seymour",
                            "twitterUsername": null
                          },
                          "date": "2017-04-28T16:20:22-07:00"
                        }
                      }
                    },
                    {
                      "node": {
                        "oid": "1a8f19c6f28b4ad9acb20351a323aa1fc8e4b26e",
                        "commitUrl": "https://github.com/github/linguist/commit/1a8f19c6f28b4ad9acb20351a323aa1fc8e4b26e",
                        "url": "https://github.com/github/linguist/commit/1a8f19c6f28b4ad9acb20351a323aa1fc8e4b26e",
                        "authoredByCommitter": false,
                        "authoredDate": "2017-04-28T21:02:38Z",
                        "author": {
                          "user": {
                            "email": "gardnerjohng@gmail.com",
                            "login": "Alhadis",
                            "name": "John Gardner",
                            "twitterUsername": null
                          },
                          "date": "2017-04-29T07:02:38+10:00"
                        },
                        "committedDate": "2017-04-28T21:02:38Z",
                        "committer": {
                          "user": {
                            "email": "",
                            "login": "lildude",
                            "name": "Colin Seymour",
                            "twitterUsername": null
                          },
                          "date": "2017-04-28T14:02:38-07:00"
                        }
                      }
                    },
                    {
                      "node": {
                        "oid": "c0e242358af6a3ad0ace66e29b480d3f507917cb",
                        "commitUrl": "https://github.com/github/linguist/commit/c0e242358af6a3ad0ace66e29b480d3f507917cb",
                        "url": "https://github.com/github/linguist/commit/c0e242358af6a3ad0ace66e29b480d3f507917cb",
                        "authoredByCommitter": false,
                        "authoredDate": "2017-04-26T22:31:36Z",
                        "author": {
                          "user": {
                            "email": "santi@mola.io",
                            "login": "smola",
                            "name": "Santiago M. Mola",
                            "twitterUsername": null
                          },
                          "date": "2017-04-27T00:31:36+02:00"
                        },
                        "committedDate": "2017-04-26T22:31:36Z",
                        "committer": {
                          "user": {
                            "email": "",
                            "login": "lildude",
                            "name": "Colin Seymour",
                            "twitterUsername": null
                          },
                          "date": "2017-04-26T15:31:36-07:00"
                        }
                      }
                    }
                  ],
                  "pageInfo": {
                    "hasNextPage": true,
                    "endCursor": "994bc1f13560661f94c880845c967c91116e2f87 4"
                  }
                }
              }
            }
          }
        ]
      }
    }
  }
}

I am confused about the seemingly subtle differences between some of the fields, specifically:

  1. What is the difference between author and committer in the API response? Do their meanings differ in Git vs GitHub? For example, the second commit’s page shows that " Alhadis authored and pchaigno committed on Apr 29, 2017". What real-life scenarios would lead to this? As a beginner Git user I’ve never encountered anything like this.
  2. From what I can tell, a Commit from the API response can include multiple timestamps such as authoredDate, committedDate, and the date under author and committer. They are identical in the response I got from my sample query above, but what would lead to them being different? And which one is shown on a commit’s commitUrl page?
  3. On that note, what is the difference between commitUrl and url in a Commit?
  4. In the first commit of the API response I got (commit 994bc1f), it says authoredByCommitter is False and that the committer is null! (there is only information on the author) Why is this? How can there be no committer? If I follow the commitUrl I see that “lildude committed on May 3, 2017” so presumably user lildude should be the committer and authoredByCommitter should be True?

Sorry for all the questions, hope someone can help elucidate these details! Thank you! :grin:

GitHub uses the metadata created by Git in a commit to present the respective author and committer information for a commit.

When using Git on the command line, it’s possible to specify an author of the commit who is not the committer themselves. This practice was common before pull requests and Git-hosting providers existed, where a contributor would submit a patch file to the mailing list and a committer would review the patch before committing it to the repository on behalf of the author.

Drawing from the Git SCM - 2.3 Git Basics - Viewing the Commit History:

You may be wondering what the difference is between author and committer . The author is the person who originally wrote the work, whereas the committer is the person who last applied the work. So, if you send in a patch to a project and one of the core members applies the patch, both of you get credit — you as the author, and the core member as the committer.

Extending from the earlier explanation, it’s possible for an author to write the changes at a different time than when they’re committed. committer.date is used (though that’s subject to change at anytime––we suggest using the API to check based on what you’re looking for).

Looking at the Commit reference documentation:

  • commitUrl ( URI! ) The HTTP URL for this Git object.
  • url ( URI! ) The HTTP URL for this commit.

The GitObject interface is implemented by Commit. Thus, commitUrl is shared among its other implementations (like Blob, Tag, and Tree) while having its own url. In any case, you’re welcome to use either interchangeably.

authoredByCommitter is False because the author and committer information don’t match.

We can inspect that particular commit by making a request to either of these endpoints:

I made the following calls and extracted the respective author and committer fields here:

// truncated for brevity
{
  // ...
  "author": {
    "name": "Colin Seymour",
    "email": "colin@github.com",
    "date": "2017-05-03T13:49:26Z"
  },
  "committer": {
    "name": "GitHub",
    "email": "noreply@github.com",
    "date": "2017-05-03T13:49:26Z"
  },
  // ...
}
// truncated for brevity
{
  // ...
  "commit": {
    "author": {
      "name": "Colin Seymour",
      "email": "colin@github.com",
      "date": "2017-05-03T13:49:26Z"
    },
    "committer": {
      "name": "GitHub",
      "email": "noreply@github.com",
      "date": "2017-05-03T13:49:26Z"
    },
  // ... 
}

In cases like these, it’s possible that this commit was created through the GitHub web flow (like editing a file and committing the changes, or pressing the merge button to merge the changes proposed in a pull request). Building from that context, this guide explains why commits may not be linked to any user.

Does that help explain things?

1 Like

Ah I didn’t know that. Great to know that there’s flexibility in how to provide attribution and credit in Git.

committer.date is used (though that’s subject to change at anytime––we suggest using the API to check based on what you’re looking for).

The GitObject interface is implemented by Commit . Thus, commitUrl is shared among its other implementations (like Blob , Tag , and Tree ) while having its own url . In any case, you’re welcome to use either interchangeably.

OK.

In cases like these, it’s possible that this commit was created through the GitHub web flow (like editing a file and committing the changes, or pressing the merge button to merge the changes proposed in a pull request).

It’s a bit counterintuitive to me, since I’d think in this case the user would be attributed to as the committer instead of author, but that’s OK. As long as I know which one’s which that’s great.

Does that help explain things?

Yes, thank you! :pray:t5:

1 Like