5 from collections
import defaultdict
6 from sqlalchemy
.orm
import join
11 NOTES_INDEX
= '.git/git-notes-index'
13 'GIT_INDEX_FILE': NOTES_INDEX
,
15 NOTES_REF
= 'refs/heads/mailnotes'
17 _eol_space_re
= re
.compile('\s+$', re
.MULTILINE
)
18 def write_notes(commit_sha1
, notes
):
19 notes
= _eol_space_re
.sub('', notes
)
20 notes
= notes
.strip('\n')
21 blob_sha1
= git('hash-object', '-w', '--stdin', input=notes
)[0]
22 git('update-index', '--add', '--cacheinfo', '0644', blob_sha1
, commit_sha1
, env
=notes_env
)
25 previous
, ret
= git('rev-parse', NOTES_REF
)
30 args
= ['-p', previous
.strip()]
31 previous_arg
= [previous
.strip()]
32 tree_sha1
= git('write-tree', env
=notes_env
)[0].strip()
33 head_sha1
= git('commit-tree', tree_sha1
, *args
,
34 input='Mass annotation by notes.py')[0].strip()
35 git('update-ref', '-m', 'Mass annotation by notes.py',
36 NOTES_REF
, head_sha1
, *previous_arg
)
38 def split_and_tab(buf
):
40 for line
in str(buf
).splitlines():
41 ret
.append('\t%s\n' % line
)
44 def compute_notes(commit
, mail
):
47 notes
.append('From: %s\n' % mail
.author
)
49 notes
.append('Subject: %s\n' % mail
.subject
)
50 notes
.append('Message-Id: <%s>\n' % mail
.message_id
)
51 notes
.append('Posted-Date: %s\n'
52 % time
.strftime("%c", time
.localtime(mail
.post_date
)))
54 notes
.append('In-Reply-To: %s\n' % mail
.in_reply_to
)
56 notes
.append('Archived-At: <http://permalink.gmane.org/gmane.comp.version-control.git/%d>\n' % mail
.gmane_id
)
57 if len(mail
.patch
)>0 and mail
.patch
[0].extra_notes
:
58 notes
.append('Extra-notes:\n')
59 notes
.extend(split_and_tab(mail
.patch
[0].extra_notes
))
62 _merge_re
= re
.compile("^([a-f0-9]{40}) Merge branch '([^']+)'")
64 pu_ref
= git('rev-parse', 'origin/pu')[0].strip()
65 pu_topic
= db
.session
.query(db
.Topic
).filter(db
.Topic
.name
== 'pu').first()
67 notes
[pu_ref
].append('Pu-Overview:\n')
68 notes
[pu_ref
].extend(split_and_tab(pu_topic
.cooking_notes
))
69 notes
[pu_ref
].append('\n')
70 for line
in git('log', '--first-parent', '--pretty=tformat:%H %s',
71 'origin/master..origin/pu', ret_pipe
=True):
72 m
= _merge_re
.match(line
)
77 t
= db
.session
.query(db
.Topic
).filter(db
.Topic
.name
== branch
).first()
78 if t
and t
.cooking_notes
:
79 notes
[sha1
].append('Pu-Topic:\n')
80 notes
[sha1
].extend(split_and_tab(t
.cooking_notes
))
81 notes
[sha1
].append('\n')
83 def _redo_patches(notes
):
85 for cmt
, mail
in (db
.session
.query(db
.Commit
, db
.Mail
)
86 .select_from(join(db
.Mail
, db
.Commit
,
87 db
.Mail
.patch_id
==db
.Commit
.patch_id
))
88 .filter(db
.Commit
.upstream
==True)
89 .filter(db
.Mail
.has_patch
==True)):
90 nts
= compute_notes(cmt
, mail
)
94 notes
[cmt
.sha1
].append('\n')
95 notes
[cmt
.sha1
].extend(nts
)
96 sys
.stdout
.write('\r%6d' % count
)
99 sys
.stdout
.write('\n')
103 notes
= defaultdict(list)
106 os
.unlink(NOTES_INDEX
)
108 for cmt
, nts
in notes
.iteritems():
109 sys
.stdout
.write('\r%6d' % count
)
111 write_notes(cmt
, ''.join(nts
))
113 sys
.stdout
.write('\n')
116 if __name__
== '__main__':
117 if len(sys
.argv
) > 1:
118 cmt
= db
.session
.query(db
.Commit
).filter(db
.Commit
.sha1
==sys
.argv
[1]).one()
119 print compute_notes(cmt
)