{"thread":{"id":"22010","subject":"[PATCH RFC 0/4] rebase -i: Add --refs option to rewrite heads within branch","startedAt":"2009-12-22T22:20:33Z","lastAt":"2009-12-23T18:11:57Z","messageCount":11,"participants":["Greg Price","Junio C Hamano","Michael J Gruber","Johannes Schindelin"],"isPatch":true,"patchVersion":1,"patchTotal":4},"messages":[{"id":"130260","messageId":"20091222222032.GU30538@dr-wily.mit.edu","threadId":"22010","inReplyTo":null,"subject":"[PATCH RFC 0/4] rebase -i: Add --refs option to rewrite heads within branch","fromName":"Greg Price","fromEmail":"price@ksplice.com","sentAt":"2009-12-22T22:20:33Z","receivedAt":"2009-12-22T22:20:33Z","isPatch":true,"sender":{"key":"price@mit.edu","avatar":"https://avatars.githubusercontent.com/u/28173?v=4"},"body":"This RFC series adds a \"ref\" command to rebase -i, and an option\n--refs to generate \"ref\" commands in the original TODO file.  This\nmakes it easy to rebase a branch together with intermediate markers,\nor a series of branches.\n\nFor example, in this situation:\n\n      part1 part2 topic\n        |     |     |\n        v     v     v\n  A--*--*--*--*--*--*\n   \\\n    B <--master\n\nwe may want to rebase 'topic' onto the new master, rewriting the\nintermediate branches 'part1', 'part2' to the corresponding new\ncommits.  This can be done with a sequence of \"git rebase --onto\"\ncommands, but it's tricky to get right.\n\nWith this series, the command\n  $ git rebase -i --refs master topic\nsuffices to produce this result:\n\n        part1 part2 topic\n  A       |     |     |\n   \\      v     v     v\n    B--*--*--*--*--*--*\n    ^\n    |\n    master\n\n\nThese patches work for me.  Before I recommend the last two patches\nfor merge, they'll need the following additional work:\n - interoperate with rebase --abort\n - add documentation\n - probably add tests\n\n\nThe series begins with two patches that are independently useful, and\nthat I believe are ready for merge:\n  pretty: Add %D for script-friendly decoration\n  log --decorate=full: drop the \"tag: \" prefix\nThey make the functionality of 'git log --decorate' available in an\noutput format optimized for machine parsing.  I expect other people\nwill find this useful for other scripts.\n\nGreg\n"},{"id":"130261","messageId":"20091222222217.GV30538@dr-wily.mit.edu","threadId":"22010","inReplyTo":"20091222222032.GU30538@dr-wily.mit.edu","subject":"[PATCH 1/4] pretty: Add %D for script-friendly decoration","fromName":"Greg Price","fromEmail":"price@ksplice.com","sentAt":"2009-12-22T22:22:18Z","receivedAt":"2009-12-22T22:22:18Z","isPatch":true,"sender":{"key":"price@mit.edu","avatar":"https://avatars.githubusercontent.com/u/28173?v=4"},"body":"When in a script or porcelain one wants to identify what refs point to\nwhich commits in a series, the functionality of 'git log --decorate'\nis extremely useful.  This is available with the %d format code in a\nform optimized for humans, but for scripts a more raw format is better.\nMake such a format available through a new format code %D.\n\nSigned-off-by: Greg Price <price@ksplice.com>\n---\n Documentation/pretty-formats.txt |    1 +\n pretty.c                         |   33 +++++++++++++++++++++++++--------\n 2 files changed, 26 insertions(+), 8 deletions(-)\n\ndiff --git a/Documentation/pretty-formats.txt b/Documentation/pretty-formats.txt\nindex 53a9168..b6b840e 100644\n--- a/Documentation/pretty-formats.txt\n+++ b/Documentation/pretty-formats.txt\n@@ -119,6 +119,7 @@ The placeholders are:\n - '%ct': committer date, UNIX timestamp\n - '%ci': committer date, ISO 8601 format\n - '%d': ref names, like the --decorate option of linkgit:git-log[1]\n+- '%D': full ref names, like the --decorate=full option of linkgit:git-log[1]\n - '%e': encoding\n - '%s': subject\n - '%f': sanitized subject line, suitable for a filename\ndiff --git a/pretty.c b/pretty.c\nindex 8f5bd1a..18ce2ff 100644\n--- a/pretty.c\n+++ b/pretty.c\n@@ -582,21 +582,35 @@ static void parse_commit_message(struct format_commit_context *c)\n \tc->commit_message_parsed = 1;\n }\n \n-static void format_decoration(struct strbuf *sb, const struct commit *commit)\n+\n+static void format_decoration(struct strbuf *sb, const struct commit *commit,\n+\t\t\t      int decoration_style, const char *affixes[3])\n {\n \tstruct name_decoration *d;\n-\tconst char *prefix = \" (\";\n+\tconst char *affix = affixes[0];\n \n-\tload_ref_decorations(DECORATE_SHORT_REFS);\n+\tload_ref_decorations(decoration_style);\n \td = lookup_decoration(&name_decoration, &commit->object);\n \twhile (d) {\n-\t\tstrbuf_addstr(sb, prefix);\n-\t\tprefix = \", \";\n+\t\tstrbuf_addstr(sb, affix);\n+\t\taffix = affixes[1];\n \t\tstrbuf_addstr(sb, d->name);\n \t\td = d->next;\n \t}\n-\tif (prefix[0] == ',')\n-\t\tstrbuf_addch(sb, ')');\n+\tif (affix == affixes[1])\n+\t\tstrbuf_addstr(sb, affixes[2]);\n+}\n+\n+static void format_decoration_short(struct strbuf *sb, const struct commit *commit)\n+{\n+\tconst char *affixes[3] = {\" (\", \", \", \")\"};\n+\tformat_decoration(sb, commit, DECORATE_SHORT_REFS, affixes);\n+}\n+\n+static void format_decoration_full(struct strbuf *sb, const struct commit *commit)\n+{\n+\tconst char *affixes[3] = {\"\", \" \", \"\"};\n+\tformat_decoration(sb, commit, DECORATE_FULL_REFS, affixes);\n }\n \n static void strbuf_wrap(struct strbuf *sb, size_t pos,\n@@ -756,7 +770,10 @@ static size_t format_commit_one(struct strbuf *sb, const char *placeholder,\n \t\t                 : '>');\n \t\treturn 1;\n \tcase 'd':\n-\t\tformat_decoration(sb, commit);\n+\t\tformat_decoration_short(sb, commit);\n+\t\treturn 1;\n+\tcase 'D':\n+\t\tformat_decoration_full(sb, commit);\n \t\treturn 1;\n \tcase 'g':\t\t/* reflog info */\n \t\tswitch(placeholder[1]) {\n-- \n1.6.6.rc1.9.g2ad41.dirty\n"},{"id":"130262","messageId":"20091222222238.GW30538@dr-wily.mit.edu","threadId":"22010","inReplyTo":"20091222222032.GU30538@dr-wily.mit.edu","subject":"[PATCH 2/4] log --decorate=full: drop the \"tag: \" prefix","fromName":"Greg Price","fromEmail":"price@ksplice.com","sentAt":"2009-12-22T22:22:38Z","receivedAt":"2009-12-22T22:22:38Z","isPatch":true,"sender":{"key":"price@mit.edu","avatar":"https://avatars.githubusercontent.com/u/28173?v=4"},"body":"The \"tag: \" prefix complicates machine parsing of decorations, so we\ndrop it from the output formats intended to be parsed by machine,\nnamely --decorate=full and the %D format code.\n\nThe prefix is helpful for a human reader to see that the ref is an\n(annotated) tag, especially since we omit the \"refs/tags/\" prefix in\nthe default output of \"git log --decorate\".  In a script, however, it\nis easy to use \"git cat-file -t\" to distinguish annotated tags from\ncommits when the distinction is relevant.\n\nSigned-off-by: Greg Price <price@ksplice.com>\n---\n log-tree.c |    5 +++--\n 1 files changed, 3 insertions(+), 2 deletions(-)\n\ndiff --git a/log-tree.c b/log-tree.c\nindex 0fdf159..5eb6b00 100644\n--- a/log-tree.c\n+++ b/log-tree.c\n@@ -22,17 +22,18 @@ static void add_name_decoration(const char *prefix, const char *name, struct obj\n \n static int add_ref_decoration(const char *refname, const unsigned char *sha1, int flags, void *cb_data)\n {\n+\tint short_refs = !!(!cb_data || *(int *)cb_data == DECORATE_SHORT_REFS);\n \tstruct object *obj = parse_object(sha1);\n \tif (!obj)\n \t\treturn 0;\n-\tif (!cb_data || *(int *)cb_data == DECORATE_SHORT_REFS)\n+\tif (short_refs)\n \t\trefname = prettify_refname(refname);\n \tadd_name_decoration(\"\", refname, obj);\n \twhile (obj->type == OBJ_TAG) {\n \t\tobj = ((struct tag *)obj)->tagged;\n \t\tif (!obj)\n \t\t\tbreak;\n-\t\tadd_name_decoration(\"tag: \", refname, obj);\n+\t\tadd_name_decoration(short_refs ? \"tag: \" : \"\", refname, obj);\n \t}\n \treturn 0;\n }\n-- \n1.6.6.rc1.9.g2ad41.dirty\n"},{"id":"130263","messageId":"20091222222256.GX30538@dr-wily.mit.edu","threadId":"22010","inReplyTo":"20091222222032.GU30538@dr-wily.mit.edu","subject":"[PATCH RFC 3/4] rebase -i: Add the \"ref\" command","fromName":"Greg Price","fromEmail":"price@ksplice.com","sentAt":"2009-12-22T22:22:56Z","receivedAt":"2009-12-22T22:22:56Z","isPatch":true,"sender":{"key":"price@mit.edu","avatar":"https://avatars.githubusercontent.com/u/28173?v=4"},"body":"This is useful for, e.g., rewriting a branch that has ancestor\nbranches along the way.\n\nSigned-off-by: Greg Price <price@ksplice.com>\n---\n git-rebase--interactive.sh |    4 ++++\n 1 files changed, 4 insertions(+), 0 deletions(-)\n\ndiff --git a/git-rebase--interactive.sh b/git-rebase--interactive.sh\nindex 0bd3bf7..25ac3e3 100755\n--- a/git-rebase--interactive.sh\n+++ b/git-rebase--interactive.sh\n@@ -367,6 +367,10 @@ do_next () {\n \t\twarn\n \t\texit 0\n \t\t;;\n+\tref)\n+\t\tmark_action_done\n+\t\tgit update-ref $sha1 HEAD # $sha1 is actually a refname\n+\t\t;;\n \tsquash|s)\n \t\tcomment_for_reflog squash\n \n-- \n1.6.6.rc1.9.g2ad41.dirty\n"},{"id":"130264","messageId":"20091222222316.GY30538@dr-wily.mit.edu","threadId":"22010","inReplyTo":"20091222222032.GU30538@dr-wily.mit.edu","subject":"[PATCH RFC 4/4] rebase -i: add --refs option to rewrite heads within branch","fromName":"Greg Price","fromEmail":"price@ksplice.com","sentAt":"2009-12-22T22:23:16Z","receivedAt":"2009-12-22T22:23:16Z","isPatch":true,"sender":{"key":"price@mit.edu","avatar":"https://avatars.githubusercontent.com/u/28173?v=4"},"body":"The new option --refs causes the TODO file to contain a \"ref\" command\nfor each head pointing to a selected commit, other than the one we are\nalready rebasing.  The effect of this is that when a branch contains\nintermediate branches, like so:\n\n      part1 part2 topic\n        |     |     |\n        v     v     v\n  A--*--*--*--*--*--*\n   \\\n    B <--master\n\na single command like \"git rebase -i --refs master topic\" suffices to\nrewrite all the heads that are part of the topic, like so:\n\n        part1 part2 topic\n  A       |     |     |\n   \\      v     v     v\n    B--*--*--*--*--*--*\n    ^\n    |\n    master\n\nSigned-off-by: Greg Price <price@ksplice.com>\n---\n git-rebase--interactive.sh |   22 ++++++++++++++++++++--\n 1 files changed, 20 insertions(+), 2 deletions(-)\n\ndiff --git a/git-rebase--interactive.sh b/git-rebase--interactive.sh\nindex 25ac3e3..cccb031 100755\n--- a/git-rebase--interactive.sh\n+++ b/git-rebase--interactive.sh\n@@ -18,6 +18,7 @@ git-rebase [-i] (--continue | --abort | --skip)\n  Available options are\n v,verbose          display a diffstat of what changed upstream\n onto=              rebase onto given branch instead of upstream\n+refs               rewrite intermediate heads on branch\n p,preserve-merges  try to recreate merges instead of ignoring them\n s,strategy=        use the given merge strategy\n m,merge            always used (no-op)\n@@ -42,6 +43,7 @@ REWRITTEN=\"$DOTEST\"/rewritten\n DROPPED=\"$DOTEST\"/dropped\n PRESERVE_MERGES=\n STRATEGY=\n+REWRITE_REFS=\n ONTO=\n VERBOSE=\n OK_TO_SKIP_PRE_REBASE=\n@@ -578,6 +580,9 @@ first and then run 'git rebase --continue' again.\"\n \n \t\toutput git reset --hard && do_rest\n \t\t;;\n+\t--refs)\n+\t\tREWRITE_REFS=t\n+\t\t;;\n \t-s)\n \t\tcase \"$#,$1\" in\n \t\t*,*=*)\n@@ -705,11 +710,14 @@ first and then run 'git rebase --continue' again.\"\n \t\t\tREVISIONS=$ONTO...$HEAD\n \t\t\tSHORTREVISIONS=$SHORTHEAD\n \t\tfi\n-\t\tgit rev-list $MERGES_OPTION --pretty=oneline --abbrev-commit \\\n-\t\t\t--abbrev=7 --reverse --left-right --topo-order \\\n+\t\tgit rev-list $MERGES_OPTION --abbrev-commit --abbrev=7 \\\n+\t\t\t--reverse --left-right --topo-order \\\n+\t\t\t--pretty=format:\"$(printf '%%m%%h %%s\\n%%m%%D')\" \\\n \t\t\t$REVISIONS | \\\n \t\t\tsed -n \"s/^>//p\" | while read shortsha1 rest\n \t\tdo\n+\t\t\tread refs\n+\n \t\t\tif test t != \"$PRESERVE_MERGES\"\n \t\t\tthen\n \t\t\t\techo \"pick $shortsha1 $rest\" >> \"$TODO\"\n@@ -734,6 +742,16 @@ first and then run 'git rebase --continue' again.\"\n \t\t\t\t\techo \"pick $shortsha1 $rest\" >> \"$TODO\"\n \t\t\t\tfi\n \t\t\tfi\n+\n+\t\t\tif test t = \"$REWRITE_REFS\"\n+\t\t\tthen\n+\t\t\t\tfor ref in $refs\n+\t\t\t\tdo\n+\t\t\t\t\ttest ${ref#refs/heads/} != $ref &&\n+\t\t\t\t\ttest $ref != $(cat \"$DOTEST\"/head-name) &&\n+\t\t\t\t\techo \"ref $ref\" >> \"$TODO\"\n+\t\t\t\tdone\n+\t\t\tfi\n \t\tdone\n \n \t\t# Watch for commits that been dropped by --cherry-pick\n-- \n1.6.6.rc1.9.g2ad41.dirty\n"},{"id":"130265","messageId":"7vzl5awpf1.fsf@alter.siamese.dyndns.org","threadId":"22010","inReplyTo":"20091222222316.GY30538@dr-wily.mit.edu","subject":"Re: [PATCH RFC 4/4] rebase -i: add --refs option to rewrite heads within branch","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2009-12-22T23:37:54Z","receivedAt":"2009-12-22T23:37:54Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Greg Price <price@ksplice.com> writes:\n\n> The new option --refs causes the TODO file to contain a \"ref\" command\n> for each head pointing to a selected commit, other than the one we are\n> already rebasing.  The effect of this is that when a branch contains\n> intermediate branches, like so:\n>\n>       part1 part2 topic\n>         |     |     |\n>         v     v     v\n>   A--*--*--*--*--*--*\n>    \\\n>     B <--master\n>\n> a single command like \"git rebase -i --refs master topic\" suffices to\n> rewrite all the heads that are part of the topic, like so:\n>\n>         part1 part2 topic\n>   A       |     |     |\n>    \\      v     v     v\n>     B--*--*--*--*--*--*\n>     ^\n>     |\n>     master\n>\n> Signed-off-by: Greg Price <price@ksplice.com>\n> ---\n\nTwo comments and a half.\n\n - As decoration is a fairly expensive operation (which is the reason why\n   loading_ref_decorations() is called lazily by format_decoration() in\n   the first place, especially in repositories with tons of refs), you\n   shouldn't give --format=%D to rev-list when the new feature is not\n   asked for.\n\n - This seems to rewrite only branch heads; don't you want to allow users\n   to rewrite lightweight tags and possibly annotated ones as well, by\n   perhaps giving \"--rewrite-refs=refs/heads/\" or \"--rewrite-refs=refs/\"\n   to limit what parts of the ref namespace to consider rewriting?\n\n - Otherwise the option should not be called \"refs\" but be named using the\n   word \"branch\" to clarify that it affects _only_ branches.\n\nObviously the series also needs tests.\n\nI also have to wonder if this feature should also handle a case like this:\n\n                  side\n                  |\n                  V\n                  *\n                 /\n        part1   *    topic\n          |    /      |\n          v   /       v\n    A--*--*--*--*--*--*\n     \\\n      B <--master\n\n===>\n\n                     side\n                     |\n                     V\n                     *\n                    /\n           part1   *    topic\n     A       |    /      |\n      \\      v   /       v\n       B--*--*--*--*--*--*\n       ^\n       |\n       master\n\nespecially if it were to be specific to branch management.\n\nOn the other hand, if the \"partN\" markers in your example workflow are\nprimarily meant to be used to mark places on a branch (as opposed to\narbitrary branch tips that independent development starting from them can\nfurther continue), it would make a lot more sense to use lightweight or\nannotated tags for them, and instead of \"--refs\" that rewrites only other\nbranch tips, it might make a lot more sense to have \"--rewrite-tags\" that\nrewrites tags that point at the commits that are rewritten, without\ntouching any branch tip.\n"},{"id":"130274","messageId":"1ac2d430912222303k6180baa6j291bb4d18c7a4968@mail.gmail.com","threadId":"22010","inReplyTo":"7vzl5awpf1.fsf@alter.siamese.dyndns.org","subject":"Re: [PATCH RFC 4/4] rebase -i: add --refs option to rewrite heads within branch","fromName":"Greg Price","fromEmail":"price@ksplice.com","sentAt":"2009-12-23T07:03:03Z","receivedAt":"2009-12-23T07:03:03Z","isPatch":true,"sender":{"key":"price@mit.edu","avatar":"https://avatars.githubusercontent.com/u/28173?v=4"},"body":"On Tue, Dec 22, 2009 at 6:37 PM, Junio C Hamano <gitster@pobox.com> wrote:\n>  - As decoration is a fairly expensive operation (which is the reason why\n>   loading_ref_decorations() is called lazily by format_decoration() in\n>   the first place, especially in repositories with tons of refs), you\n>   shouldn't give --format=%D to rev-list when the new feature is not\n>   asked for.\n\nOK, will do.\n\n\n>  - This seems to rewrite only branch heads; don't you want to allow users\n>   to rewrite lightweight tags and possibly annotated ones as well, by\n>   perhaps giving \"--rewrite-refs=refs/heads/\" or \"--rewrite-refs=refs/\"\n>   to limit what parts of the ref namespace to consider rewriting?\n\nSure.  I specifically left out tags because I generally think of a tag\nas something immutable that it would not make sense to rewrite.  But\npeople use Git in different ways and it makes sense to give the option\nof rewriting tags as well as heads.\n\nI do worry that passing --rewrite-refs=refs/ will set up remote refs\nfor rewriting, which is likely to be confusing if the user does not\nnotice them and remove them from the TODO.  Perhaps it makes sense to\naccept forms like \"--rewrite-refs=refs/heads/,refs/tags/\" or\n\"--rewrite-refs=refs/heads/ --rewrite-refs=refs/tags/\".  Is there a\nGit convention for accepting a sequence of arguments like this to an\noption -- one of these, or something else?\n\n\n> On the other hand, if the \"partN\" markers in your example workflow are\n> primarily meant to be used to mark places on a branch (as opposed to\n> arbitrary branch tips that independent development starting from them can\n> further continue), it would make a lot more sense to use lightweight or\n> annotated tags for them, and instead of \"--refs\" that rewrites only other\n> branch tips, it might make a lot more sense to have \"--rewrite-tags\" that\n> rewrites tags that point at the commits that are rewritten, without\n> touching any branch tip.\n\nI think of them as a topic branch developing one feature, then another\nbranch developing a related follow-on feature, etc.  I would also feel\nodd rewriting tags as a routine operation, or calling a ref a tag when\nI expect to rewrite it.  So I do think they're best recorded as branch\ntips rather than tags.\n\n\n> Obviously the series also needs tests.\n\nYes.\n\n\n> I also have to wonder if this feature should also handle a case like this:\n>\n>                  side\n>                  |\n>                  V\n>                  *\n>                 /\n>        part1   *    topic\n>          |    /      |\n>          v   /       v\n>    A--*--*--*--*--*--*\n>     \\\n>      B <--master\n>\n> ===>\n>\n>                     side\n>                     |\n>                     V\n>                     *\n>                    /\n>           part1   *    topic\n>     A       |    /      |\n>      \\      v   /       v\n>       B--*--*--*--*--*--*\n>       ^ [\n>       |\n>       master\n>\n> especially if it were to be specific to branch management.\n\nHuh, that's an interesting idea.  I hadn't thought of that.  This\nfeature could be nice.  But I am not sure what it would look like.\nHow might the user indicate that they want both \"side\" and \"topic\" to\nbe rebased?  I suppose we could extend the familiar command line\n   git rebase <upstream> [<branch>]\nto the form\n   git rebase <upstream> [...<branches>...]\nso that your example would be\n   $ git rebase -i --rewrite-heads master topic side\nIf we choose this approach, it might even be independent of\n--rewrite-refs, though the implementation would presumably rely on the\n\"ref\" command.  Was this interface what you were thinking, or do you\nhave another idea?\n\nGreg\n"},{"id":"130276","messageId":"4B31DA96.1050608@drmicha.warpmail.net","threadId":"22010","inReplyTo":"1ac2d430912222303k6180baa6j291bb4d18c7a4968@mail.gmail.com","subject":"Re: [PATCH RFC 4/4] rebase -i: add --refs option to rewrite heads within branch","fromName":"Michael J Gruber","fromEmail":"git@drmicha.warpmail.net","sentAt":"2009-12-23T08:53:42Z","receivedAt":"2009-12-23T08:53:42Z","isPatch":true,"sender":{"key":"git@grubix.eu","avatar":"https://avatars.githubusercontent.com/u/233215?v=4"},"body":"Greg Price venit, vidit, dixit 23.12.2009 08:03:\n> On Tue, Dec 22, 2009 at 6:37 PM, Junio C Hamano <gitster@pobox.com> wrote:\n>>  - As decoration is a fairly expensive operation (which is the reason why\n>>   loading_ref_decorations() is called lazily by format_decoration() in\n>>   the first place, especially in repositories with tons of refs), you\n>>   shouldn't give --format=%D to rev-list when the new feature is not\n>>   asked for.\n> \n> OK, will do.\n> \n> \n>>  - This seems to rewrite only branch heads; don't you want to allow users\n>>   to rewrite lightweight tags and possibly annotated ones as well, by\n>>   perhaps giving \"--rewrite-refs=refs/heads/\" or \"--rewrite-refs=refs/\"\n>>   to limit what parts of the ref namespace to consider rewriting?\n> \n> Sure.  I specifically left out tags because I generally think of a tag\n> as something immutable that it would not make sense to rewrite.  But\n> people use Git in different ways and it makes sense to give the option\n> of rewriting tags as well as heads.\n> \n> I do worry that passing --rewrite-refs=refs/ will set up remote refs\n> for rewriting, which is likely to be confusing if the user does not\n> notice them and remove them from the TODO.  Perhaps it makes sense to\n> accept forms like \"--rewrite-refs=refs/heads/,refs/tags/\" or\n> \"--rewrite-refs=refs/heads/ --rewrite-refs=refs/tags/\".  Is there a\n> Git convention for accepting a sequence of arguments like this to an\n> option -- one of these, or something else?\n> \n> \n>> On the other hand, if the \"partN\" markers in your example workflow are\n>> primarily meant to be used to mark places on a branch (as opposed to\n>> arbitrary branch tips that independent development starting from them can\n>> further continue), it would make a lot more sense to use lightweight or\n>> annotated tags for them, and instead of \"--refs\" that rewrites only other\n>> branch tips, it might make a lot more sense to have \"--rewrite-tags\" that\n>> rewrites tags that point at the commits that are rewritten, without\n>> touching any branch tip.\n> \n> I think of them as a topic branch developing one feature, then another\n> branch developing a related follow-on feature, etc.  I would also feel\n> odd rewriting tags as a routine operation, or calling a ref a tag when\n> I expect to rewrite it.  So I do think they're best recorded as branch\n> tips rather than tags.\n> \n> \n>> Obviously the series also needs tests.\n> \n> Yes.\n> \n> \n>> I also have to wonder if this feature should also handle a case like this:\n>>\n>>                  side\n>>                  |\n>>                  V\n>>                  *\n>>                 /\n>>        part1   *    topic\n>>          |    /      |\n>>          v   /       v\n>>    A--*--*--*--*--*--*\n>>     \\\n>>      B <--master\n>>\n>> ===>\n>>\n>>                     side\n>>                     |\n>>                     V\n>>                     *\n>>                    /\n>>           part1   *    topic\n>>     A       |    /      |\n>>      \\      v   /       v\n>>       B--*--*--*--*--*--*\n>>       ^ [\n>>       |\n>>       master\n>>\n>> especially if it were to be specific to branch management.\n> \n> Huh, that's an interesting idea.  I hadn't thought of that.  This\n> feature could be nice.  But I am not sure what it would look like.\n> How might the user indicate that they want both \"side\" and \"topic\" to\n> be rebased?  I suppose we could extend the familiar command line\n>    git rebase <upstream> [<branch>]\n> to the form\n>    git rebase <upstream> [...<branches>...]\n> so that your example would be\n>    $ git rebase -i --rewrite-heads master topic side\n> If we choose this approach, it might even be independent of\n> --rewrite-refs, though the implementation would presumably rely on the\n> \"ref\" command.  Was this interface what you were thinking, or do you\n> have another idea?\n> \n> Greg\n\nIf I may jump in: I imagine this to be the more common use case, i.e.:\nYou have a part of the DAG which you want to rebase, with all kinds of\nrefs (branches, tags) pointing to commits in that part of the DAG. If\nyou rebase that part of the DAG you typically want some refs rewritten\n(such as the head of the branch you're rebasing) but maybe not others\n(say a release tag or branch). remote refs should never be rebased. So,\none would need an easy way to specify one ref, all or anything in between...\n\nMichael\n"},{"id":"130279","messageId":"alpine.DEB.1.00.0912231425440.4985@pacific.mpi-cbg.de","threadId":"22010","inReplyTo":"1ac2d430912222303k6180baa6j291bb4d18c7a4968@mail.gmail.com","subject":"Re: [PATCH RFC 4/4] rebase -i: add --refs option to rewrite heads within branch","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2009-12-23T13:28:14Z","receivedAt":"2009-12-23T13:28:14Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\nOn Wed, 23 Dec 2009, Greg Price wrote:\n\n> On Tue, Dec 22, 2009 at 6:37 PM, Junio C Hamano <gitster@pobox.com> wrote:\n> \n> >  - This seems to rewrite only branch heads; don't you want to allow \n> > users  to rewrite lightweight tags and possibly annotated ones as \n> > well, by  perhaps giving \"--rewrite-refs=refs/heads/\" or \n> > \"--rewrite-refs=refs/\"  to limit what parts of the ref namespace to \n> > consider rewriting?\n> \n> Sure.  I specifically left out tags because I generally think of a tag \n> as something immutable that it would not make sense to rewrite.\n\nI do agree: if you plan to rewrite a ref, you _should_ make it a branch \nanyway.\n\nA tag is not meant to be updated easily, in fact, we explicitely lack \ntools to do so (and it is quite hard to get updated tags from a repository \nwhere the tags changed anyway).  So rewriting tags is something that \ncauses only trouble.\n\nWhy should rebase -i cause that trouble all of a sudden?\n\nCiao,\nDscho"},{"id":"130284","messageId":"1ac2d430912230934h600575e4h17e2ee84f53de1a0@mail.gmail.com","threadId":"22010","inReplyTo":"4B31DA96.1050608@drmicha.warpmail.net","subject":"Re: [PATCH RFC 4/4] rebase -i: add --refs option to rewrite heads within branch","fromName":"Greg Price","fromEmail":"price@ksplice.com","sentAt":"2009-12-23T17:34:29Z","receivedAt":"2009-12-23T17:34:29Z","isPatch":true,"sender":{"key":"price@mit.edu","avatar":"https://avatars.githubusercontent.com/u/28173?v=4"},"body":"On Wed, Dec 23, 2009 at 3:53 AM, Michael J Gruber\n<git@drmicha.warpmail.net> wrote:\n> If I may jump in: I imagine this to be the more common use case, i.e.:\n> You have a part of the DAG which you want to rebase, with all kinds of\n> refs (branches, tags) pointing to commits in that part of the DAG. If\n> you rebase that part of the DAG you typically want some refs rewritten\n> (such as the head of the branch you're rebasing) but maybe not others\n> (say a release tag or branch). remote refs should never be rebased. So,\n> one would need an easy way to specify one ref, all or anything in between...\n\nI see the interactive aspect as the backstop that gives the user total\nflexibility, whatever command-line interface we choose.  So, for\nexample, a user might find it easiest to pass --rewrite-heads so that\nall heads on the given part of the DAG are inserted as \"ref\" commands\nin the appropriate places, and then go through and remove from the\nTODO file any exceptions.\n\nBut I agree it is worth making convenient shortcuts by which the user\ncan specify their intention precisely on the command line itself.  And\nin any case, if we are to satisfy this latter use case we need a way\nof specifying a part of the DAG to rebase that is not only ancestors\nof a single commit.  What do you think of the\n\"--rewrite-refs=refs/heads/,refs/tags/\" and \"git rebase -i master\ntopic side\" proposals in my reply to Junio?\n\nGreg\n"},{"id":"130287","messageId":"7vpr65r24y.fsf@alter.siamese.dyndns.org","threadId":"22010","inReplyTo":"4B31DA96.1050608@drmicha.warpmail.net","subject":"Re: [PATCH RFC 4/4] rebase -i: add --refs option to rewrite heads within branch","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2009-12-23T18:11:57Z","receivedAt":"2009-12-23T18:11:57Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Michael J Gruber <git@drmicha.warpmail.net> writes:\n\n> Greg Price venit, vidit, dixit 23.12.2009 08:03:\n> ...\n>> Huh, that's an interesting idea.  I hadn't thought of that.  This\n>> feature could be nice.  But I am not sure what it would look like.\n>> How might the user indicate that they want both \"side\" and \"topic\" to\n>> be rebased?  I suppose we could extend the familiar command line\n>>    git rebase <upstream> [<branch>]\n>> to the form\n>>    git rebase <upstream> [...<branches>...]\n>> so that your example would be\n>>    $ git rebase -i --rewrite-heads master topic side\n>> If we choose this approach, it might even be independent of\n>> --rewrite-refs, though the implementation would presumably rely on the\n>> \"ref\" command.  Was this interface what you were thinking, or do you\n>> have another idea?\n>\n> If I may jump in: I imagine this to be the more common use case, i.e.:\n> You have a part of the DAG which you want to rebase, with all kinds of\n> refs (branches, tags) pointing to commits in that part of the DAG. If\n> you rebase that part of the DAG you typically want some refs rewritten\n> (such as the head of the branch you're rebasing) but maybe not others\n> (say a release tag or branch). remote refs should never be rebased. So,\n> one would need an easy way to specify one ref, all or anything in between...\n\nAnd warn (or perhaps reject without --force) if the sub-DAG you would\nrebase contains an already tagged commit, especially if you are treating\ntags as immutable, even the ones you haven't published.\n\nI actually don't think \"rebasing side branches while rebasing this branch\"\nwas such a good idea---we have filter-branch for that already ;-).\n"}]}