[RFC PATCH v3] technical doc: add a design doc for the evolve command

2018-11-30 Thread sxenos
From: Stefan Xenos 

This document describes what a change graph for
git would look like, the behavior of the evolve command,
and the changes planned for other commands.

Signed-off-by: Stefan Xenos 
---
 Documentation/technical/evolve.txt | 1000 
 1 file changed, 1000 insertions(+)
 create mode 100644 Documentation/technical/evolve.txt

diff --git a/Documentation/technical/evolve.txt 
b/Documentation/technical/evolve.txt
new file mode 100644
index 00..bfec6fcf82
--- /dev/null
+++ b/Documentation/technical/evolve.txt
@@ -0,0 +1,1000 @@
+Evolve
+==
+
+Objective
+=
+Create an "evolve" command to help users craft a high quality commit history.
+Users can improve commits one at a time and in any order, then run git evolve 
to
+rewrite their recent history to ensure everything is up-to-date. We track
+amendments to a commit over time in a change graph. Users can share their
+progress with others by exchanging their change graphs using the standard push,
+fetch, and format-patch commands.
+
+Status
+==
+This proposal has not been implemented yet.
+
+Background
+==
+Imagine you have three sequential changes up for review and you receive 
feedback
+that requires editing all three changes. We'll define the word "change"
+formally later, but for the moment let's say that a change is a 
work-in-progress
+whose final version will be submitted as a commit in the future.
+
+While you're editing one change, more feedback arrives on one of the others.
+What do you do?
+
+The evolve command is a convenient way to work with chains of commits that are
+under review. Whenever you rebase or amend a commit, the repository remembers
+that the old commit is obsolete and has been replaced by the new one. Then, at
+some point in the future, you can run "git evolve" and the correct sequence of
+rebases will occur in the correct order such that no commit has an obsolete
+parent.
+
+Part of making the "evolve" command work involves tracking the edits to a 
commit
+over time, which is why we need an change graph. However, the change
+graph will also bring other benefits:
+
+- Users can view the history of a change directly (the sequence of amends and
+  rebases it has undergone, orthogonal to the history of the branch it is on).
+- It will be possible to quickly locate and list all the changes the user
+  currently has in progress.
+- It can be used as part of other high-level commands that combine or split
+  changes.
+- It can be used to decorate commits (in git log, gitk, etc) that are either
+  obsolete or are the tip of a work in progress.
+- By pushing and pulling the change graph, users can collaborate more
+  easily on changes-in-progress. This is better than pushing and pulling the
+  changes themselves since the change graph can be used to locate a more
+  specific merge base, allowing for better merges between different versions of
+  the same change. 
+- It could be used to correctly rebase local changes and other local branches
+  after running git-filter-branch.
+- It can replace the change-id footer used by gerrit.
+
+Goals
+-
+Legend: Goals marked with P0 are required. Goals marked with Pn should be
+attempted unless they interfere with goals marked with Pn-1.
+
+P0. All commands that modify commits (such as the normal commit --amend or
+rebase command) should mark the old commit as being obsolete and replaced 
by
+the new one. No additional commands should be required to keep the
+change graph up-to-date.
+P0. Any commit that may be involved in a future evolve command should not be
+garbage collected. Specifically:
+- Commits that obsolete another should not be garbage collected until
+  user-specified conditions have occurred and the change has expired from
+  the reflog. User specified conditions for removing changes include:
+  - The user explicitly deleted the change.
+  - The change was merged into a specific branch.
+- Commits that have been obsoleted by another should not be garbage
+  collected if any of their replacements are still being retained.
+P0. A commit can be obsoleted by more than one replacement (called divergence).
+P0. Must be able to resolve divergence (convergence).
+P1. Users should be able to share chains of obsolete changes in order to
+collaborate on WIP changes.
+P2. Such sharing should be at the user’s option. That is, it should be possible
+to directly share a change without also sharing the file states or commit
+comments from the obsolete changes that led up to it, and the choice not to
+share those commits should not require changing any commit hashes.
+P2. It should be possible to discard part or all of the change graph
+without discarding the commits themselves that are already present in
+branches and the reflog.
+P2. Provide sufficient information to replace gerrit's Change-Id footers.
+
+Similar technologies
+
+There are some 

[RFC PATCH v2] technical doc: add a design doc for the evolve command

2018-11-18 Thread sxenos
From: Stefan Xenos 

This document describes what a change graph for
git would look like, the behavior of the evolve command,
and the changes planned for other commands.

Signed-off-by: Stefan Xenos 
---
 Documentation/technical/change-graph.txt | 928 +++
 1 file changed, 928 insertions(+)
 create mode 100644 Documentation/technical/change-graph.txt

diff --git a/Documentation/technical/change-graph.txt 
b/Documentation/technical/change-graph.txt
new file mode 100644
index 00..2f4051f65f
--- /dev/null
+++ b/Documentation/technical/change-graph.txt
@@ -0,0 +1,928 @@
+Change Graph
+
+
+Objective
+=
+Track the amendments to a commit over time in a change graph. Allow users to
+exchange such change graphs, and introduce a new "evolve" command that
+uses the graph to rebase commits based on obsolete parents.
+
+Background
+==
+Imagine you have three sequential changes up for review and you receive 
feedback
+that requires editing all three changes. We'll define the word "change"
+formally later, but for the moment let's say that a change is a 
work-in-progress
+whose final version will be submitted as a commit in the future.
+
+While you're editing one change, more feedback arrives on one of the others.
+What do you do?
+
+The evolve command is a convenient way to work with chains of commits that are
+under review. Whenever you rebase or amend a commit, the repository remembers
+that the old commit is obsolete and has been replaced by the new one. Then, at
+some point in the future, you can run "git evolve" and the correct sequence of
+rebases will occur in the correct order such that no commit has an obsolete
+parent.
+
+Part of making the "evolve" command work involves tracking the edits to a 
commit
+over time, which is why we need an change graph. However, the change
+graph will also bring other benefits:
+
+- Users can view the history of a change directly (the sequence of amends and
+  rebases it has undergone, orthogonal to the history of the branch it is on).
+- It will be possible to quickly locate and list all the changes the user
+  currently has in progress.
+- It can be used as part of other high-level commands that combine or split
+  changes.
+- It can be used to decorate commits (in git log, gitk, etc) that are either
+  obsolete or are the tip of a work in progress.
+- By pushing and pulling the change graph, users can collaborate more
+  easily on changes-in-progress. This is better than pushing and pulling the
+  changes themselves since the change graph can be used to locate a more
+  specific merge base, allowing for better merges between different versions of
+  the same change. 
+- It could be used to correctly rebase local changes and other local branches
+  after running git-filter-branch.
+- It can replace the change-id footer used by gerrit.
+
+Goals
+-
+Legend: Goals marked with P0 are required. Goals marked with Pn should be
+attempted unless they interfere with goals marked with Pn-1.
+
+P0. All commands that modify commits (such as the normal commit --amend or
+rebase command) should mark the old commit as being obsolete and replaced 
by
+the new one. No additional commands should be required to keep the
+change graph up-to-date.
+P0. Any commit that may be involved in a future evolve command should not be
+garbage collected. Specifically:
+- Commits that obsolete another should not be garbage collected until
+  user-specified conditions have occurred and the change has expired from
+  the reflog. User specified conditions for removing changes include:
+  - The user explicitly deleted the change.
+  - The change was merged into a specific branch.
+- Commits that have been obsoleted by another should not be garbage
+  collected if any of their replacements are still being retained.
+P0. A commit can be obsoleted by more than one replacement (called divergence).
+P0. Must be able to resolve divergence (convergence).
+P1. Users should be able to share chains of obsolete changes in order to
+collaborate on WIP changes.
+P2. Such sharing should be at the user’s option. That is, it should be possible
+to directly share a change without also sharing the file states or commit
+comments from the obsolete changes that led up to it, and the choice not to
+share those commits should not require changing any commit hashes.
+P2. It should be possible to discard part or all of the change graph
+without discarding the commits themselves that are already present in
+branches and the reflog.
+P2. Provide sufficient information to replace gerrit's Change-Id footers.
+
+Similar technologies
+
+There are some other technologies that address the same end-user problem.
+
+Rebase -i can be used to solve the same problem, but users can't easily switch
+tasks midway through an interactive rebase or have more than one interactive
+rebase going on at the same 

[RFC PATCH v2] technical doc: add a design doc for the evolve command

2018-11-18 Thread sxenos
From: Stefan Xenos 

This document describes what a change graph for
git would look like, the behavior of the evolve command,
and the changes planned for other commands.

Signed-off-by: Stefan Xenos 
---
 Documentation/technical/change-graph.txt | 928 +++
 1 file changed, 928 insertions(+)
 create mode 100644 Documentation/technical/change-graph.txt

diff --git a/Documentation/technical/change-graph.txt 
b/Documentation/technical/change-graph.txt
new file mode 100644
index 00..2f4051f65f
--- /dev/null
+++ b/Documentation/technical/change-graph.txt
@@ -0,0 +1,928 @@
+Change Graph
+
+
+Objective
+=
+Track the amendments to a commit over time in a change graph. Allow users to
+exchange such change graphs, and introduce a new "evolve" command that
+uses the graph to rebase commits based on obsolete parents.
+
+Background
+==
+Imagine you have three sequential changes up for review and you receive 
feedback
+that requires editing all three changes. We'll define the word "change"
+formally later, but for the moment let's say that a change is a 
work-in-progress
+whose final version will be submitted as a commit in the future.
+
+While you're editing one change, more feedback arrives on one of the others.
+What do you do?
+
+The evolve command is a convenient way to work with chains of commits that are
+under review. Whenever you rebase or amend a commit, the repository remembers
+that the old commit is obsolete and has been replaced by the new one. Then, at
+some point in the future, you can run "git evolve" and the correct sequence of
+rebases will occur in the correct order such that no commit has an obsolete
+parent.
+
+Part of making the "evolve" command work involves tracking the edits to a 
commit
+over time, which is why we need an change graph. However, the change
+graph will also bring other benefits:
+
+- Users can view the history of a change directly (the sequence of amends and
+  rebases it has undergone, orthogonal to the history of the branch it is on).
+- It will be possible to quickly locate and list all the changes the user
+  currently has in progress.
+- It can be used as part of other high-level commands that combine or split
+  changes.
+- It can be used to decorate commits (in git log, gitk, etc) that are either
+  obsolete or are the tip of a work in progress.
+- By pushing and pulling the change graph, users can collaborate more
+  easily on changes-in-progress. This is better than pushing and pulling the
+  changes themselves since the change graph can be used to locate a more
+  specific merge base, allowing for better merges between different versions of
+  the same change. 
+- It could be used to correctly rebase local changes and other local branches
+  after running git-filter-branch.
+- It can replace the change-id footer used by gerrit.
+
+Goals
+-
+Legend: Goals marked with P0 are required. Goals marked with Pn should be
+attempted unless they interfere with goals marked with Pn-1.
+
+P0. All commands that modify commits (such as the normal commit --amend or
+rebase command) should mark the old commit as being obsolete and replaced 
by
+the new one. No additional commands should be required to keep the
+change graph up-to-date.
+P0. Any commit that may be involved in a future evolve command should not be
+garbage collected. Specifically:
+- Commits that obsolete another should not be garbage collected until
+  user-specified conditions have occurred and the change has expired from
+  the reflog. User specified conditions for removing changes include:
+  - The user explicitly deleted the change.
+  - The change was merged into a specific branch.
+- Commits that have been obsoleted by another should not be garbage
+  collected if any of their replacements are still being retained.
+P0. A commit can be obsoleted by more than one replacement (called divergence).
+P0. Must be able to resolve divergence (convergence).
+P1. Users should be able to share chains of obsolete changes in order to
+collaborate on WIP changes.
+P2. Such sharing should be at the user’s option. That is, it should be possible
+to directly share a change without also sharing the file states or commit
+comments from the obsolete changes that led up to it, and the choice not to
+share those commits should not require changing any commit hashes.
+P2. It should be possible to discard part or all of the change graph
+without discarding the commits themselves that are already present in
+branches and the reflog.
+P2. Provide sufficient information to replace gerrit's Change-Id footers.
+
+Similar technologies
+
+There are some other technologies that address the same end-user problem.
+
+Rebase -i can be used to solve the same problem, but users can't easily switch
+tasks midway through an interactive rebase or have more than one interactive
+rebase going on at the same 

[PATCH] technical doc: add a design doc for the evolve command

2018-11-14 Thread sxenos
From: Stefan Xenos 

This document describes what an obsolescence graph for
git would look like, the behavior of the evolve command,
and the changes planned for other commands.

Signed-off-by: Stefan Xenos 
---
 Documentation/technical/evolve.txt | 885 +
 1 file changed, 885 insertions(+)
 create mode 100644 Documentation/technical/evolve.txt

diff --git a/Documentation/technical/evolve.txt 
b/Documentation/technical/evolve.txt
new file mode 100644
index 00..88470eada3
--- /dev/null
+++ b/Documentation/technical/evolve.txt
@@ -0,0 +1,885 @@
+Git Obsolescence Graph
+==
+
+Objective
+-
+Track the edits to a commit over time in an obsolescence graph.
+
+Background
+--
+Imagine you have three dependent changes up for review and you receive feedback
+that requires editing all three changes. While you're editing one, more 
feedback
+arrives on one of the others. What do you do?
+
+The evolve command is a convenient way to work with chains of commits that are
+under review. Whenever you rebase or amend a commit, the repository remembers
+that the old commit is obsolete and has been replaced by the new one. Then, at
+some point in the future, you can run "git evolve" and the correct sequence of
+rebases will occur in the correct order such that no commit has an obsolete
+parent.
+
+Part of making the "evolve" command work involves tracking the edits to a 
commit
+over time, which is why we need an obsolescence graph. However, the 
obsolescence
+graph will also bring other benefits:
+
+- Users can view the history of a commit directly (the sequence of amends and
+  rebases it has undergone, orthogonal to the history of the branch it is on).
+- It will be possible to quickly locate and list all the changes the user
+  currently has in progress.
+- It can be used as part of other high-level commands that combine or split
+  changes.
+- It can be used to decorate commits (in git log, gitk, etc) that are either
+  obsolete or are the tip of a work in progress.
+- By pushing and pulling the obsolescence graph, users can collaborate more
+  easily on changes-in-progress. This is better than pushing and pulling the
+  changes themselves since the obsolescence graph can be used to locate a more
+  specific merge base, allowing for better merges between different versions of
+  the same change.
+- It could be used to correctly rebase local changes and other local branches
+  after running git-filter-branch.
+- It can replace the change-id footer used by gerrit.
+
+Similar technologies
+
+There are some other technologies that address the same end-user problem.
+
+Rebase -i can be used to solve the same problem, but users can't easily switch
+tasks midway through an interactive rebase or have more than one interactive
+rebase going on at the same time. It can't handle the case where you have
+multiple changes sharing the same parent when that parent needs to be rebased
+and won't let you collaborate with others on resolving a complicated 
interactive
+rebase. You can think of rebase -i as a top-down approach and the evolve 
command
+as the bottom-up approach to the same problem.
+
+Several patch queue managers have been built on top of git (such as topgit,
+stgit, and quilt). They address the same user need. However they also rely on
+state managed outside git that needs to be kept in sync. Such state can be
+easily damaged when running a git native command that is unaware of the patch
+queue. They also typically require an explicit initialization step to be done 
by
+the user which creates workflow problems.
+
+Replacements (refs/replace) are superficially similar to obsolescences in that
+they describe that one commit should be replaced by another. However, they
+differ in both how they are created and how they are intended to be used.
+Obsolescences are created automatically by the commands a user runs, and they
+describe the user’s intent to perform a future rebase. Obsolete commits still
+appear in branches, logs, etc like normal commits (possibly with an extra
+decoration that marks them as obsolete). Replacements are typically created
+explicitly by the user, they are meant to be kept around for a long time, and
+they describe a replacement to be applied at read-time rather than as the input
+to a future operation. When a replaced commit is queried, it is typically 
hidden
+and swapped out with its replacement as though the replacement has already
+occurred.
+
+Goals
+-
+Legend: Goals marked with P0 are required. Goals marked with Pn should be
+attempted unless they interfere with goals marked with Pn-1.
+
+P0. All commands that modify commits (such as the normal commit --amend or
+rebase command) should mark the old commit as being obsolete and replaced 
by
+the new one. No additional commands should be required to keep the
+obsolescence graph up-to-date.
+P0. Any commit that may be involved in a future evolve