I wish there were a way to let me annotate a commit with a statement
like this:
* When merging a branch that does not have me in it into a trunk
that already has me, do this extra check on the result of the
merge before allowing it to be recorded.
For example, suppose there is a topic that changes all instances of
this
__attribute__((format(printf, X, Y)))
into a new macro FORMAT_PRINTF(X, Y). With such a facility, I can
annotate the commit at the tip of that series to define an extra
check:
! git diff HEAD | grep '^+.*__attribute__((format(printf'
which would prevent me from merging a topic that introduces a new
instance of the printf-format attribute that is spelled in an
old-fashioned way.
In this particular example, it might be even better if the facility
allowed me to declare something like this instead:
* When merging a branch that does not have me in it into a trunk
that already has me, do this extra processing on the result of
the merge before recording it.
The difference between them is the "extra processing" part. For
this example, it would be something that is built around:
perl -p -e '
s{__attribute__\(\(format\(\s*printf,\s*(\d+),\s*(\d+)\)\)\)}
{FORMAT_PRINTF($1, $2)}gx
'
to update the old-fashioned one to use the new macro, and the result
would become an evil merge.
To realize this, there are low-hanging-fruit building blocks that
are trivial:
- Such an annotation can be made as a note attached to the commit
in question;
- Such a check can be done in pre-commit hook;
- Such a pre-commit hook can iterate over this set of commits
DIFF=$(git rev-list --left-right HEAD...MERGE_HEAD)
collect these Merge Gate annotations from the commit appears on
the left hand side (e.g. only exists on the trunk that a side
branch is about to be merged in), and run them.
But the last one feels very costly, and I suspect that there must be
a better way to do this. I do not think we want the "what to do"
part (i.e. checking new lines for __attribute__ in the first
example, or rewriting new lines that has __attribute_ in the second
example) to be in git-core; that clearly is outside the scope of the
plumbing. But the part that finds these "annotations", especially
if we can come up with a fast implementation that may be hard to
script, may be a good addition to the plumbing command set.
Thoughts?
On 12 February 2016 at 09:06, Junio C Hamano [off-list ref] wrote:
To realize this, there are low-hanging-fruit building blocks that
are trivial:
- Such an annotation can be made as a note attached to the commit
in question;
- Such a check can be done in pre-commit hook;
- Such a pre-commit hook can iterate over this set of commits
DIFF=$(git rev-list --left-right HEAD...MERGE_HEAD)
collect these Merge Gate annotations from the commit appears on
the left hand side (e.g. only exists on the trunk that a side
branch is about to be merged in), and run them.
But the last one feels very costly, and I suspect that there must be
a better way to do this. I do not think we want the "what to do"
part (i.e. checking new lines for __attribute__ in the first
example, or rewriting new lines that has __attribute_ in the second
example) to be in git-core; that clearly is outside the scope of the
plumbing. But the part that finds these "annotations", especially
if we can come up with a fast implementation that may be hard to
script, may be a good addition to the plumbing command set.
Thoughts?
What is the benefit in doing this in notes vs having the tests in the
working tree?
Pros:
- merge-gates can be added after the commit, but will stick with the
commit if it moves around (as opposed to creating a second commit to
add the merge-gate to the working tree)
- cross repository standards can be established that allow
merge-gates to be detected and run automatically (arguably could be
done with a standardised folder structure too, but that is more
disruptive)
- can view the relevant merge-gates in git log against each commit
that they are protecting
Cons:
- difficult to see the current complete set of merge-gates
- difficult to make changes to a number of merge-gates at the same time
- poorly defined behaviour when multiple merge-gates overlap in
functionality. Which gates execute first? What if I reorder the
commits?
My practical knowledge of notes is severely lacking so excuse me if I
missed anything obvious.
Regards,
Andrew Ardill
(sorry for the double post Junio, gmail ate my plain text encoding at
some point...)
On Thu, Feb 11, 2016 at 2:42 PM, Andrew Ardill [off-list ref] wrote:
On 12 February 2016 at 09:06, Junio C Hamano [off-list ref] wrote:
quoted
To realize this, there are low-hanging-fruit building blocks that
are trivial:
- Such an annotation can be made as a note attached to the commit
in question;
- Such a check can be done in pre-commit hook;
- Such a pre-commit hook can iterate over this set of commits
DIFF=$(git rev-list --left-right HEAD...MERGE_HEAD)
collect these Merge Gate annotations from the commit appears on
the left hand side (e.g. only exists on the trunk that a side
branch is about to be merged in), and run them.
But the last one feels very costly, and I suspect that there must be
a better way to do this. I do not think we want the "what to do"
part (i.e. checking new lines for __attribute__ in the first
example, or rewriting new lines that has __attribute_ in the second
example) to be in git-core; that clearly is outside the scope of the
plumbing. But the part that finds these "annotations", especially
if we can come up with a fast implementation that may be hard to
script, may be a good addition to the plumbing command set.
Thoughts?
What is the benefit in doing this in notes vs having the tests in the
working tree?
Pros:
- merge-gates can be added after the commit, but will stick with the
commit if it moves around (as opposed to creating a second commit to
add the merge-gate to the working tree)
- cross repository standards can be established that allow
merge-gates to be detected and run automatically (arguably could be
done with a standardised folder structure too, but that is more
disruptive)
- can view the relevant merge-gates in git log against each commit
that they are protecting
Cons:
- difficult to see the current complete set of merge-gates
- difficult to make changes to a number of merge-gates at the same time
- poorly defined behaviour when multiple merge-gates overlap in
functionality. Which gates execute first? What if I reorder the
commits?
The way I could imagine "merge gates" currently:
* they are some kind of invariant to be checked, or an action
performed, an event
* they can be introduced by a commit X.
* they can be turned off by a commit Y
* an offspring commit inherits all "merge gates" from its parents (in
order of the parents
So the event for one merge gate is in effect iff you merge one commit from X..Y
Now we want to know for a given commit C, which merge gates are there?
To find all events we would need to walk the whole history of C and record
all found events, which are not turned off.
So I'd think that could be accelerated with event bitmaps (which work
similar to the
reachability bitmaps, but having a different goal and record which
events are alive
for certain commits, such that you only need to walk a bounded set of commits to
find out.
When first reading this email I thought this is a typical maintainers problem,
so it should happen all the time in larger projects, such as linux, how do they
handle system wide refactorings?
My practical knowledge of notes is severely lacking so excuse me if I
missed anything obvious.
Regards,
Andrew Ardill
(sorry for the double post Junio, gmail ate my plain text encoding at
some point...)
--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html