@@ -269,18 +269,33 @@ define(['d3'], function () {
269269 * @return {Object } the commit datum object
270270 */
271271 getCommit : function getCommit ( ref ) {
272+ // Optimization, doesn't seem to break anything
273+ if ( ! ref ) return null ;
274+
272275 var commitData = this . commitData ,
273- headMatcher = / H E A D ( \^ + ) / . exec ( ref ) ,
274276 matchedCommit = null ;
275277
278+ var parts = / ^ ( [ ^ \^ \~ ] + ) ( .* ) $ / . exec ( ref ) ,
279+ ref = parts [ 1 ] ,
280+ modifier = parts [ 2 ] ;
281+
276282 if ( ref === 'initial' ) {
277283 return this . initialCommit ;
278284 }
279285
280- if ( headMatcher ) {
286+ if ( ref . toLowerCase ( ) === 'head' ) {
281287 ref = 'HEAD' ;
282288 }
283289
290+ var commitsThatStartWith = commitData
291+ . filter ( function ( c ) { return c . id . indexOf ( ref ) === 0 } )
292+
293+ if ( commitsThatStartWith . length === 1 ) {
294+ return commitsThatStartWith [ 0 ]
295+ } else if ( commitsThatStartWith . length > 1 ) {
296+ throw new Error ( "Ref " + ref + " is ambiguous" )
297+ }
298+
284299 for ( var i = 0 ; i < commitData . length ; i ++ ) {
285300 var commit = commitData [ i ] ;
286301 if ( commit === ref ) {
@@ -293,14 +308,14 @@ define(['d3'], function () {
293308 break ;
294309 }
295310
296- var matchedTag = function ( ) {
311+ var matchedTag = function ( ) {
297312 for ( var j = 0 ; j < commit . tags . length ; j ++ ) {
298313 var tag = commit . tags [ j ] ;
299314 if ( tag === ref ) {
300315 matchedCommit = commit ;
301316 return true ;
302317 }
303-
318+
304319 if ( tag . indexOf ( '[' ) === 0 && tag . indexOf ( ']' ) === tag . length - 1 ) {
305320 tag = tag . substring ( 1 , tag . length - 1 ) ;
306321 }
@@ -315,10 +330,35 @@ define(['d3'], function () {
315330 }
316331 }
317332
318- if ( headMatcher && matchedCommit ) {
319- for ( var h = 0 ; h < headMatcher [ 1 ] . length ; h ++ ) {
320- matchedCommit = getCommit . call ( this , matchedCommit . parent ) ;
333+ if ( matchedCommit && modifier ) {
334+ while ( modifier ) {
335+ var nextToken = modifier [ 0 ]
336+ modifier = modifier . substr ( 1 )
337+ var amountMatch = modifier . match ( / ^ ( \d + ) ( .* ) $ / ) ,
338+ amount = 1 ;
339+
340+ if ( amountMatch ) {
341+ var amount = ~ ~ amountMatch [ 1 ]
321342 }
343+
344+ if ( nextToken === '^' ) {
345+ if ( amount === 0 ) {
346+ /* do nothing, refers to this commit */
347+ } else if ( amount === 1 ) {
348+ matchedCommit = this . getCommit ( matchedCommit . parent )
349+ } else if ( amount === 2 ) {
350+ matchedCommit = this . getCommit ( matchedCommit . parent2 )
351+ } else {
352+ matchedCommit = null
353+ }
354+ } else if ( nextToken === '~' ) {
355+ for ( var i = 0 ; i < amount ; i ++ ) {
356+ if ( matchedCommit && matchedCommit . parent ) {
357+ matchedCommit = this . getCommit ( matchedCommit . parent )
358+ }
359+ }
360+ }
361+ }
322362 }
323363
324364 return matchedCommit ;
@@ -360,7 +400,7 @@ define(['d3'], function () {
360400 svgContainer = container . append ( 'div' )
361401 . classed ( 'svg-container' , true )
362402 . classed ( 'remote-container' , this . isRemote ) ;
363-
403+
364404 svg = svgContainer . append ( 'svg:svg' ) ;
365405
366406 svg . attr ( 'id' , this . name )
@@ -417,7 +457,7 @@ define(['d3'], function () {
417457 preventOverlap ( commit , this ) ;
418458 }
419459 } ,
420-
460+
421461 _resizeSvg : function ( ) {
422462 var ele = document . getElementById ( this . svg . node ( ) . id ) ;
423463 var container = ele . parentNode ;
@@ -453,7 +493,7 @@ define(['d3'], function () {
453493 this . _renderMergePointers ( ) ;
454494 this . _renderIdLabels ( ) ;
455495 this . _resizeSvg ( ) ;
456- this . checkout ( this . currentBranch ) ;
496+ this . currentBranch && this . checkout ( this . currentBranch ) ;
457497 } ,
458498
459499 _renderCircles : function ( ) {
@@ -726,8 +766,8 @@ define(['d3'], function () {
726766 newTags . append ( 'svg:text' )
727767 . text ( function ( d ) {
728768 if ( d . name . indexOf ( '[' ) === 0 && d . name . indexOf ( ']' ) === d . name . length - 1 )
729- return d . name . substring ( 1 , d . name . length - 1 ) ;
730- return d . name ;
769+ return d . name . substring ( 1 , d . name . length - 1 ) ;
770+ return d . name ;
731771 } )
732772 . attr ( 'y' , function ( d ) {
733773 return tagY ( d , view ) + 14 ;
@@ -815,19 +855,23 @@ define(['d3'], function () {
815855
816856 commit . message = message ;
817857 if ( ! commit . parent ) {
818- if ( ! this . currentBranch ) {
819- throw new Error ( 'Not a good idea to make commits while in a detached HEAD state.' ) ;
820- }
821-
822- commit . parent = this . getCommit ( this . currentBranch ) . id ;
858+ commit . parent = this . getCommit ( 'HEAD' ) . id ;
823859 }
824860
825861 this . commitData . push ( commit ) ;
826- this . moveTag ( this . currentBranch , commit . id ) ;
862+ if ( this . currentBranch ) {
863+ this . moveTag ( this . currentBranch , commit . id ) ;
864+ }
827865
828866 this . renderCommits ( ) ;
829867
830- this . checkout ( this . currentBranch ) ;
868+ if ( this . currentBranch ) {
869+ console . log ( 'branch' , this . currentBranch )
870+ this . checkout ( this . currentBranch ) ;
871+ } else {
872+ console . log ( 'commit' , commit . id )
873+ this . checkout ( commit . id )
874+ }
831875 return this ;
832876 } ,
833877
@@ -887,6 +931,7 @@ define(['d3'], function () {
887931 } ,
888932
889933 checkout : function ( ref ) {
934+ console . log ( "checking out" , ref )
890935 var commit = this . getCommit ( ref ) ;
891936
892937 if ( ! commit ) {
@@ -900,7 +945,9 @@ define(['d3'], function () {
900945 previousHead . classed ( 'checked-out' , false ) ;
901946 }
902947
903- this . _setCurrentBranch ( ref === commit . id ? null : ref ) ;
948+ var startsWithCommit = commit . id . indexOf ( ref ) === 0
949+ var startsWithHead = ref . toLowerCase ( ) . indexOf ( 'head' ) === 0
950+ this . _setCurrentBranch ( startsWithCommit || startsWithHead ? null : ref ) ;
904951 this . moveTag ( 'HEAD' , commit . id ) ;
905952 this . renderTags ( ) ;
906953
@@ -969,9 +1016,9 @@ define(['d3'], function () {
9691016 while ( branchStartCommit . parent !== currentCommit . id ) {
9701017 branchStartCommit = this . getCommit ( branchStartCommit . parent ) ;
9711018 }
972-
1019+
9731020 branchStartCommit . isNoFFBranch = true ;
974-
1021+
9751022 this . commit ( { parent2 : mergeTarget . id , isNoFFCommit : true } ) ;
9761023 } else if ( this . isAncestor ( currentCommit , mergeTarget ) ) {
9771024 this . fastForward ( mergeTarget ) ;
0 commit comments