[PATCH] Change behavior of "changegroup" hook, make new behavior optional

Nikolaus.Schueler at lantiq.com Nikolaus.Schueler at lantiq.com
Fri Dec 9 03:40:22 CST 2011


Hi all,

Notify extension: Change behavior of "changegroup" hook.

I reworked the patch I have submitted earlier this week for the
notify extension according to a
suggestion from Angel Ezquerra. The option is now configurable,
if you set

notify.changegroup.usefirstcommitter

in your config, the behavior is as described below. If you do not set the option,
the behavior is as before.

Tests are enhanced, too, both cases (option set, option not set) are tested now.

The behavior if you set the option is as follows:

There are two hooks, "incoming" and "changegroup". 
If you use the "incoming" hook, the sender of the mail (given by the "From" header) is the user that did the commit. If you use the "changegroup" hook, the "From" header contains the system user, that is, the user that does the push. 

This patch would change the behavior so that the sender in case of the "changegroup" hook is the user that did the first commit in the changegroup. 

Our reason to do it that way is to have the user responsible for the commits in the changegroup as sender, not the user who does the push (which may be some admin or so).

The patch includes the suggested change plus four tests.

* One test makes sure the old behavior of the "incoming" hook is still there.
* Two additional tests show that the behavior is what we intend it to be for the "changegroup" hook.
* Another test shows that for a merge the "merge user" is not used. (The notify extension handles merges in a special way, omitting them from the notify message.) The patch contains a test for the feature.

Regards

Nik

# HG changeset patch
# User Nikolaus Schueler <nikolaus.schueler at lantiq.com>
# Date 1323423025 -3600
# Node ID c8363af23d9430737e2dd8257b8fae4200b1e7e9
# Parent  fc8c7a5ccc4a928e7559013ecdf50462c271418c
Change behavior of "changegroup" hook for notify extension

Behavior is configurable, if enabled, first committer of
changegroup is used for "From" field in mail sent by notify
extension. If option is not enabled, behavior is as before.

diff --git a/hgext/notify.py b/hgext/notify.py
--- a/hgext/notify.py
+++ b/hgext/notify.py
@@ -338,11 +338,14 @@ def hook(ui, repo, hooktype, node=None, 
     ui.pushbuffer()
     data = ''
     count = 0
+    author = ''
     if hooktype == 'changegroup' or hooktype == 'outgoing':
         start, end = ctx.rev(), len(repo)
         for rev in xrange(start, end):
             if n.node(repo[rev]):
                 count += 1
+                if not author:
+                    author = repo[rev].user()
             else:
                 data += ui.popbuffer()
                 ui.note(_('notify: suppressing notification for merge %d:%s\n') %
@@ -360,5 +363,9 @@ def hook(ui, repo, hooktype, node=None, 
         n.diff(ctx)
 
     data += ui.popbuffer()
+    useauthor = ui.config('notify', 'changegroup.usefirstcommitter')
+    if author and useauthor:
+        data = '\n'.join(['From: %s' % author, data])
+
     if count:
         n.send(ctx, count, data)
diff --git a/tests/test-notify-changegroup-merge.t b/tests/test-notify-changegroup-merge.t
new file mode 100644
--- /dev/null
+++ b/tests/test-notify-changegroup-merge.t
@@ -0,0 +1,224 @@
+Prove that the "From" field contains the committer, not the user who did the merge.
+
+First test with "usefirstcommitter" not set, should show default behavior (sender
+is system user).
+  $ cat <<EOF >> $HGRCPATH
+  > [extensions]
+  > notify=
+  > 
+  > [email]
+  > from = john.doe at example.com
+  > [hooks]
+  > changegroup.notify = python:hgext.notify.hook
+  > 
+  > [notify]
+  > sources = push
+  > diffstat = False
+  > maxsubject = 10
+  > 
+  > [usersubs]
+  > foo at bar = *
+  > 
+  > [reposubs]
+  > * = baz
+  > EOF
+  $ hg init a
+
+clone
+
+  $ hg --traceback clone a b
+  updating to branch default
+  0 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ echo a > b/a
+  $ echo b >> b/a
+  $ echo c >> b/a
+
+commit as one user
+
+  $ HGUSER=thecommitter
+  $ hg --traceback --cwd b commit -Ama
+  adding a
+  $ echo x > b/a
+  $ echo b >> b/a
+  $ echo c >> b/a
+  $ hg --traceback --cwd b commit -Amx
+
+commit as other user
+
+  $ HGUSER=theothercommitter
+  $ hg --cwd b up 0
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ echo a > b/a
+  $ echo b >> b/a
+  $ echo y >> b/a
+  $ hg --traceback --cwd b commit -Amy
+  created new head
+
+merge as a different user
+
+  $ HGUSER=themerger
+  $ hg --cwd b merge
+  merging a
+  0 files updated, 1 files merged, 0 files removed, 0 files unresolved
+  (branch merge, don't forget to commit)
+
+  $ hg --traceback --cwd b commit -Am "merged"
+
+push
+
+  $ hg --traceback --cwd b push ../a 2>&1 |
+  >     python -c 'import sys,re; print re.sub("\n\t", " ", sys.stdin.read()),'
+  pushing to ../a
+  searching for changes
+  adding changesets
+  adding manifests
+  adding file changes
+  added 4 changesets with 4 changes to 1 files
+  Content-Type: text/plain; charset="us-ascii"
+  MIME-Version: 1.0
+  Content-Transfer-Encoding: 7bit
+  Date: * (glob)
+  Subject: /tmp/hg...
+  From: john.doe at example.com
+  X-Hg-Notification: changeset 6cf7dfbc5c73
+  Message-Id: <*> (glob)
+  To: baz, foo at bar
+  
+  changeset 6cf7dfbc5c73 in $TESTTMP/a
+  details: $TESTTMP/a?cmd=changeset;node=6cf7dfbc5c73
+  summary: a
+  
+  changeset a715156cec09 in $TESTTMP/a
+  details: $TESTTMP/a?cmd=changeset;node=a715156cec09
+  summary: x
+  
+  changeset 959fdbe329fd in $TESTTMP/a
+  details: $TESTTMP/a?cmd=changeset;node=959fdbe329fd
+  summary: y
+  
+  changeset fec67fbb1d04 in $TESTTMP/a
+  details: $TESTTMP/a?cmd=changeset;node=fec67fbb1d04
+  summary: merged
+  
+  diffs (7 lines):
+  
+  diff -r 000000000000 -r fec67fbb1d04 a
+  --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+  +++ b/a	Thu Jan 01 00:00:00 1970 +0000
+  @@ -0,0 +1,3 @@
+  +x
+  +b
+  +y
+
+
+Then test with "usefirstcommitter" set.
+
+  $ rm -fr a b
+  $ cat <<EOF >> $HGRCPATH
+  > [extensions]
+  > notify=
+  > 
+  > [email]
+  > from = john.doe at example.com
+  > [hooks]
+  > changegroup.notify = python:hgext.notify.hook
+  > 
+  > [notify]
+  > sources = push
+  > diffstat = False
+  > maxsubject = 10
+  > changegroup.usefirstcommitter = True
+  > 
+  > [usersubs]
+  > foo at bar = *
+  > 
+  > [reposubs]
+  > * = baz
+  > EOF
+  $ hg init a
+
+clone
+
+  $ hg --traceback clone a b
+  updating to branch default
+  0 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ echo a > b/a
+  $ echo b >> b/a
+  $ echo c >> b/a
+
+commit as one user
+
+  $ HGUSER=thecommitter
+  $ hg --traceback --cwd b commit -Ama
+  adding a
+  $ echo x > b/a
+  $ echo b >> b/a
+  $ echo c >> b/a
+  $ hg --traceback --cwd b commit -Amx
+
+commit as other user
+
+  $ HGUSER=theothercommitter
+  $ hg --cwd b up 0
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ echo a > b/a
+  $ echo b >> b/a
+  $ echo y >> b/a
+  $ hg --traceback --cwd b commit -Amy
+  created new head
+
+merge as a different user
+
+  $ HGUSER=themerger
+  $ hg --cwd b merge
+  merging a
+  0 files updated, 1 files merged, 0 files removed, 0 files unresolved
+  (branch merge, don't forget to commit)
+
+  $ hg --traceback --cwd b commit -Am "merged"
+
+push
+
+  $ hg --traceback --cwd b push ../a 2>&1 |
+  >     python -c 'import sys,re; print re.sub("\n\t", " ", sys.stdin.read()),'
+  pushing to ../a
+  searching for changes
+  adding changesets
+  adding manifests
+  adding file changes
+  added 4 changesets with 4 changes to 1 files
+  Content-Type: text/plain; charset="us-ascii"
+  MIME-Version: 1.0
+  Content-Transfer-Encoding: 7bit
+  Date: * (glob)
+  Subject: /tmp/hg...
+  From: thecommitter
+  X-Hg-Notification: changeset 6cf7dfbc5c73
+  Message-Id: <*> (glob)
+  To: baz, foo at bar
+  
+  changeset 6cf7dfbc5c73 in $TESTTMP/a
+  details: $TESTTMP/a?cmd=changeset;node=6cf7dfbc5c73
+  summary: a
+  
+  changeset a715156cec09 in $TESTTMP/a
+  details: $TESTTMP/a?cmd=changeset;node=a715156cec09
+  summary: x
+  
+  changeset 959fdbe329fd in $TESTTMP/a
+  details: $TESTTMP/a?cmd=changeset;node=959fdbe329fd
+  summary: y
+  
+  changeset fec67fbb1d04 in $TESTTMP/a
+  details: $TESTTMP/a?cmd=changeset;node=fec67fbb1d04
+  summary: merged
+  
+  diffs (7 lines):
+  
+  diff -r 000000000000 -r fec67fbb1d04 a
+  --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+  +++ b/a	Thu Jan 01 00:00:00 1970 +0000
+  @@ -0,0 +1,3 @@
+  +x
+  +b
+  +y
diff --git a/tests/test-notify-changegroup-multiple-pushs.t b/tests/test-notify-changegroup-multiple-pushs.t
new file mode 100644
--- /dev/null
+++ b/tests/test-notify-changegroup-multiple-pushs.t
@@ -0,0 +1,184 @@
+Prove that the "From" field contains the committer, not the owner (== configured user) of the repo.
+This test shows that the first committer is used for the "From" field.
+
+First test with "usefirstcommitter" not set, should show default behavior (sender
+is system user).
+  $ cat <<EOF >> $HGRCPATH
+  > [extensions]
+  > notify=
+  > 
+  > [email]
+  > from = john.doe at example.com
+  > [hooks]
+  > changegroup.notify = python:hgext.notify.hook
+  > 
+  > [notify]
+  > sources = push
+  > diffstat = False
+  > maxsubject = 10
+  > 
+  > [usersubs]
+  > foo at bar = *
+  > 
+  > [reposubs]
+  > * = baz
+  > EOF
+  $ hg init a
+
+clone
+
+  $ hg --traceback clone a b
+  updating to branch default
+  0 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ echo a > b/a
+
+commit as one user
+
+  $ HGUSER=imoneuser
+  $ hg --traceback --cwd b commit -Ama
+  adding a
+  $ echo a >> b/a
+
+commit as one user
+
+  $ hg --traceback --cwd b commit -Amb
+
+commit as other user
+
+  $ HGUSER=imtheotheruser
+  $ echo "Second line" >> b/a
+  $ hg --traceback --cwd b commit -mx
+
+push
+
+  $ hg --traceback --cwd b push ../a 2>&1 |
+  >     python -c 'import sys,re; print re.sub("\n\t", " ", sys.stdin.read()),'
+  pushing to ../a
+  searching for changes
+  adding changesets
+  adding manifests
+  adding file changes
+  added 3 changesets with 3 changes to 1 files
+  Content-Type: text/plain; charset="us-ascii"
+  MIME-Version: 1.0
+  Content-Transfer-Encoding: 7bit
+  Date: * (glob)
+  Subject: /tmp/hg...
+  From: john.doe at example.com
+  X-Hg-Notification: changeset 7a5245fae062
+  Message-Id: <*> (glob)
+  To: baz, foo at bar
+  
+  changeset 7a5245fae062 in $TESTTMP/a
+  details: $TESTTMP/a?cmd=changeset;node=7a5245fae062
+  summary: a
+  
+  changeset 804ff104125e in $TESTTMP/a
+  details: $TESTTMP/a?cmd=changeset;node=804ff104125e
+  summary: b
+  
+  changeset 9b551426af43 in $TESTTMP/a
+  details: $TESTTMP/a?cmd=changeset;node=9b551426af43
+  summary: x
+  
+  diffs (7 lines):
+  
+  diff -r 000000000000 -r 9b551426af43 a
+  --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+  +++ b/a	Thu Jan 01 00:00:00 1970 +0000
+  @@ -0,0 +1,3 @@
+  +a
+  +a
+  +Second line
+
+Then test with "usefirstcommitter" set.
+  $ rm -fr a b
+  $ cat <<EOF >> $HGRCPATH
+  > [extensions]
+  > notify=
+  > 
+  > [email]
+  > from = john.doe at example.com
+  > [hooks]
+  > changegroup.notify = python:hgext.notify.hook
+  > 
+  > [notify]
+  > sources = push
+  > diffstat = False
+  > maxsubject = 10
+  > changegroup.usefirstcommitter = True
+  > 
+  > [usersubs]
+  > foo at bar = *
+  > 
+  > [reposubs]
+  > * = baz
+  > EOF
+  $ hg init a
+
+clone
+
+  $ hg --traceback clone a b
+  updating to branch default
+  0 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ echo a > b/a
+
+commit as one user
+
+  $ HGUSER=imoneuser
+  $ hg --traceback --cwd b commit -Ama
+  adding a
+  $ echo a >> b/a
+
+commit as one user
+
+  $ hg --traceback --cwd b commit -Amb
+
+commit as other user
+
+  $ HGUSER=imtheotheruser
+  $ echo "Second line" >> b/a
+  $ hg --traceback --cwd b commit -mx
+
+push
+
+  $ hg --traceback --cwd b push ../a 2>&1 |
+  >     python -c 'import sys,re; print re.sub("\n\t", " ", sys.stdin.read()),'
+  pushing to ../a
+  searching for changes
+  adding changesets
+  adding manifests
+  adding file changes
+  added 3 changesets with 3 changes to 1 files
+  Content-Type: text/plain; charset="us-ascii"
+  MIME-Version: 1.0
+  Content-Transfer-Encoding: 7bit
+  Date: * (glob)
+  Subject: /tmp/hg...
+  From: imoneuser
+  X-Hg-Notification: changeset 7a5245fae062
+  Message-Id: <*> (glob)
+  To: baz, foo at bar
+  
+  changeset 7a5245fae062 in $TESTTMP/a
+  details: $TESTTMP/a?cmd=changeset;node=7a5245fae062
+  summary: a
+  
+  changeset 804ff104125e in $TESTTMP/a
+  details: $TESTTMP/a?cmd=changeset;node=804ff104125e
+  summary: b
+  
+  changeset 9b551426af43 in $TESTTMP/a
+  details: $TESTTMP/a?cmd=changeset;node=9b551426af43
+  summary: x
+  
+  diffs (7 lines):
+  
+  diff -r 000000000000 -r 9b551426af43 a
+  --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+  +++ b/a	Thu Jan 01 00:00:00 1970 +0000
+  @@ -0,0 +1,3 @@
+  +a
+  +a
+  +Second line
+
diff --git a/tests/test-notify-changegroup-push.t b/tests/test-notify-changegroup-push.t
new file mode 100644
--- /dev/null
+++ b/tests/test-notify-changegroup-push.t
@@ -0,0 +1,158 @@
+Prove that the "From" field contains the committer, not the owner (== configured user) of the repo.
+
+First test with "usefirstcommitter" not set, should show default behavior (sender
+is system user).
+  $ cat <<EOF >> $HGRCPATH
+  > [extensions]
+  > notify=
+  > 
+  > [email]
+  > from = john.doe at example.com
+  > [hooks]
+  > changegroup.notify = python:hgext.notify.hook
+  > 
+  > [notify]
+  > sources = push
+  > diffstat = False
+  > maxsubject = 10
+  > 
+  > [usersubs]
+  > foo at bar = *
+  > 
+  > [reposubs]
+  > * = baz
+  > EOF
+  $ hg init a
+
+clone
+
+  $ hg --traceback clone a b
+  updating to branch default
+  0 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ echo a > b/a
+
+commit
+
+  $ hg --traceback --cwd b commit -Ama
+  adding a
+  $ echo a >> b/a
+
+commit
+
+  $ hg --traceback --cwd b commit -Amb
+
+push
+
+  $ hg --traceback --cwd b push ../a 2>&1 |
+  >     python -c 'import sys,re; print re.sub("\n\t", " ", sys.stdin.read()),'
+  pushing to ../a
+  searching for changes
+  adding changesets
+  adding manifests
+  adding file changes
+  added 2 changesets with 2 changes to 1 files
+  Content-Type: text/plain; charset="us-ascii"
+  MIME-Version: 1.0
+  Content-Transfer-Encoding: 7bit
+  Date: * (glob)
+  Subject: * (glob)
+  From: john.doe at example.com
+  X-Hg-Notification: changeset cb9a9f314b8b
+  Message-Id: * (glob)
+  To: baz, foo at bar
+  
+  changeset cb9a9f314b8b in $TESTTMP/a
+  details: $TESTTMP/a?cmd=changeset;node=cb9a9f314b8b
+  summary: a
+  
+  changeset ba677d0156c1 in $TESTTMP/a
+  details: $TESTTMP/a?cmd=changeset;node=ba677d0156c1
+  summary: b
+  
+  diffs (6 lines):
+  
+  diff -r 000000000000 -r ba677d0156c1 a
+  --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+  +++ b/a	Thu Jan 01 00:00:00 1970 +0000
+  @@ -0,0 +1,2 @@
+  +a
+  +a
+
+Then test with "usefirstcommitter" set.
+  $ rm -fr a b
+  $ cat <<EOF >> $HGRCPATH
+  > [extensions]
+  > notify=
+  > 
+  > [email]
+  > from = john.doe at example.com
+  > [hooks]
+  > changegroup.notify = python:hgext.notify.hook
+  > 
+  > [notify]
+  > sources = push
+  > diffstat = False
+  > maxsubject = 10
+  > changegroup.usefirstcommitter = True
+  > 
+  > [usersubs]
+  > foo at bar = *
+  > 
+  > [reposubs]
+  > * = baz
+  > EOF
+  $ hg init a
+
+clone
+
+  $ hg --traceback clone a b
+  updating to branch default
+  0 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ echo a > b/a
+
+commit
+
+  $ hg --traceback --cwd b commit -Ama
+  adding a
+  $ echo a >> b/a
+
+commit
+
+  $ hg --traceback --cwd b commit -Amb
+
+push
+
+  $ hg --traceback --cwd b push ../a 2>&1 |
+  >     python -c 'import sys,re; print re.sub("\n\t", " ", sys.stdin.read()),'
+  pushing to ../a
+  searching for changes
+  adding changesets
+  adding manifests
+  adding file changes
+  added 2 changesets with 2 changes to 1 files
+  Content-Type: text/plain; charset="us-ascii"
+  MIME-Version: 1.0
+  Content-Transfer-Encoding: 7bit
+  Date: * (glob)
+  Subject: * (glob)
+  From: test
+  X-Hg-Notification: changeset cb9a9f314b8b
+  Message-Id: * (glob)
+  To: baz, foo at bar
+  
+  changeset cb9a9f314b8b in $TESTTMP/a
+  details: $TESTTMP/a?cmd=changeset;node=cb9a9f314b8b
+  summary: a
+  
+  changeset ba677d0156c1 in $TESTTMP/a
+  details: $TESTTMP/a?cmd=changeset;node=ba677d0156c1
+  summary: b
+  
+  diffs (6 lines):
+  
+  diff -r 000000000000 -r ba677d0156c1 a
+  --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+  +++ b/a	Thu Jan 01 00:00:00 1970 +0000
+  @@ -0,0 +1,2 @@
+  +a
+  +a
diff --git a/tests/test-notify-incoming-push.t b/tests/test-notify-incoming-push.t
new file mode 100644
--- /dev/null
+++ b/tests/test-notify-incoming-push.t
@@ -0,0 +1,76 @@
+Prove that the "From" field contains the committer, not the user who did the merge.
+
+  $ cat <<EOF >> $HGRCPATH
+  > [extensions]
+  > notify=
+  > 
+  > [email]
+  > from = john.doe at example.com
+  > [hooks]
+  > incoming.notify = python:hgext.notify.hook
+  > 
+  > [notify]
+  > domain = test.com
+  > sources = push
+  > diffstat = False
+  > maxsubject = 10
+  > 
+  > [usersubs]
+  > foo at bar = *
+  > 
+  > [reposubs]
+  > * = baz
+  > EOF
+  $ hg init a
+
+clone
+
+  $ hg --traceback clone a b
+  updating to branch default
+  0 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ echo a > b/a
+
+commit
+
+  $ hg --traceback --cwd b commit -Ama
+  adding a
+  $ echo a >> a/a
+
+commit
+
+  $ hg --traceback --cwd b commit -Amb
+  nothing changed
+  [1]
+
+push
+
+  $ hg --traceback --cwd b push ../a 2>&1 |
+  >     python -c 'import sys,re; print re.sub("\n\t", " ", sys.stdin.read()),'
+  pushing to ../a
+  searching for changes
+  adding changesets
+  adding manifests
+  adding file changes
+  added 1 changesets with 1 changes to 1 files
+  Content-Type: text/plain; charset="us-ascii"
+  MIME-Version: 1.0
+  Content-Transfer-Encoding: 7bit
+  Date: * (glob)
+  Subject: * (glob)
+  From: test at test.com
+  X-Hg-Notification: changeset cb9a9f314b8b
+  Message-Id: * (glob)
+  To: baz at test.com, foo at bar
+  
+  changeset cb9a9f314b8b in $TESTTMP/a
+  details: $TESTTMP/a?cmd=changeset;node=cb9a9f314b8b
+  description: a
+  
+  diffs (5 lines):
+  
+  diff -r 000000000000 -r cb9a9f314b8b a
+  --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+  +++ b/a	Thu Jan 01 00:00:00 1970 +0000
+  @@ -0,0 +1,1 @@
+  +a
+


More information about the Mercurial-devel mailing list