Hmm …
Hmm …
Posted Nov 5, 2018 19:47 UTC (Mon) by epa (subscriber, #39769)In reply to: Hmm … by ms-tg
Parent article: Apache Subversion 1.11.0 released
That would take care of the 'doing this commit just so git doesn't become confused' problem and it would also help with patch sets and work on a particular feature -- where the whole work is merged as a single logical commit, but by bumping up the default nesting level you can drill down to the component changes. You can emulate this a little bit with branching and merging (where there is a single commit merging the feature branch) but it's clunky by comparison.
Posted Nov 6, 2018 3:06 UTC (Tue)
by neilbrown (subscriber, #359)
[Link] (7 responses)
Posted Nov 6, 2018 12:00 UTC (Tue)
by epa (subscriber, #39769)
[Link] (6 responses)
Perhaps all this could be done with tags, I'm not sure -- but I like the idea that groups are immutable once created (just like ordinary commits), yet at the same time you can push a new group-declaring commit retrospectively making some previous commits part of your group. (I think it might be wise to forbid group spaghetti where a commit can be part of two overlapping groups, except for the straightforward case of nesting. That is something a git hook could take care of. The git machinery itself doesn't really get affected by that, however.)
Posted Nov 6, 2018 13:45 UTC (Tue)
by smurf (subscriber, #17840)
[Link]
That special-ness could be even signalled without touching the core data structure: a normal no-follow merge commit mentions its parents in a specific order (the "null" parent is first). A "this is a group" commit would simply invert that.
Posted Nov 6, 2018 23:02 UTC (Tue)
by neilbrown (subscriber, #359)
[Link]
For the moment I'm thinking of a group as a merge commit plus all the commits on the right side of the merge that aren't also on the left (for some reasonable understanding of "left" and "right").
1/ you want "git bisect" to recognise these merge points and preferentially test those, rather than commits on the right. I suspect it would be fairly easy to do this for all merges. It would be expected to increase the number of steps a little, but probably just by one or two.
2/ you want to allow a new commit to mark an existing commit as part of it's group. This is comparatively huge. For git-bisect to be able to notice, you would need to create some sort of index from child commits back to their parents, at least for merged commits.
I've occasionally thought this would be good for patches labeled "Fixes:". If they were attached to the patch they fix in a way that git-bisect could detect, then maybe it could always pull in fix - or a least warn that a fix was missing.
I think there are ideas worth exploring here (if only I had the time).
Posted Nov 9, 2018 19:52 UTC (Fri)
by mathstuf (subscriber, #69389)
[Link] (3 responses)
I think this would be handled well with a `git bisect --first-parent` option which bisects the first-parent history and then starts bisecting the history between the two commits recursively on the remaining history using the same first-parent semantics. Then your "groupings" are exactly merges.
Posted Nov 12, 2018 4:17 UTC (Mon)
by neilbrown (subscriber, #359)
[Link] (2 responses)
What version of git do you need? Do you give "--first-parent" when you "git bisect start" or on every "git bisect good/bad"??
"revision.c" in current git contains the line
revision.c: die(_("--first-parent is incompatible with --bisect"));
which makes me wonder....
Posted Nov 12, 2018 8:26 UTC (Mon)
by smurf (subscriber, #17840)
[Link]
If you only do first-parent then you may end up at the point where your only possible refinement is to start bisecting a group, which you forbade git to do – after all, you used "--first-parent".
Thus, this situation requires additional code – which hasn't been implemented yet.
Posted Nov 12, 2018 16:24 UTC (Mon)
by mathstuf (subscriber, #69389)
[Link]
Posted Nov 6, 2018 6:28 UTC (Tue)
by smurf (subscriber, #17840)
[Link] (3 responses)
Posted Nov 6, 2018 7:08 UTC (Tue)
by epa (subscriber, #39769)
[Link] (2 responses)
Also it only really gives one level of nesting and is a bit clunky. Take for example the problem mentioned in an earlier post. To rename a file you may first do ‘git mv’ in one commit then change the contents in the next. Does anyone really land a separate branch just for that? What I envisage is something like ‘git group open; git commit; ...; git group close’. On closing the group you are prompted for a top-level commit message. Or you could group commits when rebasing. This would be similar to the current support for squashing commits into one, but still allowing the individual changes to be retrieved if you choose to ‘look inside’.
Posted Nov 6, 2018 19:44 UTC (Tue)
by MrWim (subscriber, #47432)
[Link] (1 responses)
Put this in If you want to get a log with these groups collapsed run Hmm …
Would it require changes in the git engine to achieve what you want, or would it be sufficient to add some commit-group-aware interfaces?
Hmm …
Hmm …
Hmm … commit groups
Between 4.1 and 4.19 (just a random sample) there are 20808 merge commits and 232659 non-merges. That means about 10% of commits are merges. Adding an index for the children of all merges should be manageable. If it was just "all merges with some magic string in the message" it would be even more manageable. I'm not sure if that is quite enough to allow git-bisect to do what we want.
Hmm …
Hmm …
Hmm …
Hmm …
Hmm …
Hmm …
Hmm …
git-group.sh, mark it executable and run git config --global alias.group '!/path/to/git-group.sh'. You will then be able to run git group open and git group close. It's a quick and dirty hack, with precious little error handling, but it will support nesting and should be convenient to use.git log --first-parent.git-group.sh follows:
#!/bin/sh -e
fail() {
echo $@ >&2
exit 1
}
current_branch=$(git symbolic-ref --short HEAD)
cmd=$1
shift
case "$cmd" in
open)
git checkout -b ${current_branch}-group
;;
close)
parent=$(echo $current_branch | sed 's/-group$//')
[ "$parent" != "$current_branch" ] || fail "Not in a group!"
git checkout "$parent"
git merge --no-ff --no-commit --log "$current_branch" --edit
printf '# Enter top-level commit message here. Sub-commit messages follow:\n\n' >.group_commit_msg
git log --first-parent --format=%B "${parent}...${current_branch}" >>.group_commit_msg
git commit --file .group_commit_msg --edit
rm .group_commit_msg
git branch -D "$current_branch"
;;
*)
fail "Unknown command $cmd"
;;
esac
