Currently, we use the following --pretty custom format string in the log parser to output commit data for parsing and capturing:
git show --numstat --summary --pretty=format:"%H%n%P%n%aN <%ae>%n%cN <%ce>%n%ct%n%s%n%b%nENDOFOUTPUTGITMESSAGEHERE"
For a commit object, this outputs something like the following:
$ git show --numstat --summary --pretty=format:"%H%n%P%n%aN <%ae>%n%cN <%ce>%n%ct%n%s%n%b%nENDOFOUTPUTGITMESSAGEHERE" 435fa3
435fa3a3b41d81ef557f720246a21c93d324da81 # commit id
a48b3a85b0f87cae7c9755ee007dd705b71b32aa # parent commit id
Sam Boyer <drupal@samboyer.org> # author info
Sam Boyer <drupal@samboyer.org> # committer info
1281119399 # timestamp
So the SelectQuery::join() method isn't chainable. Who knew. # commit message
ENDOFOUTPUTGITMESSAGEHERE # fugly delimiter
4 4 includes/controllers.inc # diffstat
Under a lot of circumstances, this is OK, and when I initially commit the entities refactor/the git log parser refactor, I'm going to leave it like this, but it's critical we fix it. There are several issues with that command as it currently exists, though only the last one (merging) is critical:
We don't deal smartly with dates.
Right now, dates are just dealt with as straight timestamps. AFAIK, there's no timezone conversion that happens when they're shown in this way, which means that we might have problems if commits come in from different timezones but we don't do proper timezone handling on the d.o side when we're parsing the metadata into our db.
The delimiter is fugly.
Using ENDOFGIT... whatever is not the way to do things. We need to look into using NUL chars more, probably, as that's the option provided by -z. Though that's not perfect, either.
It does not even pretend to capture full merge data.
If that command is passed a merge commit, it will output the numstat for only a single parent commit, e.g. for the merge commit 32d5d:
$ git show --numstat --summary --pretty=format:"%H%n%P%n%aN <%ae>%n%cN <%ce>%n%ct%n%s%n%b%nENDOFOUTPUTGITMESSAGEHERE" 32d5d
32d5d3d0ab8eabb812fedef73f6dd1f4e74c288b
e111ad0f0165c1b85def0dc89005c36be420793d 46fbcc8c816f73170e53c4b7cac2565d7c26b6e0
Sam Boyer <drupal@samboyer.org>
Sam Boyer <drupal@samboyer.org>
1281398349
Merge branch 'master' into entities
ENDOFOUTPUTGITMESSAGEHERE
43 0 CHANGELOG.txt
Only if -m is passed will it output individual numstats against all parent commits:
$ git show -m --numstat --summary --pretty=format:"%H%n%P%n%aN <%ae>%n%cN <%ce>%n%ct%n%s%n%b%nENDOFOUTPUTGITMESSAGEHERE" 32d5d
32d5d3d0ab8eabb812fedef73f6dd1f4e74c288b
e111ad0f0165c1b85def0dc89005c36be420793d 46fbcc8c816f73170e53c4b7cac2565d7c26b6e0
Sam Boyer <drupal@samboyer.org>
Sam Boyer <drupal@samboyer.org>
1281398349
Merge branch 'master' into entities
ENDOFOUTPUTGITMESSAGEHERE
43 0 CHANGELOG.txt
32d5d3d0ab8eabb812fedef73f6dd1f4e74c288b
e111ad0f0165c1b85def0dc89005c36be420793d 46fbcc8c816f73170e53c4b7cac2565d7c26b6e0
Sam Boyer <drupal@samboyer.org>
Sam Boyer <drupal@samboyer.org>
1281398349
Merge branch 'master' into entities
ENDOFOUTPUTGITMESSAGEHERE
7 0 CHANGELOG.txt
1 16 includes/VersioncontrolAccount.php
40 17 includes/VersioncontrolBackend.php
111 6 includes/VersioncontrolBranch.php
5 23 includes/VersioncontrolItem.php
12 26 includes/VersioncontrolLabel.php
11 30 includes/VersioncontrolOperation.php
64 139 includes/VersioncontrolRepository.php
79 6 includes/VersioncontrolTag.php
595 0 includes/controllers.inc
1 1 versioncontrol.admin.inc
1 0 versioncontrol.info
26 1 versioncontrol.install
79 71 versioncontrol.module
7 6 versioncontrol_fakevcs/includes/classes.inc
create mode 100644 includes/controllers.inc
The sum of these two outputs shows the true, full effect of the merge relative to the best common ancestor/merge base (see man git-merge-base to understand what that is). The first output are the changes introduces on 'master', the second the changes introduced on 'entities'. And for merge commits which require some manual resolution...well, I haven't even tested that yet. And it makes my head hurt.
There's another problem here, too - each output doesn't actually identify which parent its diffing against. As far as I can tell they're output in the reverse of the order in which the parent commits appear in the second line (so 46fbcc first, then e111ad), but I don't know how well that holds up, or how it changes in the case of an octopus. Annoyingly, if you use one of the built-in formats like --pretty=raw, the parent is explicitly identified in each output:
commit 32d5d3d0ab8eabb812fedef73f6dd1f4e74c288b (from e111ad0f0165c1b85def0dc89005c36be420793d)
tree fa0a8e2ffde1dc9637ad024f8f0e3ddfc9f0f597
parent e111ad0f0165c1b85def0dc89005c36be420793d
parent 46fbcc8c816f73170e53c4b7cac2565d7c26b6e0
author Sam Boyer <drupal@samboyer.org> 1281398349 -0700
committer Sam Boyer <drupal@samboyer.org> 1281398349 -0700
Merge branch 'master' into entities
43 0 CHANGELOG.txt
commit 32d5d3d0ab8eabb812fedef73f6dd1f4e74c288b (from 46fbcc8c816f73170e53c4b7cac2565d7c26b6e0)
tree fa0a8e2ffde1dc9637ad024f8f0e3ddfc9f0f597
parent e111ad0f0165c1b85def0dc89005c36be420793d
parent 46fbcc8c816f73170e53c4b7cac2565d7c26b6e0
author Sam Boyer <drupal@samboyer.org> 1281398349 -0700
committer Sam Boyer <drupal@samboyer.org> 1281398349 -0700
Merge branch 'master' into entities
7 0 CHANGELOG.txt
1 16 includes/VersioncontrolAccount.php
40 17 includes/VersioncontrolBackend.php
111 6 includes/VersioncontrolBranch.php
5 23 includes/VersioncontrolItem.php
12 26 includes/VersioncontrolLabel.php
11 30 includes/VersioncontrolOperation.php
64 139 includes/VersioncontrolRepository.php
79 6 includes/VersioncontrolTag.php
595 0 includes/controllers.inc
1 1 versioncontrol.admin.inc
1 0 versioncontrol.info
26 1 versioncontrol.install
79 71 versioncontrol.module
7 6 versioncontrol_fakevcs/includes/classes.inc
create mode 100644 includes/controllers.inc
Note the (from <commit id>) that appears on the first line of each output. I've even looked through the git source files, and as far as I can tell, there's no way to simulate that output with a custom --pretty=format.
A lot of this may end up being moot. But I want it all up here and documented in public, anyway, so that there's a clear launching point for discussion.
Comments
Comment #1
sdboyer commentedSlightly better title.
Comment #2
sdboyer commentedGonna take this back to normal for now.
Comment #3
marvil07 commentedReally good catch about merges(aka I need to open my eyes a little more).
All the mentioned points are IMHO really related with the decision to use our own functions to implement git interaction. I mean, we are implementing php for _our_ interaction, so it will be always limited.
This can be better if we use a general php wrapper for git. The problem is that after searching a little, I end up finding no general propose php api for git(like git-pyhon for python), in other to make git interaction cleaner.
So, maybe it would be better to focus on writing a general propose php api for git. After reading some of the code in the mentioned links I think git-python could be a really good start to make our own gitlib for php.
In the worst case, we just modify what we have, trying to keep that code independent from drupal APIs, as we were trying I think until someone start a decent php wrapper for git.
PS: I know I am almost out of the scope of this issue, but I needed to write this somewhere :-p
Comment #4
sdboyer commentedHeh, I don't actually see the strongest link between my original concern and the question of a wrapper for git interaction, but you know I don't disagree. Though...yeah, I guess I can see the connection. However, there is a baseline to follow - the one I wrote for svn, which I wrote specifically in preparation for writing just such a thing for git: http://github.com/sdboyer/svnlib . Between that and git-python, we should have everything we need, in terms of a basis for work.
Comment #5
sdboyer commentedMarking critical.
Comment #6
marvil07 commentedAn update after #965930: Get the log parser finished. Really. got in:
About dates
Agree, we need to make sure timestamps are stored with the right timezones(not really sure if this is necessary since IIRC timestamp means "seconds since epoch", so seems to be a fixed time), but yep, make sure about it.
About delimiter
Not really sure if this is important now, maybe we should wait to #973890: Create a reposync plugin using libgit2 php binding, when anyway we are dropping all that code in favour of probably direct function/methods to get right data.
Merge data
After #975864: Merge {versioncontrol_item_revisions} and {versioncontrol_source_items} tables versioncontrol module is not anymore tracking merges referring item revisions to many source items(now only one), it is only flagging the item revision as VERSIONCONTROL_ACTION_MERGED if the revision have more than one parent. So, unless we start supporting merges on versioncontrol_git IMO this is not anymore needed.
PS: Maybe it would be better to split this in more specific issues, when we decide what to change.
PS2: changing to major, since log parser is working as expected for now, naturally some of these can be bugs, so leaving as major.
Comment #7
marvil07 commentedComment #8
sdboyer commentedThis was me being too twitchy.