Bazaar: Automatic file modification on commit with the modification committed - file

I would like bazaar to write revision number on commit to a file in the committed branch so that this modification is included in the commit.
I looked at hooks but the pre_commit hook is only run after the changeset is created, thus the modification performed by it is not committed.
I found a related question:
Bazaar: Modify file content before commit via hook?
, however, the proposed bzr-keywords solution does not work either as its write conversion is not applied on commit:
``bzr commit`` does not implicitly apply write converters after
comitting files. If this makes sense for a given plugin providing
a content filter, the plugin can usually achieve this effect by using a
``start_commit`` or ``post_commit`` hook.
which gets me back to the pre_commit hook problem.
My reason for doing this: my software reads its version from a version file on compilation. The version is composed of main number, branch number and revision number (eg 5.3.78). I want bazaar to write the actual version to the version file automatically on commit.

You should use start_commit hook because this is the only way to change file before commit: http://doc.bazaar.canonical.com/bzr.2.3/en/user-reference/hooks-help.html#start-commit
start_commit
Called before a commit is performed on a tree. The start commit hook is able to change the tree before the commit takes place. start_commit is called with the bzrlib.mutabletree.MutableTree that the commit is being performed on.

I have a plugin script that hooks into start_commit called start_commit.py. This calls a shell script named .startcommit from the base of the project tree each time a commit occurs. I use this with Ledger data to dump all my balances for verification before each commit.
I didn't write this plugin, and I can't locate where I got it from with a quick search, so here's the source (~/.bazaar/plugins/start_commit.py):
from bzrlib import errors, mutabletree
def start_commit(tree):
"""This hook will execute tree/on-commit."""
import os,subprocess
from bzrlib import errors
abspath = tree.abspath('.startcommit')
# if there is no on-commit, bail
if not os.path.exists(abspath):
return
try:
subprocess.check_call(abspath)
# if precommit fails (process return not zero) cancel commit.
except subprocess.CalledProcessError:
raise errors.BzrError("on-commit failed")
mutabletree.MutableTree.hooks.install_named_hook('start_commit', start_commit,
"tree on-commit")
If someone knows, I'd be happy to credit the original author for this snippet. Otherwise I hope it helps!

Related

Checkout branch with libgit2

I'm trying to implement a simple checkout operation between 2 branches. The code executes without errors.
git_libgit2_init();
git_object *treeish = NULL;
git_checkout_options opts;
opts.checkout_strategy = GIT_CHECKOUT_SAFE;
/* branchName in this case is "master" */
handleError(git_revparse_single(&treeish, repo, branchName));
handleError(git_checkout_tree(repo, treeish, &opts));
git_object_free(treeish);
git_libgit2_shutdown();
However, the branch does not change when I check it using git status.
I've checked the 101 examples of libgit2 and it says:
git_checkout_options isn’t actually very optional. The defaults won’t
be useful outside of a small number of cases. The best example of this
is checkout_strategy; the default value does nothing to the work tree.
So if you want your checkout to check files out, choose an appropriate
strategy.
NONE is the equivalent of a dry run; no files will be checked out.
SAFE is similar to git checkout; unmodified files are updated, and modified files are left alone. If a file was present in the old HEAD
but is missing, it’s considered deleted, and won’t be created.
RECREATE_MISSING is similar to git checkout-index, or what happens after a clone. Unmodified files are updated, and missing files are
created, but files with modifications are left alone.
FORCE is similar to git checkout --force; all modifications are overwritten, and all missing files are created.
In my case I'm testing it with a very small repo without uncommited changes and without any conflicts between these 2 branches.
What am I doing wrong? I expected this code to do something like git checkout master
The git checkout command is exceptionally overloaded. It deals with both putting files on disk (checking out) and switching branches. In particular, git checkout <branch> will update the working directory to match the contents of the given branch and switch to it.
The libgit2 APIs do not conflate these two operations. git_checkout_* functions will only check files out on disk.
The documentation should clarify this:
In libgit2, checkout is used to update the working directory and index
to match a target tree. Unlike git checkout, it does not move the HEAD
commit for you - use git_repository_set_head or the like to do that.
So what you have written (above) will update the working directory to match the contents of the branch. After that, you will need to update your branch to the branch you want to switch to.
You can do this with git_repository_set_head to update HEAD to point to the given branch, once the files have been checked out. Be sure to specify the fully-qualified branch name (eg, refs/heads/master).
git_object *treeish = NULL;
git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT;
opts.checkout_strategy = GIT_CHECKOUT_SAFE;
git_libgit2_init();
handleError(git_revparse_single(&treeish, repo, "master"));
handleError(git_checkout_tree(repo, treeish, &opts));
handleError(git_repository_set_head(g_repo, "refs/heads/master"));
git_object_free(treeish);
git_libgit2_shutdown();

Mercurial pre-merge hook

Is there a way to do some checks before allowing a merge in Mercurial?
I have found the pre-update hook and have a script that runs before an update is allowed, by adding the following to ~/.hg/hgrc:
[hooks]
pre-update = ~/hg_pre_update.sh
But I'd like to run the check before allowing a merge as well, and currently it just allows the merge to go through without running my checks.
Background
In case there are alternative ways to solve the problem...
We have been having a number of problems with 'lost' edits under Mercurial. I've tracked down most of them now to the same underlying cause: someone has vim edit sessions open while either they or someone else does a hg update or merge. The editor warns the file has changed externally, the user ignores the warning and saves their changes.
When these changes are committed, for Mercurial there is nothing controversial. The user has simply reverted all the changes brought in with the last update and put in their own changes.
Some time later, we notice the code has gone walkabouts. Cue assorted insults flung the way of mercurial...
Set vim to autoreload changes if no local changes where done. (otherwise ask, or force a merge)
that's how I avoid such issues in any editor...
Sorry just worked out there is a pre-merge hook that works just the same as pre-update. I tried it before asking the question, but now just looking at my hgrc I realise I put the script being called for that hook to ~/hg_pre_merge.sh which doesn't exist.
I can't find the existence of pre-merge documented anywhere but still feeling like a bit of a muppet now.

calling custom actions from File instead of Binary

I've found lots of examples of calling custom actions in WiX using Binary element, but none examples where a File element was used. Can anyone give me an example?
Not strictly true about needing to run the action deferred! You can use the InstallExecute action to run all the spooled actions up to that point, including, for example file installation. After that you could schedule an immediate action which depends on the newly-installed file, which at this point will be present.
That said, if the file is going to make any changes to the machine state, then the CA really needs to be deferred in system context, so InstallExecute doesn't really buy you anything.

How to retrieve all object IDs?

I am trying to get a list of all object IDs in a git repository, using libgit2. I can't seem to find any method for this. Does libgit2 have a method to get all object IDs (or iterate through them), or do I need to read them manually?
What you may be looking for is the revision walking API.
Description of the feature can be found here.
A test demonstrating different walking strategies may also provide you with some help
Edit: A thread in the libgit2 mailing list specifically deals with this.
A more precise answer from Vicent Marti (libgit2 maintainer) is
... Just push every single HEAD into the the walker. You won't
get any duplicate commits.
All you have to do is to push every branch and tag oids into the revision walker to recursively walk the commit history. Please note this won't retrieve dangling commits (commits or chain of commits that are not referenced by a branch nor a tag).
Edit 2: This behavior (similar to git log --all) has been successfully implemented in libgit2sharp (libgit2 .Net bindings).
Edit 3: A new feature has recently been merged which would allow to enumerate all the objects (commits, trees, blobs, ...) stored in the object database: git_odb_foreach().
This would be more in line with the git fsck scenario #MatrixFrog was talking about.
git_odb_foreach() documentation
A simple test demonstrating how to use the API

How best to branch in Clearcase?

I've previously documented my opinions on Clearcase as a source control system, but unfortunately I am still using it. So I turn to you guys to help me alleviate one of my frustrations.
We have just moved from a one-branch-per-developer system, to a one-branch-per-task in an attempt to improve some of the issues that we've been having with determining why certain files were changed. Generally I am happy with the solution, but there is one major issue. We are using simple scripts to start and end tasks which create a new branch named with the username and task number and then updates the local snapshot view to have a config spec similar to the following:
element * CHECKEDOUT
element * .../martin_2322/LATEST
element * /main/LATEST -mkbranch martin_2322
load /Project/Application
Let's say that my project has two coupled files A.cs and B.cs. For my first task I make changes to A on the branch. Then I need to stop working on task 2322 for whatever reason and start work on task 2345 (task 2322 is not finished, so I don't merge it back into main).
I create a new task branch 2345, edit both A.cs and B.cs and merge the results back into main. Now I go back to work on 2322, so I change my config spec back to one defined above. At this point I see the A.cs file from the task branch (as I edited it earlier, so I get the version local to that branch) and the latest version of B.cs from main. Since I don't have the changes made to A.cs on the 2345 branch the build breaks. What I need instead is to be able to pick up task 2322 from where I left off and see it with the old version of A.cs - the one that was latest in main when the branch was created.
The way I see it I have a few options to fix this:
Change the config spec so that it gets files from main at the right date. This is easy enough to do if I know the date and don't mind setting it by hand, but I can't figure out how to automate this into our task switching scripts. Is there anyway to get the creation date of a branch?
Create a label for each branch on main. Theoretically simple to do, but the labelling system in our install of CC is already collapsing under the weight of a few hundred labels, so I don't know if it will cope with one per developer per branch (notice that the task in my example is 2322 and we're only about an quarter of the way through the project)
Merge out from main into the task branch. Once again should work, but then long running branches won't just contain the files changed for that task, but all files that needed to be merged across to get unrelated things working. This makes them as complicated as the branch-per-developer approach. I want to see which files were changed to complete a specific task.
I hope I'm just missing something here and there is a way of setting my config spec so that it retrieves the expected files from main without clunky workarounds. So, how are you guys branching in Clearcase?
A few comments:
a branch per task is the right granularity for modifying a set of file within a "unit of work". Provided the "task" is not too narrow, otherwise you end up with a gazillon of branches (and their associated merges)
when you create a config spec for a branch, you apparently forget the line for new elements (the one you "add to source control")
Plus you may consider branching for a fix starting point, which would solve the "old version of A.cs - the one that was latest in main when the branch was created" bit.
I know you have too much labels already, but you could have a script to "close" a task which would (amongst other things) delete that starting label, avoiding label cluttering.
Here the config spec I would use:
element * CHECKEDOUT
element * .../martin_2322/LATEST
element * STARTING_LABEL_2322 -mkbranch martin_2322
# selection rule for new "added to source control" file
element * /main/0 -mkbranch martin_2322
load /Project/Application
I would find this much more easier than computing the date of a branch.
do not forget you can merge back your task to main, and merge some your files from your finished task branch to the your new current task branch as well, if you need to retrofit some your fixes back to that current task as well.
You can get the creation date for a branch by using the describe command in cleartool.
cleartool describe -fmt "%d" -type martin_2322
This will printout the date and time that the branch was created. You can use this to implement your first option. For more information, you could read the following cleartool man pages, but hopefully the above command is all you need.
cleartool man describe
cleartool man fmt_ccase
We use Clearcase, and we find that creating a branch for a release is often much easier than doing it by task. If you do create it by task, then I'd have a 'main branch' for that release, and branch the tasks off that branch, and then merge them back in when finished to merge them back to the trunk.

Resources