{"thread":{"id":"24505","subject":"replaced objects and working directory","startedAt":"2010-07-25T04:20:45Z","lastAt":"2010-07-25T06:02:07Z","messageCount":2,"participants":["Nguyen Thai Ngoc Duy","Jonathan Nieder"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"146244","messageId":"AANLkTi=3=MX8+U4Oq4q_RACyxFYj-HmBYXFBxxQdFf_e@mail.gmail.com","threadId":"24505","inReplyTo":null,"subject":"replaced objects and working directory","fromName":"Nguyen Thai Ngoc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2010-07-25T04:20:45Z","receivedAt":"2010-07-25T04:20:45Z","isPatch":false,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"Hi,\n\nShould worktree (or the index) be aware of replaced objects? It seems\na bit odd to do \"git checkout HEAD^\" then \"git status\" reports\nmodification. Maybe \"git status\" and similar operations should also\ncheck worktree version against the replaced version, in addition to\nthe original version?\n\n$ git init\n$ echo 1 > 1\n$ git add 1\n$ SHA1=`git hash-object 1`\n$ git ci -m 1\n$ echo 2 >> 1\n$ git add 1\n$ git ci -m 2\n$ SHA2=`git hash-object 1`\n$ git replace $SHA1 $SHA2\n$ git st\n# On branch master\nnothing to commit (working directory clean)\n$ git co HEAD^\n$ git st\n# Not currently on any branch.\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 directory)\n#\n#       modified:   1\n#\nno changes added to commit (use \"git add\" and/or \"git commit -a\")\n$ git di\ndiff --git a/1 b/1\nindex d00491f..1191247 100644\n-- \nDuy\n"},{"id":"146245","messageId":"20100725060207.GA17601@burratino","threadId":"24505","inReplyTo":"AANLkTi=3=MX8+U4Oq4q_RACyxFYj-HmBYXFBxxQdFf_e@mail.gmail.com","subject":"Re: replaced objects and working directory","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2010-07-25T06:02:07Z","receivedAt":"2010-07-25T06:02:07Z","isPatch":false,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"Nguyen Thai Ngoc Duy wrote:\n\n> Should worktree (or the index) be aware of replaced objects?\n\nThe following is only about replaced blobs (replaced trees are\nharder to deal with, I think).\n\nTwo uses to keep in mind:\n\n 1. \"git checkout\", \"git diff\", and so on to explore the\n    tweaked history (as you mentioned).\n\n 2. \"git write-tree\" as used by filter-branch to set the\n    new history in stone.\n\n1) Currently read-tree does not do anything special with replaced\nblobs; it is up to checkout-index to get the substituted blob object\nand write a different file to disk.  Unfortunately when update-index\ntries to read it back, that means it looks like the file has changed.\n\n> Maybe \"git status\" and similar operations should also\n> check worktree version against the replaced version, in addition to\n> the original version?\n\nIt might be simpler to check against only the replaced version, like\nthis:\n\n| diff --git i/read-cache.c w/read-cache.c\n| index f1f789b..0f031da 100644\n| --- i/read-cache.c\n| +++ w/read-cache.c\n| @@ -93,7 +93,7 @@ static int ce_compare_data(struct cache_entry *ce, struct stat *st)\n|  \tif (fd >= 0) {\n|  \t\tunsigned char sha1[20];\n|  \t\tif (!index_fd(sha1, fd, st, 0, OBJ_BLOB, ce->name))\n| -\t\t\tmatch = hashcmp(sha1, ce->sha1);\n| +\t\t\tmatch = hashcmp(sha1, lookup_replace_object(ce->sha1));\n|  \t\t/* index_fd() closed the file descriptor already */\n|  \t}\n|  \treturn match;\n| @@ -134,7 +134,7 @@ static int ce_compare_gitlink(struct cache_entry *ce)\n|  \t */\n|  \tif (resolve_gitlink_ref(ce->name, \"HEAD\", sha1) < 0)\n|  \t\treturn 0;\n| -\treturn hashcmp(sha1, ce->sha1);\n| +\treturn hashcmp(sha1, lookup_replace_object(ce->sha1));\n|  }\n|  \n|  static int ce_modified_check_fs(struct cache_entry *ce, struct stat *st)\n| @@ -232,7 +232,7 @@ static int ce_match_stat_basic(struct cache_entry *ce, struct stat *st)\n|  \n|  \t/* Racily smudged entry? */\n|  \tif (!ce->ce_size) {\n| -\t\tif (!is_empty_blob_sha1(ce->sha1))\n| +\t\tif (!is_empty_blob_sha1(lookup_replace_object(ce->sha1)))\n|  \t\t\tchanged |= DATA_CHANGED;\n|  \t}\n|  \n\nThe main downside is that if you remove and re-add an index entry,\nthis is no longer a no-op.  But I think that getting \"update-index\n--refresh\" to be content should be enough to make exploring the\nalternate objects bearable.\n\n2) write-tree trusts the index as far as blobs go and rewrites all\nthe trees itself.  Probably it should dereference replace refs for\nreplaced blobs, which would make the \"rewriting everything\" behavior\nmore consistent.\n\n| diff --git i/cache-tree.c w/cache-tree.c\n| index d917437..43d5030 100644\n| --- i/cache-tree.c\n| +++ w/cache-tree.c\n| @@ -324,7 +324,7 @@ static int update_one(struct cache_tree *it,\n|  \t\t\tmode = S_IFDIR;\n|  \t\t}\n|  \t\telse {\n| -\t\t\tsha1 = ce->sha1;\n| +\t\t\tsha1 = lookup_replace_object(ce->sha1);\n|  \t\t\tmode = ce->ce_mode;\n|  \t\t\tentlen = pathlen - baselen;\n|  \t\t}\n\nI once had plans for these two tasks and time ran out.  \nhttp://thread.gmane.org/gmane.comp.version-control.git/139204/focus=139222\n\nHope that helps,\nJonathan\n"}]}