This article covers how to hack the activity graph that appears on each github user’s profile using fake commits.

an example of a "full" github contribution graph Above is an example of the aforementioned github contribution graph.

The graph is generated by the number of commits matching a user’s email and username. Due to this it is possible to add contributions by generating commits.

Below is a node js script which will generate these fake commits. In order to use this to generate your own commits update the AUTHOR, EMAIL, and DAYS_TO_GENERATE constants to match your github username, email, and number of days you wish to generate commits for, respectively. You will also need a version of node js that supports async/await.

The easiest way to use this script is to fork the following repo, BrianDGLS/sneaky-contrib-repo. Once forked, clone the forked version of the repo. You can then run node generate_contribs, after updating the constants mentioned above and copying down into the cloned folder. Assuming all works well your fake commits will be generated. You can then run git push to make the commits visible in your github contribution graph.

const { join } = require('path')
const { writeFile } = require('fs')
const { promisify } = require('util')
const { exec } = require('child_process')

const execAsync = promisify(exec)
const writeFileAsync = promisify(writeFile)

const AUTHOR = 'username'
const EMAIL = 'email'
const DAYS_TO_GENERATE = 365

const dateMinusGivenDays = days => {
  const d = new Date()
  d.setDate(d.getDate() - days)
  return d

const touchFile = async path => await writeFileAsync(path, Math.random())

const addChange = async change => await execAsync(`git add ${change}`)

const makeCommitInPast = async (date, message) =>
  await execAsync(`GIT_AUTHOR_DATE='${date}' GIT_COMMITTER_DATE='${date}' git commit --author='${AUTHOR} <${EMAIL}>' -m '${message}'`)

const applyChanges = async limit => {
  const file = join(__dirname, 'temp.txt')
  const date = dateMinusGivenDays(limit)
  await touchFile(file)
  await addChange(file)
  await makeCommitInPast(date, Math.random())

const execute = async count => {
  while (count--) await applyChanges(count)