Re: [RFC] undo and redo

11 messages, 3 authors, 2016-06-15 · open the first message on its own page

Re: [RFC] undo and redo

From: Junio C Hamano <hidden>
Date: 2016-06-15 22:42:04

Daniel Barkalow [off-list ref] writes:
Generally, each subdirectory of refs/ has refs to objects of the same
type, and heads/ is commits, but other directories are other things. tags/
is all tag objects, and you could have undo/ be trees.
That's OK from the prune front, but I am not sure what the
ramifications of this for pulling, pushing, and resolving.
I would not recommend it without really thinking it through.

Also note that tags/ is not all tag objects.  I think "git tag"
by default creates a lightweight tag, not an annotated kind.

I think you could do either one of two things.  As usual, totally
untested.  Just thinking aloud.

(1) A hack.

     - Have a single "undo-redo" branch, which was forked from
       somewhere on the "master" branch.

     - When doing "undo", make a commit that has the current top
       of undo-redo branch as the first parent and the current
       HEAD commit as the second parent, using the tree that
       represents your snapshot, to grow "undo-redo" branch.

       No, this commit does *not* represent a merge, but I am
       abusing the capability to record more than one parent
       commits.

     - When running "redo", you would want a handy way to name
       what to redo.  You can say "undo-redo~N" to mean "Nth
       from the top of undo-redo branch.

       Your implementation of "redo" can either be (patch way):

       git-diff-tree -p undo-redo~N^ undo-redo~N | git apply --index

       or (merge way):

       git-read-tree -m undo-redo~N^2 undo-redo~N HEAD &&
       git-merge-cache -o git-merge-one-file-script -a

(2) Try StGIT.

Re: [RFC] undo and redo

From: Carl Baldwin <hidden>
Date: 2016-06-15 22:42:04

Well, both are good ideas.  Both are stack oriented, though.

I see what you mean about adding an undo directory to .git/refs/.  I
will do some tests... (read further)

On Wed, Aug 24, 2005 at 03:48:21PM -0700, Junio C Hamano wrote:
Daniel Barkalow [off-list ref] writes:
quoted
Generally, each subdirectory of refs/ has refs to objects of the same
type, and heads/ is commits, but other directories are other things. tags/
is all tag objects, and you could have undo/ be trees.
That's OK from the prune front, but I am not sure what the
ramifications of this for pulling, pushing, and resolving.
I would not recommend it without really thinking it through.
So, I've tried cloning, pulling to|from, pushing to|from and resolving
merges in a repository with undo information stored under
.git/refs/undo.  None of these operations seem to notice the existence
of this directory.  I think this is good.

The cloned repository does not end up 'inheriting' the undo directory
(as I would expect) but does end up with any objects reachable from the
undo tree.  However, these objects get pruned on the next 'git prune'.
This, I think, is minor.

Pull seems to ignore the undo directory and, of course, the objects
reachable by the undo trees.  This is what I expected and wanted.

Resolving merges worked as expected.

I think undo trees should be considered local to the repository and this
is the behavior that I observed.  I think this is a positive.

Before reading your message, I polished up the scripts and changed them
so that they store the undo tree and the base tree's hashes in the
.git/refs/undo directory.  Also, git-redo-script can take an optional
argument...the name of the undo to replay.  I guess undo should also
take an optional argument to give the undo tree some symbolic name.

I think this is getting rather solid.  Let me know what you think.

Here is the git-undo-script:

#!/bin/sh

. git-sh-setup-script || die "Not a git archive"

git-update-cache --refresh || exit 1

undodir=$GIT_DIR/refs/undo

undoinfo=$undodir/$(date +%Y.%m.%d.%H.%M.%S)

headtree=$(git-cat-file commit $(cat $GIT_DIR/HEAD) | sed -n 's/^tree //p')
undotree=$(git-write-tree)

if [ $headtree == $undotree ]; then
    echo There are no changes to undo.
else
    mkdir -p $(dirname $undoinfo)
    echo $headtree > $undoinfo.base
    echo $undotree > $undoinfo.undo

    echo Saved current state in $undodir as $(basename $undoinfo)

    git-read-tree -m -u $undotree $headtree
fi

# --- SNIP ---

and here, is the redo script

#!/bin/sh

. git-sh-setup-script || die "Not a git archive"

git-update-cache --refresh || exit 1

usage () {
    echo >&2 "Usage: git-redo-script [undo name]"
    exit 1
}

undodir=$GIT_DIR/refs/undo

# If an 'undo name' was given on the command line then try to use it.
# If not, then automatically pick the most recent undo.
undoinfo=
case "$#" in
0)
    undoinfo=$undodir/$(ls -tr $undodir | sed -n 's/\.undo$//p' | tail -n 1)
    ;;
1)
    if [ -s $undodir/$1 ]; then
        undoinfo=$(echo $undodir/$1 | sed -n "s/\.[^.]*$//p")
    elif [ -s $undodir/$1.undo -a -s $undodir/$1.base ]; then
        undoinfo=$undodir/$1
    else
        usage
    fi
    ;;
*)
    usage
    ;;
esac

# Perform a three-way merge between the base tree, undo tree and current index
if [ ! -s $undoinfo.undo -o ! -s $undoinfo.base ]; then
    echo "No undo information available"
else
    git-read-tree -u -m $(cat $undoinfo.base) $(cat $undoinfo.undo) $(git-write-tree)
    git-merge-cache git-merge-one-file-script -a

    rm -f $undoinfo.*
    test -z "$(ls $undodir)" && rmdir $undodir
fi

# --- SNIP ---

I would be glad to write up documentation and provide a patch.

Cheers,
Carl
Also note that tags/ is not all tag objects.  I think "git tag"
by default creates a lightweight tag, not an annotated kind.

I think you could do either one of two things.  As usual, totally
untested.  Just thinking aloud.

(1) A hack.

     - Have a single "undo-redo" branch, which was forked from
       somewhere on the "master" branch.

     - When doing "undo", make a commit that has the current top
       of undo-redo branch as the first parent and the current
       HEAD commit as the second parent, using the tree that
       represents your snapshot, to grow "undo-redo" branch.

       No, this commit does *not* represent a merge, but I am
       abusing the capability to record more than one parent
       commits.

     - When running "redo", you would want a handy way to name
       what to redo.  You can say "undo-redo~N" to mean "Nth
       from the top of undo-redo branch.

       Your implementation of "redo" can either be (patch way):

       git-diff-tree -p undo-redo~N^ undo-redo~N | git apply --index

       or (merge way):

       git-read-tree -m undo-redo~N^2 undo-redo~N HEAD &&
       git-merge-cache -o git-merge-one-file-script -a

(2) Try StGIT.
-- 
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 Carl Baldwin                        Systems VLSI Laboratory
 Hewlett Packard Company
 MS 88                               work: 970 898-1523
 3404 E. Harmony Rd.                 work: Carl.N.Baldwin@hp.com
 Fort Collins, CO 80525              home: Carl@ecBaldwin.net
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Re: [RFC] undo and redo

From: Junio C Hamano <hidden>
Date: 2016-06-15 22:42:04

So, I've tried cloning, pulling to|from, pushing to|from and resolving
merges in a repository with undo information stored under
.git/refs/undo.  None of these operations seem to notice the existence
of this directory.  I think this is good.
What I meant was that, when "undo/bar" is a tree object, things
may work in a funny way:

    $ git pull ../repo-with-undo/.git refs/undo/bar

    $ git push ../other-repo/.git undo/bar:refs/heads/foo
    $ cd ../other-repo && git resolve master foo 'Attempt to merge undo'

I think this undo/redo first needs to be thought about how best
it is used.  My guess is that the workflow you have in mind is
something like this:

    $ git checkout master
    $ hack hack hack
    # Hmph, it almost works, and but my boss says work on
    # some other feature that is more urgent
    $ git undo
    Saved current state as 2005-08-24T20:32:22
    $ work work work
    $ git commit -m 'Boring but urgent fix'
    # Ok, now let's back to the thing I wanted to do.
    $ git redo
    # I happen to know it is the last undo, so I did not name
    # it, but I could have said 2005-08-24T20:32:22
    $ hack more
    $ git commit -m 'Finally fix frotz.'

I see some problems in this.

One is minor.  As you mentioned about "giving undo a symbolic
name", after you accumulate a handful undo, you would need them
to have descriptive names, and a way to list them before using
"git redo".

But as Linus suggested in another reply, you could as well have
done this without inventing these two commands.

    $ git checkout master
    $ hack hack hack
    # Hmph, it almost works, and but my boss says work on
    # some other feature that is more urgent
    $ git commit -m 'WIP - fix frotz'
    $ git branch anchor-frotz
    $ git reset --hard master^
    $ work work work
    $ git commit -m 'Boring but urgent fix'
    # Ok, now let's go back to the thing I wanted to do.
    $ git pull . anchor-frotz
    $ rm .git/heads/anchor-frotz
    $ git reset --soft master^
    $ hack more
    $ git commit -m 'Finally fix frotz.'

The above flow would be something somebody not so organized
(like myself) would do.  A perfect person would have done this:

    $ git checkout -b frotz master
    $ hack hack hack
    # Hmph, it almost works, and but my boss says work on
    # some other feature that is more urgent
    $ git commit -m 'WIP - fix frotz'
    $ git checkout master
    $ work work work
    $ git commit -m 'Boring but urgent fix'
    # Ok, now let's go back to the thing I wanted to do.
    $ git checkout frotz
    $ git reset --soft HEAD^
    $ hack more
    $ git commit -m 'Finally fix frotz.'
    $ git checkout master
    $ git pull . frotz
    $ rm .git/refs/heads/frotz

The "perfect person" approach has an added benefit that you
could have made intermediate commits while doing "hacking",
because your hackery is always done in the "frotz" branch.

Of course, the scenarios your undo/redo is useful for may not be
limited to this "handling interrupt" use case.  If that is the
only thing it solves, then I do not see much point having them
as new commands.  I think the undo/redo has potential beyond
that.

So let's first clarify what kind of workflow these new commands
would help, how well that workflow is applicable in general, and
then how well these new commands would help that workflow.
I would be glad to write up documentation and provide a patch.
Sure.  I think a set of patches for new commands, and new
options to existing commands should ideally include the
following:

 - Justification, such as:

   - The problems new commands/options address.
   - The expected workflow the new commands/options fit in.
   - How useful that workflow is.
   - How impossible or cumbersome to achieve that workflow using
     existing tools.

   Some of these should go to the commit log message, and the
   documentation to describe the "best practice" workflow using
   the new feature should go to Documentation/howto/ directory.

 - Documentation.  Files Documentation/git-*.txt to describe
   new commands or updates to existing pages, new entry in
   Documentation/Makefile as necessary, and a new link from
   Documentation/git.txt to reach that page.

 - Implementation.

 - Test scripts in t/ directory, either a new test script or
   updates to existing ones, if the patch is to fix existing
   implementation.

Re: [RFC] undo and redo

From: Carl Baldwin <hidden>
Date: 2016-06-15 22:42:04

On Wed, Aug 24, 2005 at 10:06:45PM -0700, Junio C Hamano wrote:
quoted
So, I've tried cloning, pulling to|from, pushing to|from and resolving
merges in a repository with undo information stored under
.git/refs/undo.  None of these operations seem to notice the existence
of this directory.  I think this is good.
What I meant was that, when "undo/bar" is a tree object, things
may work in a funny way:

    $ git pull ../repo-with-undo/.git refs/undo/bar

    $ git push ../other-repo/.git undo/bar:refs/heads/foo
    $ cd ../other-repo && git resolve master foo 'Attempt to merge undo'
I was thinking that undo trees should not be pushed and pulled between
repositories.  For this I would use a new branch with proper commits as
Linus suggested.
I think this undo/redo first needs to be thought about how best
it is used.  My guess is that the workflow you have in mind is
something like this:

    $ git checkout master
    $ hack hack hack
    # Hmph, it almost works, and but my boss says work on
    # some other feature that is more urgent
    $ git undo
    Saved current state as 2005-08-24T20:32:22
    $ work work work
    $ git commit -m 'Boring but urgent fix'
    # Ok, now let's back to the thing I wanted to do.
    $ git redo
    # I happen to know it is the last undo, so I did not name
    # it, but I could have said 2005-08-24T20:32:22
    $ hack more
    $ git commit -m 'Finally fix frotz.'
For this, I may also use branching, as suggested.  I meant for undo/redo
to be a lighter weight alternative to allow for a faster context switch.
I am reluctant to commit what I have in my working directory unless I
have taken the time to review the changes using diff tools and cleaned
up considerably.  This is my way of being a careful developer.  Not all
developers share my style but I know many that do.  This makes
committing a heavy weight operation for me.

So, referring to your example.  If my 'boss' says that I need to switch
to working on 'Boring but urgent fix' for the next *week* or more I will
likely take the time to make the full context switch to a new branch and
work on the fix.  I may also choose to just clone my repository and use
a new working directory.  If the fix takes just a day or two I may do
the same.

Now, let's say that the 'fix' is something that I can do in an hour or
two and quickly get back to where I was.  In this context, making the
full context switch can feel very cumbersome compared to the amount of
work required to make the fix.  Now, a simple 'git undo' will ease this
switch.

Another example is if I'm working on a commit and suddenly get a
brilliant idea for some easy modification that I want to make and commit
by itself before making this commit.  I can do this easily with

        % git undo
        % carefully make easy change
        % git commit
        % git redo

Having a light-weight alternative like this could make the difference
between realizing the easy, brilliant idea and forgetting about it on
the back burner because it was just too cumbersome to make the context
switch.

The bottom line is that I don't argue against using the existing
work-flows.  I hope to add the flexibility to use various work-flows to
fit the job at hand.

[ stuff deleted ]
    $ git checkout master
    $ hack hack hack
    # Hmph, it almost works, and but my boss says work on
    # some other feature that is more urgent
    $ git commit -m 'WIP - fix frotz'
    $ git branch anchor-frotz
    $ git reset --hard master^
    $ work work work
    $ git commit -m 'Boring but urgent fix'
    # Ok, now let's go back to the thing I wanted to do.
    $ git pull . anchor-frotz
    $ rm .git/heads/anchor-frotz
    $ git reset --soft master^
    $ hack more
    $ git commit -m 'Finally fix frotz.'
Again, these are effective.  I simply want to provide an alternative
light weight way of accomplishing this.
The above flow would be something somebody not so organized
(like myself) would do.  A perfect person would have done this:

    $ git checkout -b frotz master
    $ hack hack hack
    # Hmph, it almost works, and but my boss says work on
    # some other feature that is more urgent
    $ git commit -m 'WIP - fix frotz'
    $ git checkout master
    $ work work work
    $ git commit -m 'Boring but urgent fix'
    # Ok, now let's go back to the thing I wanted to do.
    $ git checkout frotz
    $ git reset --soft HEAD^
    $ hack more
    $ git commit -m 'Finally fix frotz.'
    $ git checkout master
    $ git pull . frotz
    $ rm .git/refs/heads/frotz

The "perfect person" approach has an added benefit that you
could have made intermediate commits while doing "hacking",
because your hackery is always done in the "frotz" branch.

Of course, the scenarios your undo/redo is useful for may not be
limited to this "handling interrupt" use case.  If that is the
only thing it solves, then I do not see much point having them
as new commands.  I think the undo/redo has potential beyond
that.
What other potential do you see?  I sounds like you had a stream of
thought here that didn't make it in the email.  I think there are
probably many ways that it can be useful.  I'll ask some of my
colleagues here who have liked undo/redo type functionality what they
think.

I think it would be impossible to think of all of the possibilities
ahead of time.  But, if you've thought of some, please share :-)
So let's first clarify what kind of workflow these new commands
would help, how well that workflow is applicable in general, and
then how well these new commands would help that workflow.
quoted
I would be glad to write up documentation and provide a patch.
Sure.  I think a set of patches for new commands, and new
options to existing commands should ideally include the
following:

 - Justification, such as:

   - The problems new commands/options address.
   - The expected workflow the new commands/options fit in.
   - How useful that workflow is.
   - How impossible or cumbersome to achieve that workflow using
     existing tools.

   Some of these should go to the commit log message, and the
   documentation to describe the "best practice" workflow using
   the new feature should go to Documentation/howto/ directory.

 - Documentation.  Files Documentation/git-*.txt to describe
   new commands or updates to existing pages, new entry in
   Documentation/Makefile as necessary, and a new link from
   Documentation/git.txt to reach that page.

 - Implementation.

 - Test scripts in t/ directory, either a new test script or
   updates to existing ones, if the patch is to fix existing
   implementation.
This all sounds reasonable.  I'm willing to do this work.

Cheers,
Carl

-- 
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 Carl Baldwin                        Systems VLSI Laboratory
 Hewlett Packard Company
 MS 88                               work: 970 898-1523
 3404 E. Harmony Rd.                 work: Carl.N.Baldwin@hp.com
 Fort Collins, CO 80525              home: Carl@ecBaldwin.net
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Re: [RFC] undo and redo

From: Kirby C. Bohling <hidden>
Date: 2016-06-15 22:42:04

On Thu, Aug 25, 2005 at 10:32:01AM -0600, Carl Baldwin wrote:
<snip...>
Another example is if I'm working on a commit and suddenly get a
brilliant idea for some easy modification that I want to make and commit
by itself before making this commit.  I can do this easily with

        % git undo
        % carefully make easy change
        % git commit
        % git redo

Having a light-weight alternative like this could make the difference
between realizing the easy, brilliant idea and forgetting about it on
the back burner because it was just too cumbersome to make the context
switch.

The bottom line is that I don't argue against using the existing
work-flows.  I hope to add the flexibility to use various work-flows to
fit the job at hand.
<snip...>

[Not much of a git user, but am evaluating it for possible future
usage]... 

Why not just save the changes to a file via a patch.  Just like you
would if you were sending a patch to someone else.  I have the work
flow you are talking about when I use CVS.  I just create a patch,
apply the patch in reverse (or run the command to get you a clean
working tree in the SCM).  Make my unrelated changes commit it.
Then apply the patch, possibly resolve merge conflicts,  and proceed
with finishing my original work.

Assuming your patch creation and application tools capture all the
meta-data the SCM has (which I believe git does), it's pretty simple
to simulate what you want manaully.  With only a handful of
commands.

I see the appeal of not having manually deal with the files, but
assuming you don't feel it's branch worthy, and you don't want to
have it be something someone else can access externally, it doesn't
seem like a feature I can't get almost as simply with existing git
commands.  

I guess my final question is what does undo/redo have over saving
stuff away in a patch assuming that the patch captures all of the
SCM meta-data (the add/move/remove file type commands).  If git
doesn't capture all the meta-data in a patch, it would seem better
to make it do that and get this as a side-affect.

    Thanks,
        Kirby

Re: [RFC] undo and redo

From: Junio C Hamano <hidden>
Date: 2016-06-15 22:42:04

"Kirby C. Bohling" [off-list ref] writes:
I guess my final question is what does undo/redo have over saving
stuff away in a patch assuming that the patch captures all of the
SCM meta-data (the add/move/remove file type commands).  If git
doesn't capture all the meta-data in a patch, it would seem better
to make it do that and get this as a side-affect.
One thing that Carl's undo saves that is not easily available in
the patch form is the "what is this patch based on" information.
If you had it, you could do a three-way merge instead of patch
application.

You were at A (time flows from left to right) when somebody
(maybe your bright idea) interrupted you.  You take a snapshot
of your tree state D as a pair <A, D>, and rewind the tree to
original commit A's state:

 -->A
     \
      D

Then you do the work that interrupted you, maybe making commits
B and then C:

 -->A-->B-->C
     \
      D

At this point, you would want to restart working on whatever you
were doing, which is the difference between A->D applied on top
of C.

You could keep that information as a patch between A->D and
apply it on top of C to get there, which is your approach if I
am reading you correctly.  Carl does a three-way merge between C
and D using A as the pivot point.

Re: [RFC] undo and redo

From: Carl Baldwin <hidden>
Date: 2016-06-15 22:42:04

On Thu, Aug 25, 2005 at 02:59:18PM -0500, Kirby C. Bohling wrote:
On Thu, Aug 25, 2005 at 10:32:01AM -0600, Carl Baldwin wrote:
<snip...>
quoted
Another example is if I'm working on a commit and suddenly get a
brilliant idea for some easy modification that I want to make and commit
by itself before making this commit.  I can do this easily with

        % git undo
        % carefully make easy change
        % git commit
        % git redo

Having a light-weight alternative like this could make the difference
between realizing the easy, brilliant idea and forgetting about it on
the back burner because it was just too cumbersome to make the context
switch.

The bottom line is that I don't argue against using the existing
work-flows.  I hope to add the flexibility to use various work-flows to
fit the job at hand.
<snip...>

[Not much of a git user, but am evaluating it for possible future
usage]... 

Why not just save the changes to a file via a patch.  Just like you
would if you were sending a patch to someone else.  I have the work
flow you are talking about when I use CVS.  I just create a patch,
apply the patch in reverse (or run the command to get you a clean
working tree in the SCM).  Make my unrelated changes commit it.
Then apply the patch, possibly resolve merge conflicts,  and proceed
with finishing my original work.
I used to do this with CVS too.  For you and me, people who are patch
savy veterans, this is great!  However, as easy as it is I knew very few
other developers who even thought about doing it.  In the real world,
many people see a huge difference between:

git diff-cache > $patchfile
cat $patchfile | patch -R -p1
do work
cat $patchfile | patch -p1

AND

git undo
do work
git redo

The first one simply never happens with most developers.  Most don't
really think of doing something outside the tool.  The second option
will likely get used.  Plus, I know at least one person here who is very
good with patches and working outside the tool and still would love to
have the second approach available.

Is there something wrong with having flexibility?  It seems most of the
criticism of this feature is that there is already a way to accomplish
what I want to do.  Tools that can't be used flexibly are not tools that
I like to use.  Heck, I'm on UNIX aren't I?

Oops, sorry for the rant.  I'm really not in a bad mood... really.  I
hope it didn't sound like that :-).  Oh, and I didn't mean to suggest
that git is not flexible in other regards.  I think its great!  Moving
along...
Assuming your patch creation and application tools capture all the
meta-data the SCM has (which I believe git does), it's pretty simple
to simulate what you want manaully.  With only a handful of
commands.
I can simulate git manually too with just a few more commands.  Where's
the cutoff?
I see the appeal of not having manually deal with the files, but
assuming you don't feel it's branch worthy, and you don't want to
have it be something someone else can access externally, it doesn't
seem like a feature I can't get almost as simply with existing git
commands.  
Not having to manually manage a set of patches may seem small but it
reduces a barrier that may otherwise be just high enough to hurt
productivity in certain situations.
I guess my final question is what does undo/redo have over saving
stuff away in a patch assuming that the patch captures all of the
SCM meta-data (the add/move/remove file type commands).  If git
doesn't capture all the meta-data in a patch, it would seem better
to make it do that and get this as a side-affect.

    Thanks,
        Kirby
Thanks for your comments.

Carl

-- 
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 Carl Baldwin                        Systems VLSI Laboratory
 Hewlett Packard Company
 MS 88                               work: 970 898-1523
 3404 E. Harmony Rd.                 work: Carl.N.Baldwin@hp.com
 Fort Collins, CO 80525              home: Carl@ecBaldwin.net
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Re: [RFC] undo and redo

From: Kirby C. Bohling <hidden>
Date: 2016-06-15 22:42:04

On Thu, Aug 25, 2005 at 01:19:05PM -0700, Junio C Hamano wrote:
"Kirby C. Bohling" [off-list ref] writes:
quoted
I guess my final question is what does undo/redo have over saving
stuff away in a patch assuming that the patch captures all of the
SCM meta-data (the add/move/remove file type commands).  If git
doesn't capture all the meta-data in a patch, it would seem better
to make it do that and get this as a side-affect.
One thing that Carl's undo saves that is not easily available in
the patch form is the "what is this patch based on" information.
If you had it, you could do a three-way merge instead of patch
application.
You were at A (time flows from left to right) when somebody
(maybe your bright idea) interrupted you.  You take a snapshot
of your tree state D as a pair <A, D>, and rewind the tree to
original commit A's state:

 -->A
     \
      D

Then you do the work that interrupted you, maybe making commits
B and then C:

 -->A-->B-->C
     \
      D

At this point, you would want to restart working on whatever you
were doing, which is the difference between A->D applied on top
of C.

You could keep that information as a patch between A->D and
apply it on top of C to get there, which is your approach if I
am reading you correctly.  Carl does a three-way merge between C
and D using A as the pivot point.
    Just out of curiosity, why isn't the SHA1 of 'A' part of the
diff or patch format?  I mean it can't be that hard to add it as a
single line of data that git can parse to extract that piece of
information.  Then a patch would enable you to do the 3-way merge
you describe.  If added properly "regular" patch would just ignore
that line.  The patch would then record that it is relative to 'A'.

    Assuming git could be taught "git-merge-patch" and then take use
the patch that's saved during the "undo" step and has the anchor for
the patch to use as the pivot point (as described above).  Life
should be good.  There are probably corner cases I don't understand,
but it sure looks like if you have the pivot or anchor point for the
patch embedded in the patch, you have all the needed information to
pull this off.

    I would think this would be generally useful outside of the
context of "undo/redo" also.

    Kirby

Re: [RFC] undo and redo

From: Kirby C. Bohling <hidden>
Date: 2016-06-15 22:42:04

On Thu, Aug 25, 2005 at 02:37:33PM -0600, Carl Baldwin wrote:
On Thu, Aug 25, 2005 at 02:59:18PM -0500, Kirby C. Bohling wrote:
quoted
On Thu, Aug 25, 2005 at 10:32:01AM -0600, Carl Baldwin wrote:
<snip...>
quoted
Another example is if I'm working on a commit and suddenly get a
brilliant idea for some easy modification that I want to make and commit
by itself before making this commit.  I can do this easily with

        % git undo
        % carefully make easy change
        % git commit
        % git redo

Having a light-weight alternative like this could make the difference
between realizing the easy, brilliant idea and forgetting about it on
the back burner because it was just too cumbersome to make the context
switch.

The bottom line is that I don't argue against using the existing
work-flows.  I hope to add the flexibility to use various work-flows to
fit the job at hand.
<snip...>

[Not much of a git user, but am evaluating it for possible future
usage]... 

Why not just save the changes to a file via a patch.  Just like you
would if you were sending a patch to someone else.  I have the work
flow you are talking about when I use CVS.  I just create a patch,
apply the patch in reverse (or run the command to get you a clean
working tree in the SCM).  Make my unrelated changes commit it.
Then apply the patch, possibly resolve merge conflicts,  and proceed
with finishing my original work.
I used to do this with CVS too.  For you and me, people who are patch
savy veterans, this is great!  However, as easy as it is I knew very few
other developers who even thought about doing it.  In the real world,
many people see a huge difference between:

git diff-cache > $patchfile
cat $patchfile | patch -R -p1
do work
cat $patchfile | patch -p1

AND

git undo
do work
git redo

The first one simply never happens with most developers.  Most don't
really think of doing something outside the tool.  The second option
will likely get used.  Plus, I know at least one person here who is very
good with patches and working outside the tool and still would love to
have the second approach available.
I guess I can see that.  I just see it as much easier to manage
multiple undo-redo states manually.  I mean, I wouldn't make anyone
use git directly if the difference between the two commands bothers
them.  git seems too low a level.  I would think one of the
procelains would be be a better level.  However, having a unified
interface for all the porcelains seems a reasonable request.
Is there something wrong with having flexibility?  It seems most of the
criticism of this feature is that there is already a way to accomplish
what I want to do.  Tools that can't be used flexibly are not tools that
I like to use.  Heck, I'm on UNIX aren't I?

Oops, sorry for the rant.  I'm really not in a bad mood... really.  I
hope it didn't sound like that :-).  Oh, and I didn't mean to suggest
that git is not flexible in other regards.  I think its great!  Moving
along...
quoted
Assuming your patch creation and application tools capture all the
meta-data the SCM has (which I believe git does), it's pretty simple
to simulate what you want manaully.  With only a handful of
commands.
I can simulate git manually too with just a few more commands.  Where's
the cutoff?
Yes and no.  I meant the order and style of commands was nearly
identical.  I meant applying the command line in reverse was the
only additional step.  As a workflow, I'd just document it in the
HOWTO's.  I'm a minimalist in that sense.  Sure, I use more then
echo, redirection and netcat even though in theory I could send you
this e-mail with it.  IMHO, the above undo/redo doesn't seem to save
enough effort to me.  I wouldn't bother learning undo/redo unless it
was superior to the patch way, it's just one more thing I'd have to
remember.
quoted
I see the appeal of not having manually deal with the files, but
assuming you don't feel it's branch worthy, and you don't want to
have it be something someone else can access externally, it doesn't
seem like a feature I can't get almost as simply with existing git
commands.  
Not having to manually manage a set of patches may seem small but it
reduces a barrier that may otherwise be just high enough to hurt
productivity in certain situations.
I don't mean to discourge it's implementation, I really questioned
it because I figured there had to be some more subtle implications I
didn't understand about undo/redo that patch couldn't capture.  It
also seems like multiple levels of undo/redo or undo/redo on
multiple branches could get tricky for the user to track and for git
to be able to display the information to the user sanely.

    Thanks,
        Kirby

Re: [RFC] undo and redo

From: Carl Baldwin <hidden>
Date: 2016-06-15 22:42:04

On Thu, Aug 25, 2005 at 03:49:30PM -0500, Kirby C. Bohling wrote:
On Thu, Aug 25, 2005 at 01:19:05PM -0700, Junio C Hamano wrote:
quoted
"Kirby C. Bohling" [off-list ref] writes:
    Just out of curiosity, why isn't the SHA1 of 'A' part of the
diff or patch format?  I mean it can't be that hard to add it as a
single line of data that git can parse to extract that piece of
information.  Then a patch would enable you to do the 3-way merge
you describe.  If added properly "regular" patch would just ignore
that line.  The patch would then record that it is relative to 'A'.
Not a bad idea.  It could be ignored in most cases and used when needed.

Carl
    Assuming git could be taught "git-merge-patch" and then take use
the patch that's saved during the "undo" step and has the anchor for
the patch to use as the pivot point (as described above).  Life
should be good.  There are probably corner cases I don't understand,
but it sure looks like if you have the pivot or anchor point for the
patch embedded in the patch, you have all the needed information to
pull this off.

    I would think this would be generally useful outside of the
context of "undo/redo" also.

    Kirby
-- 
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 Carl Baldwin                        Systems VLSI Laboratory
 Hewlett Packard Company
 MS 88                               work: 970 898-1523
 3404 E. Harmony Rd.                 work: Carl.N.Baldwin@hp.com
 Fort Collins, CO 80525              home: Carl@ecBaldwin.net
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Re: [RFC] undo and redo

From: Carl Baldwin <hidden>
Date: 2016-06-15 22:42:04

On Thu, Aug 25, 2005 at 04:09:29PM -0500, Kirby C. Bohling wrote:
I guess I can see that.  I just see it as much easier to manage
multiple undo-redo states manually.  I mean, I wouldn't make anyone
use git directly if the difference between the two commands bothers
them.  git seems too low a level.  I would think one of the
procelains would be be a better level.  However, having a unified
interface for all the porcelains seems a reasonable request.
Maybe Porcelain is the right place for it.  The question would be "Is it
important that porcelains handle undo/redo in a way that interoperates?"
quoted
Is there something wrong with having flexibility?  It seems most of the
criticism of this feature is that there is already a way to accomplish
what I want to do.  Tools that can't be used flexibly are not tools that
I like to use.  Heck, I'm on UNIX aren't I?

Oops, sorry for the rant.  I'm really not in a bad mood... really.  I
hope it didn't sound like that :-).  Oh, and I didn't mean to suggest
that git is not flexible in other regards.  I think its great!  Moving
along...
quoted
Assuming your patch creation and application tools capture all the
meta-data the SCM has (which I believe git does), it's pretty simple
to simulate what you want manaully.  With only a handful of
commands.
I can simulate git manually too with just a few more commands.  Where's
the cutoff?
This analogy *was* a bit extreme.

Cheers,
Carl

-- 
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 Carl Baldwin                        Systems VLSI Laboratory
 Hewlett Packard Company
 MS 88                               work: 970 898-1523
 3404 E. Harmony Rd.                 work: Carl.N.Baldwin@hp.com
 Fort Collins, CO 80525              home: Carl@ecBaldwin.net
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help