Git and log order -


i trying create linear order "git log" output, attempts failed. need map commit next release contains commit. cannot run

git tag --contains <commit> 

for each commit, our repository contains extremely large amount of commits (more 300,000).

first tried using

git log --pretty=format:"%ct%h" | sort --key=1,10  

to obtain linear order based on commit time. however, not seem produce 100% accurate result. leads first question:

q1) how git store commit times, when commits pushed main repository? store current machine time each commit, in utc?

i looked @ "git log", , documentation states default, git log lists commits in chronological order. in project, checked whether introducing error, far can tell, code correct, , chronological order given git log not linear order. finally, question is?

q2) how can 1 obtain linear order "git log", given git not store revision numbers?

thanks :)

#1: how git store commit times, when commits pushed main repository? store current machine time each commit, in utc?

from man git-commit:

git internal format
[unix timestamp] [timezone offset], [unix timestamp] number of seconds since unix epoch. [timezone offset] positive or negative offset utc.

based on this, git internally-used time-format unix epoch time, including machines utc offset.

#2: how can 1 obtain linear order "git log", given git not store revision numbers?

the method you've used (git log --pretty=format:"%ct%h") pull data all branches have been merged current branch.

this makes "linear order" difficult. consider following [source: git-scm.org]:

multiple branches, pre-merge

so, here we've got several 'topic branches' being worked on. decide keep (dumbidea , iss91v2), discarding others (iss91). we're discarding c5 , c6, keeping other commits, , our post-merge history looks [source: git-scm.org]:

post-merge

(arrows point from children to parents; c14 child of commits c13 , c11).

so we've got single head commit which, arguments sake, we'll assume we're going release release1 or something. so, question: how can now, having history, extract linear, chronologically correct list of commits?

simple answer: don't believe can - or, if do, don't believe it'll want.

you could sort commits linearly, time:

git log --pretty=format:"%ct %h" | sort --key=1,10 

that'll give list corresponding to:

c1 c2 ... snip ... c13 c14 

note, however, isn't linear history! because we've merged branches together, created at same time. can't extract linear history of parents of c14 (our head), because there isn't 1 - it's child of 2 branches, not child of single commit, , isn't linear relationship.

so, argue, perhaps linear history of 1 branch? c14 -> c13 ... c3 -> c1, example?

this, too, @ minimum difficult , (more likely) impossible.

this problem compounded when we've got multiple branches joining (3- or more-way merges). this question goes more detail of reasons can't extract history of 'single branch' - when you're looking @ parents of merge-commit, how decide 'single branch' , 'joining-in' branch?


having said that, if examine, example, logs little repository, in graph format: (i did snip few commits weren't useful)

 zsh% git log --graph --all --format=format:'%c(blue)%h%c(reset) - %c(green)(%cr)%c(reset)                %c(yellow)%d%c(reset)' --abbrev-commit --date=relative * 3cf5f06 - (8 weeks ago)  (origin/master, origin/head, master) * a3a3205 - (4 months ago)  * c033bf9 - (4 months ago)  (origin/svg) * ccee435 - (4 months ago)  *   f08bc1e - (4 months ago)  |\   | * 48c4406 - (5 months ago)  * | 203eeaa - (4 months ago)  * | 5fb0ea9 - (5 months ago)  |/   * 39bccb8 - (5 months ago) 

note history is in chronological order; branches haven't been 'flattened' one, though, looks little funky. each of these commits contained in current head (master, origin/master). obvious, because both of forks in history have been merged (the merge @ f08bc1e).

#3: need map commit next release contains commit

if you're interested in individual commit, this question, or if releases tagged help.

reading question, appears may want map each commit release; that's lot of work, , can't - don't think need check each commit, though, because branches merged in, , if head of linear branch in release, linear parents be. unless you've done cherry-picking, or similar.

if sorted time, checked commits older oldest release, recording commit id if included in oldest, second oldest, etc, , removing commit list when find release contains it, you'll have check @ number of releases * number of commits; @ worst case, no commit in release. best case, releases contain every commit older itself, 300,000 checks. still lot, (to naive mind), doable.

(apologies long reply).


Comments

Popular posts from this blog

java - Play! framework 2.0: How to display multiple image? -

gmail - Is there any documentation for read-only access to the Google Contacts API? -

php - Controller/JToolBar not working in Joomla 2.5 -