{"thread":{"id":"24599","subject":"[PATCH] git-subtree: Add prune mode","startedAt":"2010-08-01T09:25:56Z","lastAt":"2010-08-02T16:02:55Z","messageCount":4,"participants":["Santi Béjar","Avery Pennarun"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"146907","messageId":"1280654756-9039-1-git-send-email-santi@agolina.net","threadId":"24599","inReplyTo":null,"subject":"[PATCH] git-subtree: Add prune mode","fromName":"Santi Béjar","fromEmail":"santi@agolina.net","sentAt":"2010-08-01T09:25:56Z","receivedAt":"2010-08-01T09:25:56Z","isPatch":true,"sender":{"key":"santi@agolina.net","avatar":null},"body":"Add prune mode (flag --prune) with the following properties:\n\n* The history must be as clean as possible\n* The directory content must be equal to the external module,\n  at least when you add/update it[b]\n* The subproject should be able to switch back and forth between\n  different versions.\n\n[b] A consequence of this is that it loses all changes\n    made in the subtree. If they are important you have to extract\n    them, apply them and add the subproject back.\n\nAs all the history is lost and you never merge commits\n'split' is not necessary, but it is basically:\n\n$ git filter-branch --subdirectory-filter $prefix\n\nAnd normally you will just want to extract the changes with format-patch\nand apply them with:\n\ngit am -p2\n\nSigned-off-by: Santi Béjar <santi@agolina.net>\n---\nHi *,\n\n   here it is a the same patch I send some days before but with documentation.\n\nSanti\n\n git-subtree.sh  |   29 +++++++++++++++++++++++++++--\n git-subtree.txt |   21 ++++++++++++++++++++-\n 2 files changed, 47 insertions(+), 3 deletions(-)\n\ndiff --git a/git-subtree.sh b/git-subtree.sh\nindex 781eef3..766b68b 100755\n--- a/git-subtree.sh\n+++ b/git-subtree.sh\n@@ -27,6 +27,7 @@ onto=         try connecting new tree to an existing one\n rejoin        merge the new branch back into HEAD\n  options for 'add', 'merge', 'pull' and 'push'\n squash        merge subtree changes as a single commit\n+prune         prune history\n \"\n eval $(echo \"$OPTS_SPEC\" | git rev-parse --parseopt -- \"$@\" || echo exit $?)\n \n@@ -44,6 +45,7 @@ rejoin=\n ignore_joins=\n annotate=\n squash=\n+prune=\n message=\n \n debug()\n@@ -92,6 +94,8 @@ while [ $# -gt 0 ]; do\n \t\t--no-ignore-joins) ignore_joins= ;;\n \t\t--squash) squash=1 ;;\n \t\t--no-squash) squash= ;;\n+\t\t--prune) prune=1;;\n+\t\t--no-prune) prune=;;\n \t\t--) break ;;\n \t\t*) die \"Unexpected option: $opt\" ;;\n \tesac\n@@ -110,12 +114,16 @@ if [ -z \"$prefix\" ]; then\n fi\n \n case \"$command\" in\n-\tadd) [ -e \"$prefix\" ] && \n+\tadd) [ -e \"$prefix\" -a -z \"$prune\" ] &&\n \t\tdie \"prefix '$prefix' already exists.\" ;;\n \t*)   [ -e \"$prefix\" ] || \n \t\tdie \"'$prefix' does not exist; use 'git subtree add'\" ;;\n esac\n \n+if [ -n \"$squash\" -a -n \"$prune\" ] ; then\n+\tdie \"Flags --prune and --squash are incompatible\"\n+fi\n+\n dir=\"$(dirname \"$prefix/.\")\"\n \n if [ \"$command\" != \"pull\" -a \"$command\" != \"add\" -a \"$command\" != \"push\" ]; then\n@@ -359,6 +367,17 @@ squash_msg()\n \techo \"git-subtree-split: $newsub\"\n }\n \n+prune_msg()\n+{\n+\tdir=\"$1\"\n+\tnewsub=\"$2\"\n+\t\n+\tgit show -s --pretty=\"tformat:Subtree '$dir/': %h %s\" $newsub\n+\techo\n+\techo \"git-subtree-dir: $dir\"\n+\techo \"git-subtree-split: $newsub\"\n+}\n+\n toptree_for_commit()\n {\n \tcommit=\"$1\"\n@@ -464,7 +483,7 @@ ensure_clean()\n \n cmd_add()\n {\n-\tif [ -e \"$dir\" ]; then\n+\tif [ -e \"$dir\" -a -z \"$prune\" ]; then\n \t\tdie \"'$dir' already exists.  Cannot add.\"\n \tfi\n \n@@ -498,6 +517,9 @@ cmd_add_commit()\n \trev=\"$1\"\n \t\n \tdebug \"Adding $dir as '$rev'...\"\n+\tif [ -d \"$dir\" ]; then\n+\t    git rm -r -q $dir\n+\tfi\n \tgit read-tree --prefix=\"$dir\" $rev || exit $?\n \tgit checkout -- \"$dir\" || exit $?\n \ttree=$(git write-tree) || exit $?\n@@ -513,6 +535,9 @@ cmd_add_commit()\n \t\trev=$(new_squash_commit \"\" \"\" \"$rev\") || exit $?\n \t\tcommit=$(add_squashed_msg \"$rev\" \"$dir\" |\n \t\t\t git commit-tree $tree $headp -p \"$rev\") || exit $?\n+\telif [ -n \"$prune\" ]; then\n+\t\tcommit=$(prune_msg \"$dir\" \"$rev\" |\n+\t\t\t git commit-tree $tree -p $headrev) || exit $?\n \telse\n \t\tcommit=$(add_msg \"$dir\" \"$headrev\" \"$rev\" |\n \t\t\t git commit-tree $tree $headp -p \"$rev\") || exit $?\ndiff --git a/git-subtree.txt b/git-subtree.txt\nindex dbcba31..5a91147 100644\n--- a/git-subtree.txt\n+++ b/git-subtree.txt\n@@ -66,7 +66,8 @@ add::\n \tA new commit is created\tautomatically, joining the imported\n \tproject's history with your own.  With '--squash', imports\n \tonly a single commit from the subproject, rather than its\n-\tentire history.\n+\tentire history. With '--prune', imports only the contents of\n+\tthe commit from the subproject without any history.\n \n merge::\n \tMerge recent changes up to <commit> into the <prefix>\n@@ -165,6 +166,24 @@ OPTIONS FOR add, merge, AND pull\n \tlocal repository remain intact and can be later split\n \tand send upstream to the subproject.\n \n+--prune::\n+\tInstead of merging the history (full or squashed) from the\n+\tsubtree project, produce only a single commit that\n+\treproduce the exact content in the preffix as in the\n+\tsubtree.\n+\n+\tIt has similar features as the --squash option, namely\n+\treduces the clutter (althougth --prune reduce it even\n+\tmore), helps avoiding problems when the same subproject is\n+\tinclude multiple time and can switch back and forth\n+\tbetween different version of a subtree.\n+\n+\tThe main difference is that with --prune the content of\n+\tthe prefix always matches the content of the subproject,\n+\twhile with --squash it merges you changes with the changes\n+\tfrom the subtree. If you want to keep your changes you\n+\thave to extract them, apply them in the external\n+\trepository and add the subproject back.\n \n OPTIONS FOR split\n -----------------\n-- \n1.7.1.765.gb5868\n"},{"id":"146920","messageId":"AANLkTinLuMwGw_0gXDBBdgT=eg2T_eqtRCNHh2PgV-7U@mail.gmail.com","threadId":"24599","inReplyTo":"1280654756-9039-1-git-send-email-santi@agolina.net","subject":"Re: [PATCH] git-subtree: Add prune mode","fromName":"Avery Pennarun","fromEmail":"apenwarr@gmail.com","sentAt":"2010-08-02T02:54:25Z","receivedAt":"2010-08-02T02:54:25Z","isPatch":true,"sender":{"key":"apenwarr@gmail.com","avatar":"https://avatars.githubusercontent.com/u/20592?v=4"},"body":"On Sun, Aug 1, 2010 at 5:25 AM, Santi Béjar <santi@agolina.net> wrote:\n> Add prune mode (flag --prune) with the following properties:\n>\n> * The history must be as clean as possible\n> * The directory content must be equal to the external module,\n>  at least when you add/update it[b]\n> * The subproject should be able to switch back and forth between\n>  different versions.\n>\n> [b] A consequence of this is that it loses all changes\n>    made in the subtree. If they are important you have to extract\n>    them, apply them and add the subproject back.\n\nI think I started to reply to this before but I can't quite remember\nwhat happened.  Anyway, I have several concerns with this patch:\n\n- calling it \"prune\" is pretty incorrect.  It doesn't remove anything\nfrom your history.  It silently loses patches from your tree, but\nthat's not \"pruning\" really.  I suggest \"--squash\n--discard-local-changes\" or something.  ie. it's a variant of squash,\nand it throws things away.  We want both of those to be clear.\n\n- I'm not convinced this concept is even a good idea.  Who on earth\nwants to silently lose changes?  Default --squash behaviour is to\nmerge the old branch with the new branch.  If you want to throw stuff\naway, that should probably be an entirely separate operation from the\nmerging.  ie. \"git subtree discard-local-changes --prefix=whatever\" to\ncreate a new patch that undoes all the local changes to this branch;\nthen \"git subtree merge --squash\" to update to a different upstream.\n\n- In what sense is the history from this any \"cleaner\" (or any\ndifferent) from --squash?  It seems like, in fact, the history will be\na *lie* since it talks about merging but actually reverts changes.\n\n> As all the history is lost and you never merge commits\n> 'split' is not necessary, but it is basically:\n>\n> $ git filter-branch --subdirectory-filter $prefix\n\nAre you saying that 'git subtree split' doesn't work after the\ndiscard-local-changes operation?  If so, we should fix that, I think.\nOtherwise it's very confusing.\n\n> +prune_msg()\n> +{\n> +       dir=\"$1\"\n> +       newsub=\"$2\"\n> +\n> +       git show -s --pretty=\"tformat:Subtree '$dir/': %h %s\" $newsub\n> +       echo\n> +       echo \"git-subtree-dir: $dir\"\n> +       echo \"git-subtree-split: $newsub\"\n> +}\n> +\n\nHmm.  I'm rather concerned about this one.  What's the top line of the\ncommit message?  add_msg, add_squashed_msg, rejoin_msg, and squash_msg\nare all much clearer than this.  It also seems that it doesn't honour\nthe -m flag here.\n\n>  cmd_add()\n>  {\n> -       if [ -e \"$dir\" ]; then\n> +       if [ -e \"$dir\" -a -z \"$prune\" ]; then\n>                die \"'$dir' already exists.  Cannot add.\"\n>        fi\n\nThis is the 'add' command.  I'm not sure it should have special\nbehaviour with prune.\n\n(Arguably 'add' should let you optionally overwrite an existing\ndirectory if it already exists.  But if so, I don't think this should\nonly happen with --prune; it should probably be a special --overwrite\nor --force option.)\n\n>        debug \"Adding $dir as '$rev'...\"\n> +       if [ -d \"$dir\" ]; then\n> +           git rm -r -q $dir\n> +       fi\n>        git read-tree --prefix=\"$dir\" $rev || exit $?\n\nIsn't there some plumbing command we can use instead of 'git rm'?  I\ndon't really know what.  Does anyone have any suggestions?\n\n>        A new commit is created automatically, joining the imported\n>        project's history with your own.  With '--squash', imports\n>        only a single commit from the subproject, rather than its\n> -       entire history.\n> +       entire history. With '--prune', imports only the contents of\n> +       the commit from the subproject without any history.\n\nThis is unclear.  \"Without any history\" isn't really accurate, since a\nnew commit message is generated; actually the history importing is\nprecisely the same as what happens with --squash.\n\n> +--prune::\n> +       Instead of merging the history (full or squashed) from the\n> +       subtree project, produce only a single commit that\n> +       reproduce the exact content in the preffix as in the\n> +       subtree.\n\ns/preffix/prefix/\n\n> +       It has similar features as the --squash option, namely\n> +       reduces the clutter (althougth --prune reduce it even\n> +       more), helps avoiding problems when the same subproject is\n> +       include multiple time and can switch back and forth\n> +       between different version of a subtree.\n\ns/althougth/although/\ns/include multiple/included multiple/\n\nI don't understand how --prune supposedly \"reduces it even more\" than\n--squash.  What clutter?  How does it reduce it *more*?  How does it\navoid problems when the same subproject is included multiple times?\nWhat problems are those?\n\nYou can switch back and forth between different versions of a subtree,\nbut this is true of --squash as well - that's why I think this\noperation should be a subcommand of --squash instead.\n\n> +       The main difference is that with --prune the content of\n> +       the prefix always matches the content of the subproject,\n> +       while with --squash it merges you changes with the changes\n> +       from the subtree. If you want to keep your changes you\n> +       have to extract them, apply them in the external\n> +       repository and add the subproject back.\n\ns/you changes/your changes/\n\nThis last part is especially strange: if you want to keep your own\nchanges, why do you want to use --prune at all?  --squash does that\nautomatically.\n\nHave fun,\n\nAvery\n"},{"id":"146936","messageId":"AANLkTi=U2=ZYXnxW3GVteB9GtxFP41GRzcTejzLE2S8w@mail.gmail.com","threadId":"24599","inReplyTo":"AANLkTinLuMwGw_0gXDBBdgT=eg2T_eqtRCNHh2PgV-7U@mail.gmail.com","subject":"Re: [PATCH] git-subtree: Add prune mode","fromName":"Santi Béjar","fromEmail":"santi@agolina.net","sentAt":"2010-08-02T10:41:03Z","receivedAt":"2010-08-02T10:41:03Z","isPatch":true,"sender":{"key":"santi@agolina.net","avatar":null},"body":"On Mon, Aug 2, 2010 at 4:54 AM, Avery Pennarun <apenwarr@gmail.com> wrote:\n> On Sun, Aug 1, 2010 at 5:25 AM, Santi Béjar <santi@agolina.net> wrote:\n>> Add prune mode (flag --prune) with the following properties:\n>>\n>> * The history must be as clean as possible\n>> * The directory content must be equal to the external module,\n>>  at least when you add/update it[b]\n>> * The subproject should be able to switch back and forth between\n>>  different versions.\n>>\n>> [b] A consequence of this is that it loses all changes\n>>    made in the subtree. If they are important you have to extract\n>>    them, apply them and add the subproject back.\n>\n> I think I started to reply to this before but I can't quite remember\n> what happened.  Anyway, I have several concerns with this patch:\n>\n> - calling it \"prune\" is pretty incorrect.  It doesn't remove anything\n> from your history.\n\nIt removes the history of the subproject.\nAnd --squash does not squash your history. We are talking about the\nsubproject, not the superproject.\n\n>  It silently loses patches from your tree, but\n> that's not \"pruning\" really.  I suggest \"--squash\n> --discard-local-changes\" or something.  ie. it's a variant of squash,\n> and it throws things away.  We want both of those to be clear.\n\nIt's not a variant of squash, it is completely different, but it\nshares some properties. One tries to keep your local changes, the\nother no.\n\n>\n> - I'm not convinced this concept is even a good idea.  Who on earth\n> wants to silently lose changes?\n\nI want. I very much prefer do all the changes upstream than in the\nsubproject. I never modify the subtree, so it is not a issue for me,\nbut I really prefer to know that every time I add the subproject I get\nexactly the content as the other project.\n\n> Default --squash behaviour is to\n> merge the old branch with the new branch.  If you want to throw stuff\n> away, that should probably be an entirely separate operation from the\n> merging.  ie. \"git subtree discard-local-changes --prefix=whatever\" to\n> create a new patch that undoes all the local changes to this branch;\n> then \"git subtree merge --squash\" to update to a different upstream.\n\nMaybe it is not clear from the docs/code, but with --prune you always\nhave to \"git subtree add\", so it is pretty clear that you discard all\nthe local changes.\n\nI should add a check that --prune is only compatible with \"git subtree add\".\n\n> - In what sense is the history from this any \"cleaner\" (or any\n> different) from --squash?\n\nWith git-subtree you always have the subtree history (even if it is\nsquashed). So when you merge a second time the submodule you get the always\nthe history of the subtree (even with --squash). So you basically always have\nat least two branches while examining the history. Compare this\nsquashed history:\n\n$ git log --graph --oneline\n*   bb2dc25 (HEAD, master) Merge commit\n'08b917ee90ecfd7b666364fe4ebb92aee5cdd2f7'\n|\\\n| * 08b917e Squashed 'latex/' changes from ea35faf..895916a\n* |   9de91f1 Merge commit 'b1b4c36bb8358582a6a20bb500bf98421428e2ca' as 'latex'\n|\\|\n| * b1b4c36 Squashed 'latex/' content from commit ea35faf\n* ea35faf Indent, whitespaces,...\n\nwith this pruned history:\n\n$ git log --graph --oneline\n* 8703aec (HEAD, master) Subtree 'latex/': 895916a Add files subcommand\n* a942284 Subtree 'latex/': ea35faf Indent, whitespaces,...\n* ea35faf Indent, whitespaces,...\n\n>  It seems like, in fact, the history will be\n> a *lie* since it talks about merging but actually reverts changes.\n\nThere is *no* merging with --prune, you get a new commit with a single\nparent that changes the contents of the subtree in such a way that\nreproduce the contents of the subproject.\n\n>> As all the history is lost and you never merge commits\n>> 'split' is not necessary, but it is basically:\n>>\n>> $ git filter-branch --subdirectory-filter $prefix\n>\n> Are you saying that 'git subtree split' doesn't work after the\n> discard-local-changes operation?  If so, we should fix that, I think.\n> Otherwise it's very confusing.\n\nI tried but did not succeed.\n\nBut what I was trying to say is that I don´t see the necessity of it,\nas you never merge the subproject (with history).\n\n>\n>> +prune_msg()\n>> +{\n>> +       dir=\"$1\"\n>> +       newsub=\"$2\"\n>> +\n>> +       git show -s --pretty=\"tformat:Subtree '$dir/': %h %s\" $newsub\n>> +       echo\n>> +       echo \"git-subtree-dir: $dir\"\n>> +       echo \"git-subtree-split: $newsub\"\n>> +}\n>> +\n>\n> Hmm.  I'm rather concerned about this one.  What's the top line of the\n> commit message?  add_msg, add_squashed_msg, rejoin_msg, and squash_msg\n> are all much clearer than this.\n\nI see it is very different from all the others. It is:\n\nSubtree '$dir/': $hash $subject\n\nI´ll change it to match what add_msg does:\n\nAdd '$dir/' from commit '$latest_new'\n\n\n>  It also seems that it doesn't honour\n> the -m flag here.\n\nI´ll fix it. I took squash_msg as model...\n\n>\n>>  cmd_add()\n>>  {\n>> -       if [ -e \"$dir\" ]; then\n>> +       if [ -e \"$dir\" -a -z \"$prune\" ]; then\n>>                die \"'$dir' already exists.  Cannot add.\"\n>>        fi\n>\n> This is the 'add' command.  I'm not sure it should have special\n> behaviour with prune.\n\nWith prune mode you don´t merge new commits but add them.\n\n>\n> (Arguably 'add' should let you optionally overwrite an existing\n> directory if it already exists.  But if so, I don't think this should\n> only happen with --prune; it should probably be a special --overwrite\n> or --force option.)\n\nThis is sensible, and prune mode should use it when available.\n\n>\n>>        debug \"Adding $dir as '$rev'...\"\n>> +       if [ -d \"$dir\" ]; then\n>> +           git rm -r -q $dir\n>> +       fi\n>>        git read-tree --prefix=\"$dir\" $rev || exit $?\n>\n> Isn't there some plumbing command we can use instead of 'git rm'?  I\n> don't really know what.  Does anyone have any suggestions?\n\nI tried it, but I didn´t found a command to remove from the index and\nthe working dir at the same time.\n\nAnd I found \"git checkout --\" used after the \"git read-tree\".\n\n>\n>>        A new commit is created automatically, joining the imported\n>>        project's history with your own.  With '--squash', imports\n>>        only a single commit from the subproject, rather than its\n>> -       entire history.\n>> +       entire history. With '--prune', imports only the contents of\n>> +       the commit from the subproject without any history.\n>\n> This is unclear.  \"Without any history\" isn't really accurate, since a\n> new commit message is generated; actually the history importing is\n> precisely the same as what happens with --squash.\n\nNo, with --squash you always have a side branch with the history of\nthe subtree as viewed from the superproject.\n\nWith --prune the only history you get is a new commit in the superproject.\n\nSee above for a \"git log --graph\" example of each.\n\nWould it be clearer if \"without any history\" is gone?\n\n>\n>> +--prune::\n>> +       Instead of merging the history (full or squashed) from the\n>> +       subtree project, produce only a single commit that\n>> +       reproduce the exact content in the preffix as in the\n>> +       subtree.\n>\n> s/preffix/prefix/\n\nOK\n\n>\n>> +       It has similar features as the --squash option, namely\n>> +       reduces the clutter (althougth --prune reduce it even\n>> +       more), helps avoiding problems when the same subproject is\n>> +       include multiple time and can switch back and forth\n>> +       between different version of a subtree.\n>\n> s/althougth/although/\n> s/include multiple/included multiple/\n>\n\nOK.\n\n> I don't understand how --prune supposedly \"reduces it even more\" than\n> --squash.  What clutter?  How does it reduce it *more*?\n\nSee above for a \"git log --graph\" example.\n\n>  How does it\n> avoid problems when the same subproject is included multiple times?\n\nYou just add/have the content in different subdirectories. You don´t\nhave problems with the history/merging/... because it does keep the\nhistory, does not merge,...\n\n> What problems are those?\n\nI suppose it is about history and merging, the same problems with\nplain \"git subtree\" without --squash.\n\n>\n> You can switch back and forth between different versions of a subtree,\n> but this is true of --squash as well - that's why I think this\n> operation should be a subcommand of --squash instead.\n\nThe fact that it shares some properties with --squash does not make it\na subcommand of it. But you cannot merge, you don´t have a side branch\nwith the subproject \"history\",...\n\n>\n>> +       The main difference is that with --prune the content of\n>> +       the prefix always matches the content of the subproject,\n>> +       while with --squash it merges you changes with the changes\n>> +       from the subtree. If you want to keep your changes you\n>> +       have to extract them, apply them in the external\n>> +       repository and add the subproject back.\n>\n> s/you changes/your changes/\n>\n> This last part is especially strange: if you want to keep your own\n> changes, why do you want to use --prune at all?  --squash does that\n> automatically.\n\nIf you want to keep your own changes you better upstream them, like\nyou would do with \"git submodules\".\n\nIf the changes are upstream, all the superprojects using the subtree\nwill benefit from it.\n\nI try to \"push\" everything (changes, merging,whatever) upstream (or a\nforked upstream).\n\nHave fun,\nSanti\n"},{"id":"146951","messageId":"AANLkTinR1OSt-3O4FQ8QBMm60LFZ_jU8u6mzenZdCDTd@mail.gmail.com","threadId":"24599","inReplyTo":"AANLkTi=U2=ZYXnxW3GVteB9GtxFP41GRzcTejzLE2S8w@mail.gmail.com","subject":"Re: [PATCH] git-subtree: Add prune mode","fromName":"Santi Béjar","fromEmail":"santi@agolina.net","sentAt":"2010-08-02T16:02:55Z","receivedAt":"2010-08-02T16:02:55Z","isPatch":true,"sender":{"key":"santi@agolina.net","avatar":null},"body":"On Mon, Aug 2, 2010 at 12:41 PM, Santi Béjar <santi@agolina.net> wrote:\n> On Mon, Aug 2, 2010 at 4:54 AM, Avery Pennarun <apenwarr@gmail.com> wrote:\n>> On Sun, Aug 1, 2010 at 5:25 AM, Santi Béjar <santi@agolina.net> wrote:\n>>> Add prune mode (flag --prune) with the following properties:\n>>>\n>>> * The history must be as clean as possible\n>>> * The directory content must be equal to the external module,\n>>>  at least when you add/update it[b]\n>>> * The subproject should be able to switch back and forth between\n>>>  different versions.\n>>>\n>>> [b] A consequence of this is that it loses all changes\n>>>    made in the subtree. If they are important you have to extract\n>>>    them, apply them and add the subproject back.\n>>\n>> I think I started to reply to this before but I can't quite remember\n>> what happened.  Anyway, I have several concerns with this patch:\n>>\n>> - calling it \"prune\" is pretty incorrect.  It doesn't remove anything\n>> from your history.\n>\n> It removes the history of the subproject.\n> And --squash does not squash your history. We are talking about the\n> subproject, not the superproject.\n>\n>>  It silently loses patches from your tree, but\n>> that's not \"pruning\" really.  I suggest \"--squash\n>> --discard-local-changes\" or something.  ie. it's a variant of squash,\n>> and it throws things away.  We want both of those to be clear.\n>\n> It's not a variant of squash, it is completely different, but it\n> shares some properties. One tries to keep your local changes, the\n> other no.\n\nI just wanted to add one thing. For me \"--squash\n--discard-local-changes\" would be something like --squash but with\n\"git merge -s theirs\", so totally different from the --prune mode. I\ncannot be a flag to --squash.\n\nI'm open to discuss the name of the flag, but for now I found --prune\nthe best one. And as it is only used with \"git subtree add\" I don't\nthink it should be about \"discard local changes\".\n\nHave fun,\nSanti\n"}]}