{"thread":{"id":"22551","subject":"Using ‘git replace’ to replace blobs","startedAt":"2010-02-07T01:10:56Z","lastAt":"2010-02-07T06:45:59Z","messageCount":2,"participants":["Jonathan Nieder","Christian Couder"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"133838","messageId":"20100207011056.GA15307@progeny.tock","threadId":"22551","inReplyTo":null,"subject":"Using ‘git replace’ to replace blobs","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2010-02-07T01:10:56Z","receivedAt":"2010-02-07T01:10:56Z","isPatch":false,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"I think it is a known problem that ‘git replace’ cannot be used safely\nto replace blobs used in the currently checked out commit.  The man\npage says:\n\n\tComparing blobs or trees that have been replaced with\n\tthose that replace them will not work properly.\n\nIndeed, in practice it produces problems. [1]\n\nI would like to start to fix this.  But the correct semantics are not\nobvious to me:\n\n - When writing a tree from an index that includes replaced blobs,\n   should the result use the original blobs or the replaced ones?\n\n - When reading a tree that includes replaced blobs, should the\n   resulting cache entries use the original blobs or the replaced\n   ones?\n\nMy hunch is to say both should use the replaced blobs.  This way,\nreplacing a blob in a checked-out index would behave in a more\nintuitive way, and git filter-branch would make permanent any\nsubstitutions requested through replaced blob entries.\n\nI have not thought it through completely, though.\n\nThoughts?\nJonathan\n\n[1] For example,\n\n git init repo\n cd repo\n echo first > 1.txt\n echo second > 2.txt\n git add 1.txt 2.txt\n git commit -m demonstration\n git show --raw\n git ls-tree HEAD | awk '\n\tNR == 1 { first = $3 }\n\tNR == 2 { system(\"git replace \" first \" \" $3) }\n '\n git status\n rm *\n git checkout -f\n git status\n\nwhich one would expect to result in a clean tree, produces\n\n Initialized empty Git repository in /tmp/repo/.git/\n [master (root-commit) 998cc27] demonstration\n  2 files changed, 2 insertions(+), 0 deletions(-)\n  create mode 100644 1.txt\n  create mode 100644 2.txt\n commit 998cc270986f68450f00bda5e5db62f31367ff96\n Author: Jonathan Nieder <jrnieder@gmail.com>\n Date:   Sat Feb 6 18:48:50 2010 -0600\n\n     demonstration\n\n :000000 100644 0000000... 9c59e24... A  1.txt\n :000000 100644 0000000... e019be0... A  2.txt\n # On branch master\n nothing to commit (working directory clean)\n # On branch master\n # Changed but not updated:\n #   (use \"git add <file>...\" to update what will be committed)\n #   (use \"git checkout -- <file>...\" to discard changes in working\n #   directory)\n #\n #       modified:   1.txt\n #\n no changes added to commit (use \"git add\" and/or \"git commit -a\")\n"},{"id":"133856","messageId":"201002070746.00200.chriscool@tuxfamily.org","threadId":"22551","inReplyTo":"20100207011056.GA15307@progeny.tock","subject":"Re: Using ‘git replace’ to replace blobs","fromName":"Christian Couder","fromEmail":"chriscool@tuxfamily.org","sentAt":"2010-02-07T06:45:59Z","receivedAt":"2010-02-07T06:45:59Z","isPatch":false,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"On dimanche 07 février 2010, Jonathan Nieder wrote:\n> I think it is a known problem that ‘git replace’ cannot be used safely\n> to replace blobs used in the currently checked out commit.  The man\n> page says:\n>\n> \tComparing blobs or trees that have been replaced with\n> \tthose that replace them will not work properly.\n>\n> Indeed, in practice it produces problems. [1]\n>\n> I would like to start to fix this.  \n\nOne way to fix it may be to use a bit in \"struct object\" that could tell if \nany object was replaced or not. I think that in the \"Add caching support to \ngit-daemon\" GSoc patches, Nick Edelen did something like that for grafts. \n(See http://thread.gmane.org/gmane.comp.version-control.git/127932/)\n\n> But the correct semantics are not \n> obvious to me:\n>\n>  - When writing a tree from an index that includes replaced blobs,\n>    should the result use the original blobs or the replaced ones?\n\nIt may depend on why the original blob was replaced in the first place.\nI did not think much about this though.\n\n>  - When reading a tree that includes replaced blobs, should the\n>    resulting cache entries use the original blobs or the replaced\n>    ones?\n\nI think it should depend on whether the global variable read_replace_refs is \nset or not.\n\n> My hunch is to say both should use the replaced blobs.  This way,\n> replacing a blob in a checked-out index would behave in a more\n> intuitive way, and git filter-branch would make permanent any\n> substitutions requested through replaced blob entries.\n\nIt might not always be a good idea to make any substitution permanent.\nFor example if you use git replace to improve the bisectability of your \ncommit history you may want to keep the original commits.\n\nI know you are talking about blobs, not commits, but perhaps there are some \nsimilar use cases of replaced blobs.\n\nThanks for looking at that,\nChristian.\n"}]}