15

how can I know when a git branch was created?

i don't want to know when was the first commit to that branch. I want to find out when that branch was created.

This is a script to reproduce a working example:

#! /bin/bash
set -x
set -e

mkdir test
cd test
git init
echo "hello" >readme
git add readme
git commit -m "initial import"
date

sleep 5
git checkout -b br1
date                   # this is the date that I want to find out.

sleep 5
echo "hello_br1" >readme
git commit -a -m "hello_br1"
date

echo "hello_br1_b" >readme
git commit -a -m "hello_br1_b"

git checkout master
echo "hello_master" >readme
git commit -a -m "hello_master"

git branch -a; 
git log --all --graph --abbrev-commit --decorate --pretty=format:"%h - %an, %ad : %s" --date=iso

Executing this:

./test.sh 
++ set -e
++ mkdir test
++ cd test
++ git init
Initialized empty Git repository in /test_git/test2/.git/
++ echo hello
++ git add readme
++ git commit -m 'initial import'
[master (root-commit) 9b95944] initial import
 1 files changed, 1 insertions(+), 0 deletions(-)
 create mode 100644 readme
++ date
Fri Aug 16 17:51:24 CEST 2013
++ sleep 5
++ git checkout -b br1
Switched to a new branch 'br1'
++ date
Fri Aug 16 17:51:29 CEST 2013
++ sleep 5
++ echo hello_br1
++ git commit -a -m hello_br1
[br1 6c559cd] hello_br1
 1 files changed, 1 insertions(+), 1 deletions(-)
++ date
Fri Aug 16 17:51:34 CEST 2013
++ echo hello_br1_b
++ git commit -a -m hello_br1_b
[br1 5f0d8ab] hello_br1_b
 1 files changed, 1 insertions(+), 1 deletions(-)
++ git checkout master
Switched to branch 'master'
++ echo hello_master
++ git commit -a -m hello_master
[master 2ed092d] hello_master
 1 files changed, 1 insertions(+), 1 deletions(-)
++ git branch -a
  br1
* master
++ git log --all --graph --abbrev-commit --decorate '--pretty=format:%h - %an, %ad : %s' --date=iso
* 5f0d8ab - David Portabella, 2013-08-16 17:51:34 +0200 : hello_br1_b
* 6c559cd - David Portabella, 2013-08-16 17:51:34 +0200 : hello_br1
| * 2ed092d - David Portabella, 2013-08-16 17:51:34 +0200 : hello_master
|/  
* 9b95944 - David Portabella, 2013-08-16 17:51:24 +0200 : initial import

so, with git log, or git reflog, I can find out the date of the initial import (17:51:24) and the date of the first commit to the branch br1 (17:51:34).

but I need to find out when the branch br1 was created (17:51:29).

how to do that?

(bonus question: and, does it have a hash? how to know who created that branch)

David Portabella
  • 12,390
  • 27
  • 101
  • 182
  • See also (1) [Find common ancestor of two branches](http://stackoverflow.com/questions/1549146/find-common-ancestor-of-two-branches), (2) [Finding a branch point with Git?](http://stackoverflow.com/questions/1527234/finding-a-branch-point-with-git), and (3) [Branch length: where does a branch start in Git?](http://stackoverflow.com/questions/17581026/branch-length-where-does-a-branch-start-in-git). –  Aug 16 '13 at 16:51
  • Possible duplicate of [How to determine when a Git branch was created?](http://stackoverflow.com/questions/2255416/how-to-determine-when-a-git-branch-was-created) – phuclv Apr 24 '17 at 06:27

3 Answers3

37

Sorry, but Git doesn't keep officially tracked information of when branches are created (it's not data that stored and shared among repositories). Branches are simply references to commits and nothing more. This also means that there is no id or object that will point you at this data.

The reflog does keep track of when changes are made to a branch, but it's only a limited history that expires over time. It does record some information though. For instance, git branch bar resulted in this entry in the reflog:

:: git reflog show --date=iso bar
7d9b83d bar@{2013-08-16 12:23:28 -0400}: branch: Created from master

I also see a similar entry when using git checkout -b bar:

:: git co -b bar
Switched to a new branch 'bar'
:: git reflog show --date=iso bar
d6970ef bar@{2013-08-16 12:30:50 -0400}: branch: Created from HEAD

So, depending on your use-case, and how far back you need to dig, git reflog may actually be useful for you.

John Szakmeister
  • 44,691
  • 9
  • 89
  • 79
  • this command shows indeed the information i needed (at least the date), thanks. it's a pity that it does not store this info officialy, and forever. why it wouldn't do that? why would someone decide that it is not important to know who created a branch and when? anyway, do you know a trick to do the same for a remote repository? (the trick didn't work when i wanted to find out who created a branch in a remote repository) – David Portabella Aug 16 '13 at 20:30
  • 2
    Unfortunately, I don't think we have the same trick on the remote repo. The reflog is local to a repo. On the remote end, you can probably see a branch being created to, but as part of a push, and it would have that timestamp (not the one when the author created it). As for why Git doesn't keep track of that, there was a discussion about it on the git mailing list recently, so I won't rehash it. I'll dig up a link and post it here later (I have to run right now). The short form: they didn't consider it valuable enough to keep around. – John Szakmeister Aug 16 '13 at 20:40
  • git reflog show --date=iso branch-name worked for me – Vishal Kottarathil Jun 14 '19 at 05:45
  • For folks who are interested, I have a script that attempts to find the branch point: https://github.com/jszakmeister/etc/blob/master/git-addons/git-branch-point. You need to have some idea of where it branched from, but it does a pretty decent job of locating the commit you branched from. Again, Git isn't perfect here because it doesn't track that data. :-) – John Szakmeister Jun 14 '19 at 09:25
10

You can neither find out who created a branch, nor when it was created -- at least not with Git itself.

Because Git does not track branch metadata. It simply does not care about who made a branch (you usually get lots of branches from remotes), since branches are just pointers (refs) to commits.

Thus a branch also does not have a branch -- a Git ref is, in fact, simply a plain text file in your .git folder containing the hash of the object it references (or, in case of a symbolic ref, the name of the other ref it references).

Nevik Rehnel
  • 49,633
  • 6
  • 60
  • 50
0

As the other answers point out, git doesn't keep track of the commit where a branch ref was first created.

For awhile, I was using the following trick to find the previous branchpoint:

git rev-list --simplify-by-decoration -2 HEAD | tail -n 1

While that yields the previous branch point above your current branch, it's not necessarily the branch-point of when you created your current branch. For example, I was doing some work on a branch and I wanted to come back to some debug code before I deleted it in the current branch, so I made a branch, switched back to my working branch and continued on... When I'm on that working branch and run the above code, it yields that debug-code branch-point.

I use bash aliases/functions for common git use-cases, and I have functions for creating and deleting branches. I also have a function that allows me to obtain the branchpoint commit where the current branch was first created. This is a simplified version of my bash functions/aliases:

branchpointfun() {
  CURB=`git rev-parse --abbrev-ref HEAD`
  BRANCHPOINTVAR=BRANCHPOINT_OF_${CURB}
  # If a branchpoint variable exists for the current branch
  if [[ -v ${BRANCHPOINTVAR} ]]; then
    echo ${!BRANCHPOINTVAR}
  else
    git rev-list --simplify-by-decoration -2 HEAD | tail -n 1
  fi
}
alias branchpoint=branchpointfun

branchfun() {
  NAME="$@";
  if [ "$NAME" != "" ]; then
    # Record where this branchpoint started in order to do diffs and linting with it later
    CURCOMMIT=`git rev-parse HEAD`
    export declare BRANCHPOINT_OF_${NAME}=$CURCOMMIT
    echo "export BRANCHPOINT_OF_${NAME}=$CURCOMMIT" >> $VARSFILE
    # Now create the branch
    git checkout -b $NAME;
  fi
}
alias branch=branchfun

closefun() {
  CURB=`git rev-parse --abbrev-ref HEAD`;
  SELBR=`git branch --merged | grep -E "^  $@" | cut -d " " -f 3`;
  git branch -d $SELBR;
  BRANCHPOINTVAR=BRANCHPOINT_OF_${SELBR}
  # If a branchpoint variable exists for the branch being removed
  if [[ -v ${BRANCHPOINTVAR} ]]; then
    unset ${BRANCHPOINTVAR}
    grep -v "^${BRANCHPOINTVAR}=" $VARSFILE > $VARSFILE
  fi
}
alias close=closefun

Anytime I want the branchpoint of the current branch, I just issue the command branchpoint.

I removed a lot of my custom code that's unrelated to the branch point issue and have not tested this streamlined version, so it may not work as-written if I overlooked something. Note that my bashrc sources the $VARSFILE so that the branch points persist between terminal sessions.

I use the branchpoint in order to assess progress on a current branch via git diff and I use it to lint only changed files since branching, with super-linter.

hepcat72
  • 890
  • 4
  • 22