
Show HN: First Commit – find the first commit of any GitHub project - wonderfuly
http://first-commit.com/
======
HillaryBriss
The existence of a tool like first-commit makes me feel especially self
conscious about my earliest commits on GitHub repos. It adds to the perception
that one's initial checkin is somehow especially important (as opposed to the
bug infested, barely-compiling disasterpieces I usually checkin.)

Now, it's like: "Uh, oh, this initial checkin better be perfect. Someone will
scrutinize it with first-commit."

OTOH, no one has ever expressed any interest whatsoever in any of my GitHub
repos. I doubt even first-commit can change that.

~~~
Ao7bei3s
I always start with an empty commit[1] for two reasons:

1\. It's slightly harder to edit the first commit afterwards (say, to replace
a working title with the actual project title before publishing, or to fix
authorship or whatever).

2\. I create a _lot_ of small repos, all the time, so I have a shell alias for
"init, commit, add .gitignore, commit".

[1] git init && git commit --allow-empty -m 'Initial commit'

~~~
gioele
I prefer

    
    
        git init && git commit --allow-empty -m "$(basename (readlink -f .))"

~~~
fjarlq

      pwd -P
    

would be equivalent and more portable (POSIX compliant[1]) than

    
    
      readlink -f .
    

which doesn't work on BSD-based systems.

[1]:
[http://pubs.opengroup.org/onlinepubs/009696899/utilities/pwd...](http://pubs.opengroup.org/onlinepubs/009696899/utilities/pwd.html)

------
aleksi
Wow, Go has a really long history! [http://first-
commit.com/golang/go](http://first-commit.com/golang/go)

~~~
542458
Yeah, what's up with that? There are two 1970s and two 1980s commits in the
git repo before we hit the real golang stuff (in 2008!). All the old commits
do is author a c "hello world" program. Any idea why those are there?

[https://github.com/golang/go/commits/master?page=727](https://github.com/golang/go/commits/master?page=727)

EDIT: I just noticed that they're labeled as being by Brian Kernighan. What?

EDIT2: Oh, it's his _original_ hello world code:
[https://en.wikipedia.org/wiki/%22Hello,_World!%22_program](https://en.wikipedia.org/wiki/%22Hello,_World!%22_program)
What's it doing there? Just for novelty's sake?

~~~
david-given
It's probably an import from an early VCS for, as you say, novelty's sake.
They don't seemed to be connected to another other history (although it's very
hard to tell. Genuine question: why are github's revision visualisation tools
so shoddy? Getting from 'here is a checkin' to 'show me the history of one
specific file' seems far too hard...)

Here's one of my repos: [http://first-commit.com/davidgiven/ack](http://first-
commit.com/davidgiven/ack)

First checkin 1984. That's real history, too; those files, or their
descendants, are still in the current snapshot. Incidentally, not only does
that commit predate git, or the SVN repository I converted it from, but it
predates CVS itself... I've seen suggestions that the pile of shell scripts
which became CVS was actually _written_ for that project!

Not my code, I should add, I'm just looking after it. It's Andy Tanenbaum and
Cerial Jacobs' compiler toolchain, the Amsterdam Compiler Kit. Portable,
platform independent ANSI & K&R C, Pascal, Modula-2, Occam and Algol-68
development kit, complete with linkers, assemblers and libc...

------
FarhadG
Wow, this is awesome!!! I just made a bookmarklet (chrome extension coming
soon) for this very reason just a few days ago. Maybe we should
collaborate...?

Repo: [https://github.com/FarhadG/init](https://github.com/FarhadG/init) Demo:
[http://farhadg.github.io/init/landing/](http://farhadg.github.io/init/landing/)

~~~
zatkin
This is fundamentally broken if there is no master branch, or if the master
branch is not the branch that points to the last commit you made. i.e.
[https://github.com/antirez/redis](https://github.com/antirez/redis)

~~~
FarhadG
Fixed (regarding the master branch) and it already tracks the current branch
you're on. Go ahead and give it a whirl :)

I could add the functionality to determine which branch does actually have the
oldest commit, but I find it more intuitive and useful to go the first commit
of the current branch that you're on...

Thanks for the feedback.

------
jordanpg
Am I missing something?

Why is this tool interesting? Or, why is this tool useful?

Wasn't this already pretty easy to find if one was so inclined?

~~~
lol768
From what I can see following a quick cursory glance at the commit history
page for quite a large project
([https://github.com/twbs/bootstrap/commits/master](https://github.com/twbs/bootstrap/commits/master))
it's somewhat difficult to jump to the last page (earliest in terms of when
hey were made) of commits. That is unless I'm missing something obvious, of
course.

Sure, you can click older a bunch of times but it doesn't seem like there's a
button to jump to the last page of commits. I guess you could clone the repo
and look yourself using git log but this can be something of a hassle and
probably wouldn't always be possible depending on the device (I'm thinking
mobile devices, tablets etc).

You could probably guess a large page number, use it in the commit history URL
and chop it in half repeatedly until you don't get a 404 and then repeat from
there to try and find the last page of commits. Ultimately this is an issue
with how GitHub's commit history is designed though.

~~~
JasperBall
?

Just do something like:

    
    
        git rev-list --max-parents=0 HEAD

~~~
baby
This command doesn't make any sense to me. That's why I hate using git...

~~~
parennoob
Let me attempt an explanation.

'git rev-list' will give you the SHA-1 hashes of all the commits reachable
from a given commit. So 'git rev-list HEAD' is going to give you all commits
reachable from HEAD, i.e. your latest one all the way to your first commit.
After that, there's a bunch of ways you could filter that. For example, you
could run 'git rev-list HEAD | tail -1' to get the hash of the first commit,
and now all you need to do to show the whole diff is pipe it to 'xargs git
show' (xargs reads from stdin and uses that as the argument to whatever comes
after it.

The grandparent comment uses a slightly interesting trick – he/she used the
built-in '\--max-parents' filter. '\--max-parents' limits the number of parent
commits. For example, a merge has 2 or more parent commits, so the '\--max-
parents=1' option will exclude all merge commits. What commit has _no_
parents? Why, the first commit of the repo, of course.

Hence, the command 'git rev-list --max-parents=0 HEAD | xargs git show'.

------
yuvadam
Obligatory reference to the first bootstrap revision from hell - first git
commit of git! [1]

[1] -
[https://github.com/git/git/commit/e83c5163316f89bfbde7d9ab23...](https://github.com/git/git/commit/e83c5163316f89bfbde7d9ab23ca2e25604af290)

------
glaberficken
[http://first-commit.com/wong2/first-commit](http://first-
commit.com/wong2/first-commit)

couldn't resist =)

------
rafaqueque
Pretty cool. I also found this while ago:
[http://firstpr.me/](http://firstpr.me/) – shows your first pull request and
contribution to the open source community.

~~~
to3m
Well... assuming your first contribution doesn't predate github ;)

------
pedrocr
Seems to be rejecting this perfectly valid repo url:

[https://github.com/darktable-org/darktable](https://github.com/darktable-
org/darktable)

It appears to be the hyphen in the org name.

~~~
wonderfuly
it works for me: [http://first-commit.com/api/darktable-
org/darktable](http://first-commit.com/api/darktable-org/darktable)

~~~
pedrocr
I'm sure the code works fine but the interface throws up a "Not a valid Github
repo url" window and does nothing.

~~~
wonderfuly
oh, my fault. it has been fixed, thanks for your report!

~~~
pedrocr
_The first commit of darktable-org /darktable was created by @ on Tue Apr 07
2009_

Seems like you don't handle commits by users not recognized by github.

~~~
wonderfuly
hmm, will fix that

~~~
Amorymeltzer
Shows up pretty obviously with git, which is the first example

------
hodgesmr
If you'd like to do this in the terminal, clone the repo and:

    
    
      git rev-list --max-parents=0 HEAD | xargs git show

------
pinkunicorn
Any support for private github repos through authentication with Github?

~~~
FarhadG
The bookmarklet strategy was intended for this very reason when I made it:

[https://github.com/FarhadG/init](https://github.com/FarhadG/init)

------
wonderfuly
author here

~~~
brudgers
How does the code work?

~~~
jasode
I think _wonderfuly_ 's reply missed the point of the question which is to
explain it without having someone dissect the source code line by line.

Anyways, I did a quick look at the source file[1] and it looks like it depends
on the assumption of github returning 35 commit titles per page. From that, it
divides total # of commits by 35 to derive the url for the _last page_
containing the 1st commit. (The url you'd arrive at if you if you repeatedly
clicked the "Older" button on github to get to the final page which contains
the 1st commit.) It then scrapes that url for relevant data. (It uses the
cheerio library to help with scraping.)

I'm not familiar enough with github's HTML navigation and page formatting to
know if this method is fragile or robust. Github _does_ offer an API[2] so it
may be possible to get the 1st commit that way instead of scraping HTML that
was intended for display in a web browser.

Excerpt of the arithmetic:

    
    
      function getFirstPageUrl(repo, num_of_commits) {
        const COMMITS_PER_PAGE = 35;
        var first_page = Math.ceil(num_of_commits / COMMITS_PER_PAGE);
        return `${BASE_URL}/${repo}/commits?page=${first_page}`;
      }
    
    

[1][https://github.com/wong2/first-
commit/blob/master/app/github...](https://github.com/wong2/first-
commit/blob/master/app/github.js#L37)

[2][https://developer.github.com/v3/git/commits/](https://developer.github.com/v3/git/commits/)

~~~
brudgers
Yes, my intent was to provide the author a chance to talk about their work and
share their enthusiasm. It's why I asked about code, since the answer "to how
does it work?" is "type the repository url into the box".

