diff mbox series

[RFC/PoC,5/5] docbundle: provide the git-log History Simplification example

Message ID 20221102224843.2104-6-philipoakley@iee.email (mailing list archive)
State New, archived
Headers show
Series Provide example docbundles | expand

Commit Message

Philip Oakley Nov. 2, 2022, 10:48 p.m. UTC
Create the History Simplification example and bundle it.

ToDo: add the tests that the man page attempts to demonstrate.

add the effects of `--graph` to the tests and man page.

/* NEEDSWORK */

Signed-off-by: Philip Oakley <philipoakley@iee.email>
---
 t/t9990-history-simplification.sh | 261 ++++++++++++++++++++++++++++++
 1 file changed, 261 insertions(+)
 create mode 100644 t/t9990-history-simplification.sh

Comments

Ævar Arnfjörð Bjarmason Nov. 3, 2022, 9:17 a.m. UTC | #1
On Wed, Nov 02 2022, Philip Oakley wrote:

> +note () {
> +	git tag "$1"
> +}

Aren't you just...

> +test_expect_success setup '
> +	# get the structure set out, then the file contents
> +	echo "asdf" >foo &&
> +	echo "quux" >quux &&
> +	git add foo quux &&
> +	test_tick && git commit -m "I: Initial commit" &&
> +	note I &&

...re-inventing "test_commit" here (including the "echo")?
Philip Oakley Nov. 3, 2022, 7:50 p.m. UTC | #2
On 03/11/2022 09:17, Ævar Arnfjörð Bjarmason wrote:
> On Wed, Nov 02 2022, Philip Oakley wrote:
>
>> +note () {
>> +	git tag "$1"
>> +}
> Aren't you just...
>
>> +test_expect_success setup '
>> +	# get the structure set out, then the file contents
>> +	echo "asdf" >foo &&
>> +	echo "quux" >quux &&
>> +	git add foo quux &&
>> +	test_tick && git commit -m "I: Initial commit" &&
>> +	note I &&
> ...re-inventing "test_commit" here (including the "echo")?

Probably.

It was a bit of 'monkey coding' of an earlier test without any real
study.. As you can probably tell it is just getting the spirit of the
history simplification setup in place..
diff mbox series

Patch

diff --git a/t/t9990-history-simplification.sh b/t/t9990-history-simplification.sh
new file mode 100644
index 0000000000..ada06698d5
--- /dev/null
+++ b/t/t9990-history-simplification.sh
@@ -0,0 +1,261 @@ 
+#!/bin/sh
+
+test_description='History simplification man page'
+
+GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
+export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
+
+. ./test-lib.sh
+
+note () {
+	git tag "$1"
+}
+
+unnote () {
+	test_when_finished "rm -f tmp" &&
+	git name-rev --tags --annotate-stdin >tmp &&
+	sed -e "s|$OID_REGEX (tags/\([^)]*\)) |\1 |g" <tmp
+}
+
+#
+# Create a test repo with the man(3) History Simplification commit graph:
+#
+# We assume, for the TREESAME check,
+# that you are filtering for a file `foo` in this commit graph:
+#-----------------------------------------------------------------------
+#	  .-A---M---N---O---P---Q
+#	 /     /   /   /   /   /
+#	I     B   C   D   E   Y
+#	 \   /   /   /   /   /
+#	  `-------------'   X
+#-----------------------------------------------------------------------
+#The horizontal line of history A---Q is taken to be the first parent of
+#each merge.
+#
+# See Documentation/rev-list-options.txt
+# see https://groups.google.com/d/msgid/git-users/11286f4a-c961-4d12-91a0-f49e34d8691bn%40googlegroups.com. for git-user discussion.
+# https://github.com/ChuckTest/git-history-test
+# C:\git-sdk-64\usr\src\git-history-test
+
+test_expect_success setup '
+	# get the structure set out, then the file contents
+	echo "asdf" >foo &&
+	echo "quux" >quux &&
+	git add foo quux &&
+	test_tick && git commit -m "I: Initial commit" &&
+	note I &&
+
+	git branch B &&
+	git branch C &&
+	git branch D &&
+	git branch E &&
+
+	echo "foo" >foo &&
+	git add foo &&
+	test_tick && git commit -m "A" &&
+	note A &&
+
+	git checkout B &&
+	echo "foo" >foo &&
+	git add foo &&
+	test_tick && git commit -m "B" &&
+	note B &&
+
+	git checkout main &&
+	test_tick && git merge B -m "M: trivial merge" &&
+	note M &&
+
+	git checkout C &&
+	# is this needed?
+	#echo "other" >other &&
+	#git add other &&
+	test_tick && git commit --allow-empty -m "C: identical to I" &&
+	note C &&
+
+	git checkout main &&
+	test_tick && git merge C --no-commit -m "N: !TREESAME any parent" &&
+	echo "foobar" >foo &&
+	git add foo &&
+	git commit -m "N: !TREESAME any parent" &&
+	note N &&
+
+	git checkout D &&
+	echo "baz" >foo &&
+	git add foo &&
+	test_tick && git commit -m "D" &&
+	note D &&
+
+	git checkout main &&
+	test_tick &&
+	test_must_fail git merge D --no-commit &&
+	echo "foobarbaz" >foo &&
+	git add foo &&
+	git commit -m "O: !TREESAME any parent" &&
+	note O &&
+
+	git checkout E &&
+	echo "xyzzy" >quux &&
+	git add quux &&
+	test_tick && git commit -m "E" &&
+	note E &&
+
+	git checkout main &&
+	test_tick &&
+	git merge E --no-commit &&
+	echo "quux xyzzy" >quux &&
+	git add quux &&
+	git commit -m "P: TREESAME O; !E" &&
+	note S &&
+
+	git checkout --orphan Side &&
+	git rm -f foo quux &&
+	echo "initial" >side &&
+	git add side &&
+	git commit -m "X" &&
+	note X &&
+
+	echo "side" >side &&
+	git add side &&
+	git commit -m "Y" &&
+	note Y &&
+
+	git checkout main &&
+	test_tick && 
+	git merge Side --allow-unrelated-histories -m "Q: TREESAME P; !Y" &&
+	note Q
+'
+
+test_expect_success 'bundle history-simplification repo' '
+	git bundle create ${GIT_BUNDLE_DIR}/t9990-history-simplification.bndl --all
+'
+
+# Test it!
+# `rev-list` walks backwards through history, including or excluding
+# commits based on whether `--full-history` and/or parent rewriting
+# (via `--parents` or `--children`) are used. The following settings
+# are available.
+# 
+# Default mode::
+# 	Commits are included if they are not TREESAME to any parent
+# 	(though this can be changed, see `--sparse` below).  If the
+# 	commit was a merge, and it was TREESAME to one parent, follow
+# 	only that parent.  (Even if there are several TREESAME
+# 	parents, follow only one of them.)  Otherwise, follow all
+# 	parents.
+# +
+# This results in:
+# +
+# -----------------------------------------------------------------------
+# 	  .-A---N---O
+# 	 /     /   /
+# 	I---------D
+# -----------------------------------------------------------------------
+# +
+# Note how the rule to only follow the TREESAME parent, if one is
+# available, removed `B` from consideration entirely.  `C` was
+# considered via `N`, but is TREESAME.  Root commits are compared to an
+# empty tree, so `I` is !TREESAME.
+# +
+# Parent/child relations are only visible with `--parents`, but that does
+# not affect the commits selected in default mode, so we have shown the
+# parent lines.
+# 
+# --full-history without parent rewriting::
+# 	This mode differs from the default in one point: always follow
+# 	all parents of a merge, even if it is TREESAME to one of them.
+# 	Even if more than one side of the merge has commits that are
+# 	included, this does not imply that the merge itself is!  In
+# 	the example, we get
+# +
+# -----------------------------------------------------------------------
+# 	I  A  B  N  D  O  P  Q
+# -----------------------------------------------------------------------
+# +
+# `M` was excluded because it is TREESAME to both parents.  `E`,
+# `C` and `B` were all walked, but only `B` was !TREESAME, so the others
+# do not appear.
+# +
+# Note that without parent rewriting, it is not really possible to talk
+# about the parent/child relationships between the commits, so we show
+# them disconnected.
+# 
+# --full-history with parent rewriting::
+# 	Ordinary commits are only included if they are !TREESAME
+# 	(though this can be changed, see `--sparse` below).
+# +
+# Merges are always included.  However, their parent list is rewritten:
+# Along each parent, prune away commits that are not included
+# themselves.  This results in
+# +
+# -----------------------------------------------------------------------
+# 	  .-A---M---N---O---P---Q
+# 	 /     /   /   /   /
+# 	I     B   /   D   /
+# 	 \   /   /   /   /
+# 	  `-------------'
+# -----------------------------------------------------------------------
+# +
+# Compare to `--full-history` without rewriting above.  Note that `E`
+# was pruned away because it is TREESAME, but the parent list of P was
+# rewritten to contain `E`'s parent `I`.  The same happened for `C` and
+# `N`, and `X`, `Y` and `Q`.
+# 
+# In addition to the above settings, you can change whether TREESAME
+# affects inclusion:
+# 
+# --dense::
+# 	Commits that are walked are included if they are not TREESAME
+# 	to any parent.
+# 
+# --sparse::
+# 	All commits that are walked are included.
+# +
+# Note that without `--full-history`, this still simplifies merges: if
+# one of the parents is TREESAME, we follow only that one, so the other
+# sides of the merge are never walked.
+# 
+# --simplify-merges::
+# 	First, build a history graph in the same way that
+# 	`--full-history` with parent rewriting does (see above).
+# +
+# Then simplify each commit `C` to its replacement `C'` in the final
+# history according to the following rules:
+# +
+# --
+# * Set `C'` to `C`.
+# +
+# * Replace each parent `P` of `C'` with its simplification `P'`.  In
+#   the process, drop parents that are ancestors of other parents or that are
+#   root commits TREESAME to an empty tree, and remove duplicates, but take care
+#   to never drop all parents that we are TREESAME to.
+# +
+# * If after this parent rewriting, `C'` is a root or merge commit (has
+#   zero or >1 parents), a boundary commit, or !TREESAME, it remains.
+#   Otherwise, it is replaced with its only parent.
+# --
+# +
+# The effect of this is best shown by way of comparing to
+# `--full-history` with parent rewriting.  The example turns into:
+# +
+# -----------------------------------------------------------------------
+# 	  .-A---M---N---O
+# 	 /     /       /
+# 	I     B       D
+# 	 \   /       /
+# 	  `---------'
+# -----------------------------------------------------------------------
+# +
+# Note the major differences in `N`, `P`, and `Q` over `--full-history`:
+# +
+# --
+# * `N`'s parent list had `I` removed, because it is an ancestor of the
+#   other parent `M`.  Still, `N` remained because it is !TREESAME.
+# +
+# * `P`'s parent list similarly had `I` removed.  `P` was then
+#   removed completely, because it had one parent and is TREESAME.
+# +
+# * `Q`'s parent list had `Y` simplified to `X`. `X` was then removed, because it
+#   was a TREESAME root. `Q` was then removed completely, because it had one
+#   parent and is TREESAME.
+
+test_done