{"thread":{"id":"43149","subject":"Re: [PATCH] rerere: record (or avoid misrecording) resolved, skipped or aborted rebase/am","startedAt":"2006-12-08T20:43:46Z","lastAt":"2006-12-09T20:08:49Z","messageCount":7,"participants":["Junio C Hamano","Eric Wong","Jakub Narebski"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"298568","messageId":"7v7ix2i0e5.fsf@assigned-by-dhcp.cox.net","threadId":"43149","inReplyTo":"11655749724034-git-send-email-normalperson@yhbt.net","subject":"Re: [PATCH 1/5] rerere: avoid misrecording on a skipped or aborted rebase/am","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2006-12-08T20:43:46Z","receivedAt":"2006-12-08T20:43:46Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Eric Wong <normalperson@yhbt.net> writes:\n\n> +if (@ARGV && $ARGV[0] eq 'clear') {\n> +\tfor my $path (keys %merge_rr) {\n> +\t\tmy $name = $merge_rr{$path};\n> +\t\tif (-d \"$rr_dir/$name\") {\n> +\t\t\trmtree([\"$rr_dir/$name\"]);\n> +\t\t}\n> +\t}\n> +\tunlink $merge_rr;\n> +\texit 0;\n> +}\n\nCome to think of it, I am not sure about this one.  Don't you\nneed to make sure that there is no existing resolution before\nremoving it?  In other words, shouldn't the removal be like this?\n\n\tif (-d \"$rr_dir/$name\" && ! -f \"$rr_dir/$name/postimage\") {\n\t\trmtree([\"$rr_dir/$name\"]);\n\t}\n\n"},{"id":"298204","messageId":"20061208212830.GB13944@localdomain","threadId":"43149","inReplyTo":"7v7ix2i0e5.fsf@assigned-by-dhcp.cox.net","subject":"Re: [PATCH 1/5] rerere: avoid misrecording on a skipped or aborted rebase/am","fromName":"Eric Wong","fromEmail":"normalperson@yhbt.net","sentAt":"2006-12-08T21:28:30Z","receivedAt":"2006-12-08T21:28:30Z","isPatch":true,"sender":{"key":"e@80x24.org","avatar":null},"body":"Junio C Hamano <junkio@cox.net> wrote:\n> Eric Wong <normalperson@yhbt.net> writes:\n> \n> > +if (@ARGV && $ARGV[0] eq 'clear') {\n> > +\tfor my $path (keys %merge_rr) {\n> > +\t\tmy $name = $merge_rr{$path};\n> > +\t\tif (-d \"$rr_dir/$name\") {\n> > +\t\t\trmtree([\"$rr_dir/$name\"]);\n> > +\t\t}\n> > +\t}\n> > +\tunlink $merge_rr;\n> > +\texit 0;\n> > +}\n> \n> Come to think of it, I am not sure about this one.  Don't you\n> need to make sure that there is no existing resolution before\n> removing it?  In other words, shouldn't the removal be like this?\n> \n> \tif (-d \"$rr_dir/$name\" && ! -f \"$rr_dir/$name/postimage\") {\n> \t\trmtree([\"$rr_dir/$name\"]);\n> \t}\n\nYes.  However, it seems unlikely, that MERGE_RR would point to something\nthat has a postimage.  I suppose that a machine could crash or a user\ncould've hit ^C at the correct millisecond that would cause rerere to\nnot update MERGE_RR correctly.\n\nUpdated patches on the way (leaving out the status updates).\n\n-- \n"},{"id":"296091","messageId":"11656133963055-git-send-email-normalperson@yhbt.net","threadId":"43149","inReplyTo":"20061208212830.GB13944@localdomain","subject":"[PATCH] rerere: add clear, diff, and status commands","fromName":"Eric Wong","fromEmail":"normalperson@yhbt.net","sentAt":"2006-12-08T21:29:55Z","receivedAt":"2006-12-08T21:29:55Z","isPatch":true,"sender":{"key":"e@80x24.org","avatar":null},"body":"git-am and git-rebase will be updated to use 'clear', and\ndiff/status can be used to aid the user in tracking progress in\nthe resolution process.\n\nSigned-off-by: Eric Wong <normalperson@yhbt.net>\n---\n Documentation/git-rerere.txt |   27 +++++++++++++++++++++++++--\n git-rerere.perl              |   25 +++++++++++++++++++++++++\n 2 files changed, 50 insertions(+), 2 deletions(-)\n\ndiff --git a/Documentation/git-rerere.txt b/Documentation/git-rerere.txt\nindex 8b6b651..22494b2 100644\n--- a/Documentation/git-rerere.txt\n+++ b/Documentation/git-rerere.txt\n@@ -7,8 +7,7 @@ git-rerere - Reuse recorded resolve\n \n SYNOPSIS\n --------\n-'git-rerere'\n-\n+'git-rerere' [clear|diff|status]\n \n DESCRIPTION\n -----------\n@@ -167,6 +166,30 @@ would conflict the same way the test merge you resolved earlier.\n `git-rerere` is run by `git rebase` to help you resolve this\n conflict.\n \n+COMMANDS\n+--------\n+\n+Normally, git-rerere is run without arguments or user-intervention.\n+However, it has several commands that allow it to interact with\n+its working state.\n+\n+'clear'::\n+\n+This resets the metadata used by rerere if a merge resolution is to be\n+is aborted.  Calling gitlink:git-am[1] --skip or gitlink:git-rebase[1]\n+[--skip|--abort] will automatcally invoke this command.\n+\n+'diff'::\n+\n+This displays diffs for the current state of the resolution.  It is\n+useful for tracking what has changed while the user is resolving\n+conflicts.  Additional arguments are passed directly to the system\n+diff(1) command installed in PATH.\n+\n+'status'::\n+\n+Like diff, but this only prints the filenames that will be tracked\n+for resolutions.\n \n Author\n ------\ndiff --git a/git-rerere.perl b/git-rerere.perl\nindex d3664ff..2703d01 100755\n--- a/git-rerere.perl\n+++ b/git-rerere.perl\n@@ -172,6 +172,31 @@ sub merge {\n -d \"$rr_dir\" || exit(0);\n \n read_rr();\n+\n+if (my $arg = shift @ARGV) {\n+\tif ($arg eq 'clear') {\n+\t\tfor my $path (keys %merge_rr) {\n+\t\t\tmy $name = $merge_rr{$path};\n+\t\t\tif (-d \"$rr_dir/$name\" && ! -f \"$rr_dir/$name/postimage\") {\n+\t\t\t\trmtree([\"$rr_dir/$name\"]);\n+\t\t\t}\n+\t\t}\n+\t\tunlink $merge_rr;\n+\t} elsif ($arg eq 'status') {\n+\t\tfor my $path (keys %merge_rr) {\n+\t\t\tprint $path, \"\\n\";\n+\t\t}\n+\t} elsif ($arg eq 'diff') {\n+\t\tfor my $path (keys %merge_rr) {\n+\t\t\tmy $name = $merge_rr{$path};\n+\t\t\tsystem(qw/diff/, @ARGV,\n+\t\t\t\t'-L', \"a/$path\", '-L', \"b/$path\",\n+\t\t\t\t\"$rr_dir/$name/preimage\", $path);\n+\t\t}\n+\t}\n+\texit 0;\n+}\n+\n my %conflict = map { $_ => 1 } find_conflict();\n \n # MERGE_RR records paths with conflicts immediately after merge\n-- \n1.4.4.2.g860f4\n"},{"id":"294699","messageId":"1165613397460-git-send-email-normalperson@yhbt.net","threadId":"43149","inReplyTo":"11656133963055-git-send-email-normalperson@yhbt.net","subject":"[PATCH] rerere: record (or avoid misrecording) resolved, skipped or aborted rebase/am","fromName":"Eric Wong","fromEmail":"normalperson@yhbt.net","sentAt":"2006-12-08T21:29:56Z","receivedAt":"2006-12-08T21:29:56Z","isPatch":true,"sender":{"key":"e@80x24.org","avatar":null},"body":"Data in rr-cache isn't valid after a patch application is\nskipped or and aborted, so our next commit could be misrecorded\nas a resolution of that skipped/failed commit, which is wrong.\n\ngit-am --skip, git-rebase --skip/--abort will automatically\ninvoke git-rerere clear to avoid this.\n\nAlso, since git-am --resolved indicates a resolution was\nsuccesful, remember to run git-rerere to record the resolution\n(and not surprise the user when the next commit is made).\n\nSigned-off-by: Eric Wong <normalperson@yhbt.net>\n---\n git-am.sh     |    8 ++++++++\n git-rebase.sh |    8 ++++++++\n 2 files changed, 16 insertions(+), 0 deletions(-)\n\ndiff --git a/git-am.sh b/git-am.sh\nindex afe322b..5df6787 100755\n--- a/git-am.sh\n+++ b/git-am.sh\n@@ -246,6 +246,10 @@ last=`cat \"$dotest/last\"`\n this=`cat \"$dotest/next\"`\n if test \"$skip\" = t\n then\n+\tif test -d \"$GIT_DIR/rr-cache\"\n+\tthen\n+\t\tgit-rerere clear\n+\tfi\n \tthis=`expr \"$this\" + 1`\n \tresume=\n fi\n@@ -408,6 +412,10 @@ do\n \t\t\tstop_here_user_resolve $this\n \t\tfi\n \t\tapply_status=0\n+\t\tif test -d \"$GIT_DIR/rr-cache\"\n+\t\tthen\n+\t\t\tgit rerere\n+\t\tfi\n \t\t;;\n \tesac\n \ndiff --git a/git-rebase.sh b/git-rebase.sh\nindex 25530df..2b4f347 100755\n--- a/git-rebase.sh\n+++ b/git-rebase.sh\n@@ -139,6 +139,10 @@ do\n \t--skip)\n \t\tif test -d \"$dotest\"\n \t\tthen\n+\t\t\tif test -d \"$GIT_DIR/rr-cache\"\n+\t\t\tthen\n+\t\t\t\tgit-rerere clear\n+\t\t\tfi\n \t\t\tprev_head=\"`cat $dotest/prev_head`\"\n \t\t\tend=\"`cat $dotest/end`\"\n \t\t\tmsgnum=\"`cat $dotest/msgnum`\"\n@@ -157,6 +161,10 @@ do\n \t\texit\n \t\t;;\n \t--abort)\n+\t\tif test -d \"$GIT_DIR/rr-cache\"\n+\t\tthen\n+\t\t\tgit-rerere clear\n+\t\tfi\n \t\tif test -d \"$dotest\"\n \t\tthen\n \t\t\trm -r \"$dotest\"\n-- \n1.4.4.2.g860f4\n"},{"id":"298026","messageId":"elcm6u$l8t$1@sea.gmane.org","threadId":"43149","inReplyTo":"1165613397460-git-send-email-normalperson@yhbt.net","subject":"Re: [PATCH] rerere: record (or avoid misrecording) resolved, skipped or aborted rebase/am","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2006-12-08T21:44:08Z","receivedAt":"2006-12-08T21:44:08Z","isPatch":true,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"Eric Wong wrote:\n\nJust one comment:\n\n> +       if test -d \"$GIT_DIR/rr-cache\"\n> +       then\n> +               git-rerere clear\n> +       fi\n>         this=`expr \"$this\" + 1`\n>         resume=\n>  fi\n> @@ -408,6 +412,10 @@ do\n>                         stop_here_user_resolve $this\n>                 fi\n>                 apply_status=0\n> +               if test -d \"$GIT_DIR/rr-cache\"\n> +               then\n> +                       git rerere\n> +               fi\n\nWhy do you use once \"git-rerere\", and another time \"git rerere\"?\nShouldn't scripts always use git-command form?\n-- \nJakub Narebski\nWarsaw, Poland\nShadeHawk on #git\n\n"},{"id":"297017","messageId":"20061208215021.GA28018@localdomain","threadId":"43149","inReplyTo":"elcm6u$l8t$1@sea.gmane.org","subject":"Re: [PATCH] rerere: record (or avoid misrecording) resolved, skipped or aborted rebase/am","fromName":"Eric Wong","fromEmail":"normalperson@yhbt.net","sentAt":"2006-12-08T21:50:21Z","receivedAt":"2006-12-08T21:50:21Z","isPatch":true,"sender":{"key":"e@80x24.org","avatar":null},"body":"Jakub Narebski <jnareb@gmail.com> wrote:\n> Eric Wong wrote:\n> \n> Just one comment:\n> \n> > +       if test -d \"$GIT_DIR/rr-cache\"\n> > +       then\n> > +               git-rerere clear\n> > +       fi\n> >         this=`expr \"$this\" + 1`\n> >         resume=\n> >  fi\n> > @@ -408,6 +412,10 @@ do\n> >                         stop_here_user_resolve $this\n> >                 fi\n> >                 apply_status=0\n> > +               if test -d \"$GIT_DIR/rr-cache\"\n> > +               then\n> > +                       git rerere\n> > +               fi\n> \n> Why do you use once \"git-rerere\", and another time \"git rerere\"?\n> Shouldn't scripts always use git-command form?\n\nYes.  Or at least I remember git-command form being preferred.\n\nI don't think I've been entirely consistent in the things I've\nwritten, and my shell history is just as inconsistent :x\n\n-- \n"},{"id":"293926","messageId":"7vbqmcbzn2.fsf@assigned-by-dhcp.cox.net","threadId":"43149","inReplyTo":"1165613397460-git-send-email-normalperson@yhbt.net","subject":"Re: [PATCH] rerere: record (or avoid misrecording) resolved, skipped or aborted rebase/am","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2006-12-09T20:08:49Z","receivedAt":"2006-12-09T20:08:49Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"I looked at your previous 5-patch series but will replace with\nthis updated 2-patch series.\n\nThe rerere command started its life as a mere helper for\nPorcelains, but with 'status' and 'diff', you are making it\nsomewhat Porcelain-ish.  I still have not decided myself, but I\nthink we probably would want to treat this as a Porcelain and\ngive a bit of usability to it, so what I've committed has two\nchanges from your version:\n\n (1) 'diff' without @ARGV defaults to '-u';\n (2) running rerere with unknown sub command die()s instead of\n     silently exiting with 0.\n\nThe difference between your previous 5-patch series and this\nround raises an interesting issue.\n\nYou used to have a safety valve in git-commit to prevent users\nfrom running it while rebase/am is in progress, which I imagine\nwould be a common mistake.\n\nThere are three commands in git suite that a user would use to\neventually make new commits, out of something other than what\nwas edited and prepared in the working tree, that can stop in\nthe middle.\n\n (1) git-am is used to make new commits from e-mailed patches,\n     and stops in the middle when a patch does not apply.\n     \"git-am --resolved/--skip\" are the ways to continue.\n\n (2) git-rebase is used to rewrite the history of a branch, and\n     stops in the middle when a patch does not apply or merge\n     conflicts.  \"git-rebase --continue/--skip/--abort\" are\n     possible exits [*1*].\n\n (3) git-pull/git-merge are used to make merge commits with\n     another branch, and stops in the middle when it conflicts.\n     Possible exits are \"git commit\" or \"git reset\".\n\nNow, I am not going to propose to fix this inconsistency and\nforbid use of \"git commit\" to resolve \"git-merge\" (instead, the\nuser would say \"git-merge --resolved/--abort\").  As the workflow\ngoes, these are very different operations and the user is often\nwell aware which workflow is in progress; having different\ncommands for different exit route is fine.\n\nBut in order to implement the safety valve like you did cleanly,\nwe should first have an enumeration of states (the above is a\nsubset --- there is the \"base state\" in which you are working\ntowards a commit based on HEAD, which is obviously concluded\nwith a \"git commit\", and \"bisect in progress\") and make it easy\nfor commands to communicate what state the working tree is in.\nThat would also help 'git-explain'.\n\n[Footnote]\n\n*1* Resuming rebase was much worse before Sean updated it with\ncommit 031321c6 to hide that it uses git-am as its backend,\nwhich is purely its implementation detail.\n"}]}