An alternative to using PQM
John Arbash Meinel
john at arbash-meinel.com
Thu Oct 26 13:55:24 BST 2006
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
Nicholas Allen wrote:
>
>> Either way would be fairly easy, I think. I'd probably write it in
>> Python with
>> bzrlib personally, because I'm reasonably familiar with bzrlib and so
>> it'd give
>> me more flexibility, and it's easier to write unit tests for python
>> code than
>> shell scripts.
>>
>> If I didn't use bzrlib, I probably wouldn't choose a shell script, I'd
>> write
>> Python using the subprocess module instead :)
> Is it easily possible to determine if conflicts occurred by looking at
> the exit code for "bzr merge"? Likewise for other commands like push and
> commit to see if they were successful? The only other problem I see by
> running processes is when branches are password protected. The script
> would have to enter the password at the right time.
>
> Thanks,
>
> Nicholas Allen
'bzr merge' returns 0 if it is a clean merge, and 1 if there are conflicts.
So yes, you can use the return value.
For 'password protected' branches...
I'm not sure how you are thinking to set this up, but the most common
thing would be to have everyone push to the same machine, into
neighboring directories. Possibly into the same repository (just to
avoid pushing the same data multiple times).
Then the ChangeIntegrator could just run over all the branches in that
directory.
For 'bzrlib' versus 'bzr'. It could be done either way. I personally
would probably do it using 'bzrlib', because it is a richer api. For
example, you could do something like:
# You need a working directory to do merging inside, but the stuff you
# pull from only needs a 'Branch'.
target_tree = bzrlib.workingtree.WorkingTree.open(target_path)
target_ancestry = target_tree.branch.repository.get_revision_graph(
target_tree.last_revision())
for root, dirs, files in os.walk(possible_branches):
try:
a_branch = bzrlib.branch.Branch.open(root)
except bzrlib.errors.NotBranchError:
continue
last_revision_id = a_branch.last_revision()
if last_revision_id in target_ancestry:
continue # This branch has already been merged
rev_info = a_branch.repository.get_revision(last_revision_id)
# Do the merge
conflicts = target_tree.merge_from_branch(a_branch)
# Check for conflicts
if len(conflicts) > 0:
target_tree.revert()
# email the user about 'conflicts'
continue
# Run the test suite
# Mix stderr and stdout so the information is in order
# rather than separated, alternatively, keep it separate
p = subprocess.popen(['make test'], cwd=target_tree.basedir
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT)
out, err = p.communicate()
if p.returncode != 0:
# Email the user about 'failed test suite'
# sending them the contents of 'out'
target_tree.revert()
continue
# v- Commit the change to the mainline, possibly preserving
# the committer's name, and possibly preserving the commit message
target_tree.commit(message=rev_info.message,
committer=rev_info.committer)
# Email the development group about the successful merge
This is much simpler than using a shell script and checking the return
code for 'bzr missing' to see if anything needs to be merged, and 'bzr
merge' to see if there are any conflicts.
The above little snippet is probably 90% of what you need in your
proposed ChangeIntegrator. Depending on how much configuration you want
to do outside of the script. And whether you want the merged commit to
have the same message, or whether you want to put some sort of
'Automerged' string into it, or use a different committer id, or ....
There are a lot of ways to extend it. But that should give you the bulk
of what you want.
John
=:->
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.2.1 (Cygwin)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org
iD8DBQFFQLA8JdeBCYSNAAMRAmjFAJ998KQbmUTGXmC6nY1PogKhJcgZ8gCeMMCn
0xSNPzpgZnvpWLf29RrgcSU=
=SWMe
-----END PGP SIGNATURE-----
More information about the bazaar
mailing list