{"thread":{"id":"9728","subject":"[PATCH 2/2] filter-branch: introduce convenience function \"skip_commit\"","startedAt":"2007-08-31T19:06:27Z","lastAt":"2007-08-31T21:39:09Z","messageCount":5,"participants":["Johannes Schindelin","Karl Hasselström","Junio C Hamano"],"isPatch":true,"patchVersion":1,"patchTotal":2},"messages":[{"id":"52067","messageId":"Pine.LNX.4.64.0708312005420.28586@racer.site","threadId":"9728","inReplyTo":null,"subject":"[PATCH 2/2] filter-branch: introduce convenience function \"skip_commit\"","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2007-08-31T19:06:27Z","receivedAt":"2007-08-31T19:06:27Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"\nWith this function, a commit filter can leave out unwanted commits\n(such as temporary commits).  It does _not_ undo the changeset\ncorresponding to that commit, but it _skips_ the revision.  IOW\nits ancestors' tree objects remain the same.\n\nIf you like to commit early and often, but want to filter out all\nintermediate commits, marked by \"@@@\" in the commit message, you can\nnow do this with\n\n\tgit filter-branch --commit-filter '\n\t\tif git cat-file commit $GIT_COMMIT | grep '@@@' > /dev/null;\n\t\tthen\n\t\t\tskip_commit \"$@\";\n\t\telse\n\t\t\tgit commit-tree \"$@\";\n\t\tfi' newbranch\n\nSigned-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\n\n\tSame comment as for 1/2 applies here, too...\n\n Documentation/git-filter-branch.txt |   34 +++++++++++++++++++++++++++-------\n git-filter-branch.sh                |   14 ++++++++++++++\n t/t7003-filter-branch.sh            |    8 +-------\n 3 files changed, 42 insertions(+), 14 deletions(-)\n\ndiff --git a/Documentation/git-filter-branch.txt b/Documentation/git-filter-branch.txt\nindex 456d52b..29bb8ce 100644\n--- a/Documentation/git-filter-branch.txt\n+++ b/Documentation/git-filter-branch.txt\n@@ -112,6 +112,11 @@ OPTIONS\n As a special extension, the commit filter may emit multiple\n commit ids; in that case, ancestors of the original commit will\n have all of them as parents.\n++\n+You can use the 'map' convenience function in this filter, and other\n+convenience functions, too.  For example, calling 'skip_commit \"$@\"'\n+will leave out the current commit (but not its changes! If you want\n+that, use gitlink:git-rebase[1] instead).\n \n --tag-name-filter <command>::\n \tThis is the filter for rewriting tag names. When passed,\n@@ -209,24 +214,39 @@ To remove commits authored by \"Darl McBribe\" from the history:\n git filter-branch --commit-filter '\n \tif [ \"$GIT_AUTHOR_NAME\" = \"Darl McBribe\" ];\n \tthen\n-\t\tshift;\n-\t\twhile [ -n \"$1\" ];\n-\t\tdo\n-\t\t\tshift;\n-\t\t\techo \"$1\";\n-\t\t\tshift;\n-\t\tdone;\n+\t\tskip_commit \"$@\";\n \telse\n \t\tgit commit-tree \"$@\";\n \tfi' HEAD\n ------------------------------------------------------------------------------\n \n+Note that the changes introduced by the commits, and not reverted by\n+subsequent commits, will still be in the rewritten branch. If you want\n+to throw out _changes_ together with the commits, you should use the\n+interactive mode of gitlink:git-rebase[1].\n+\n+The function 'skip_commits' is defined as follows:\n+\n+--------------------------\n+skip_commit()\n+{\n+\tshift;\n+\twhile [ -n \"$1\" ];\n+\tdo\n+\t\tshift;\n+\t\tmap \"$1\";\n+\t\tshift;\n+\tdone;\n+}\n+--------------------------\n+\n The shift magic first throws away the tree id and then the -p\n parameters.  Note that this handles merges properly! In case Darl\n committed a merge between P1 and P2, it will be propagated properly\n and all children of the merge will become merge commits with P1,P2\n as their parents instead of the merge commit.\n \n+\n To restrict rewriting to only part of the history, specify a revision\n range in addition to the new branch name.  The new branch name will\n point to the top-most revision that a 'git rev-list' of this range\ndiff --git a/git-filter-branch.sh b/git-filter-branch.sh\nindex 3b041d8..a4b6577 100755\n--- a/git-filter-branch.sh\n+++ b/git-filter-branch.sh\n@@ -23,6 +23,20 @@ map()\n \tfi\n }\n \n+# if you run 'skip_commit \"$@\"' in a commit filter, it will print\n+# the (mapped) parents, effectively skipping the commit.\n+\n+skip_commit()\n+{\n+\tshift;\n+\twhile [ -n \"$1\" ];\n+\tdo\n+\t\tshift;\n+\t\tmap \"$1\";\n+\t\tshift;\n+\tdone;\n+}\n+\n # override die(): this version puts in an extra line break, so that\n # the progress is still visible\n \ndiff --git a/t/t7003-filter-branch.sh b/t/t7003-filter-branch.sh\nindex c79853d..e935b20 100755\n--- a/t/t7003-filter-branch.sh\n+++ b/t/t7003-filter-branch.sh\n@@ -138,13 +138,7 @@ test_expect_success \"remove a certain author's commits\" '\n \tgit-filter-branch -f --commit-filter \"\\\n \t\tif [ \\\"\\$GIT_AUTHOR_NAME\\\" = \\\"B V Uips\\\" ];\\\n \t\tthen\\\n-\t\t\tshift;\\\n-\t\t\twhile [ -n \\\"\\$1\\\" ];\\\n-\t\t\tdo\\\n-\t\t\t\tshift;\\\n-\t\t\t\techo \\\"\\$1\\\";\\\n-\t\t\t\tshift;\\\n-\t\t\tdone;\\\n+\t\t\tskip_commit \\\"\\$@\\\";\n \t\telse\\\n \t\t\tgit commit-tree \\\"\\$@\\\";\\\n \t\tfi\" removed-author &&\n-- \n1.5.3.rc7.18.gc9b59\n"},{"id":"52069","messageId":"20070831191921.GB2151@diana.vm.bytemark.co.uk","threadId":"9728","inReplyTo":"Pine.LNX.4.64.0708312005420.28586@racer.site","subject":"Re: [PATCH 2/2] filter-branch: introduce convenience function \"skip_commit\"","fromName":"Karl Hasselström","fromEmail":"kha@treskal.com","sentAt":"2007-08-31T19:19:21Z","receivedAt":"2007-08-31T19:19:21Z","isPatch":true,"sender":{"key":"kha@treskal.com","avatar":"https://gravatar.com/avatar/f0120c734b5279b345075a28521e1ac66acb20c9913ffe9bf6ae97e53f7f3f13?d=mp&s=160"},"body":"On 2007-08-31 20:06:27 +0100, Johannes Schindelin wrote:\n\n> It does _not_ undo the changeset corresponding to that commit, but\n> it _skips_ the revision. IOW its ancestors' tree objects remain the\n> same.\n\nWhile this is true too, I'm guessing you intended to say that its\n_descendants'_ tree objects remain the same. Right?\n\n-- \nKarl Hasselström, kha@treskal.com\n      www.treskal.com/kalle\n"},{"id":"52080","messageId":"Pine.LNX.4.64.0708312204490.28586@racer.site","threadId":"9728","inReplyTo":"20070831191921.GB2151@diana.vm.bytemark.co.uk","subject":"Re: [PATCH 2/2] filter-branch: introduce convenience function \"skip_commit\"","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2007-08-31T21:05:40Z","receivedAt":"2007-08-31T21:05:40Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\nOn Fri, 31 Aug 2007, Karl Hasselstr?m wrote:\n\n> On 2007-08-31 20:06:27 +0100, Johannes Schindelin wrote:\n> \n> > It does _not_ undo the changeset corresponding to that commit, but\n> > it _skips_ the revision. IOW its ancestors' tree objects remain the\n> > same.\n> \n> While this is true too, I'm guessing you intended to say that its\n> _descendants'_ tree objects remain the same. Right?\n\nRight.  So how about:\n\nIOW no tree objects are changed by this.\n\nHmm?\n\nCiao,\nDscho\n"},{"id":"52090","messageId":"7vzm07wftf.fsf@gitster.siamese.dyndns.org","threadId":"9728","inReplyTo":"Pine.LNX.4.64.0708312204490.28586@racer.site","subject":"Re: [PATCH 2/2] filter-branch: introduce convenience function \"skip_commit\"","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2007-08-31T21:32:28Z","receivedAt":"2007-08-31T21:32:28Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:\n\n> Hi,\n>\n> On Fri, 31 Aug 2007, Karl Hasselstr?m wrote:\n>\n>> On 2007-08-31 20:06:27 +0100, Johannes Schindelin wrote:\n>> \n>> > It does _not_ undo the changeset corresponding to that commit, but\n>> > it _skips_ the revision. IOW its ancestors' tree objects remain the\n>> > same.\n>> \n>> While this is true too, I'm guessing you intended to say that its\n>> _descendants'_ tree objects remain the same. Right?\n>\n> Right.  So how about:\n>\n> IOW no tree objects are changed by this.\n\nOk, will amend.\n"},{"id":"52093","messageId":"Pine.LNX.4.64.0708312238430.28586@racer.site","threadId":"9728","inReplyTo":"7vzm07wftf.fsf@gitster.siamese.dyndns.org","subject":"Re: [PATCH 2/2] filter-branch: introduce convenience function \"skip_commit\"","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2007-08-31T21:39:09Z","receivedAt":"2007-08-31T21:39:09Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\nOn Fri, 31 Aug 2007, Junio C Hamano wrote:\n\n> Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:\n> \n> > On Fri, 31 Aug 2007, Karl Hasselstr?m wrote:\n> >\n> >> On 2007-08-31 20:06:27 +0100, Johannes Schindelin wrote:\n> >> \n> >> > It does _not_ undo the changeset corresponding to that commit, but\n> >> > it _skips_ the revision. IOW its ancestors' tree objects remain the\n> >> > same.\n> >> \n> >> While this is true too, I'm guessing you intended to say that its\n> >> _descendants'_ tree objects remain the same. Right?\n> >\n> > Right.  So how about:\n> >\n> > IOW no tree objects are changed by this.\n> \n> Ok, will amend.\n\nThanks; this was the next mail I wanted to send ;-)\n\nCiao,\nDscho\n"}]}