{"thread":{"id":"27251","subject":"How to fork a file (git cp ?)","startedAt":"2011-05-04T17:56:29Z","lastAt":"2011-05-08T20:03:03Z","messageCount":19,"participants":["Mikhail T.","Johannes Sixt","Stephen Bash","Øyvind A. Holm","Junio C Hamano","Piotr Krukowiecki","Jeff King","Pete Harlan"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"167029","messageId":"4DC1934D.6070608@aldan.algebra.com","threadId":"27251","inReplyTo":null,"subject":"How to fork a file (git cp ?)","fromName":"Mikhail T.","fromEmail":"mi+thun@aldan.algebra.com","sentAt":"2011-05-04T17:56:29Z","receivedAt":"2011-05-04T17:56:29Z","isPatch":false,"sender":{"key":"mi+thun@aldan.algebra.com","avatar":null},"body":"I need to add a new thing to our project. The thing will be similar to what \nalready exists. I'd like to \"derive\" the new files from the existing ones -- \nwithout altering them and by preserving the change-history.\n\nThis is not a separate branch -- the \"forked\" files will co-exist. I'd call this \ngit-cp (analogous to git-mv), but it does not exist...\n\nAny ideas? Thanks!\n\n    -mi\n"},{"id":"167030","messageId":"4DC1980D.4010009@kdbg.org","threadId":"27251","inReplyTo":"4DC1934D.6070608@aldan.algebra.com","subject":"Re: How to fork a file (git cp ?)","fromName":"Johannes Sixt","fromEmail":"j6t@kdbg.org","sentAt":"2011-05-04T18:16:45Z","receivedAt":"2011-05-04T18:16:45Z","isPatch":false,"sender":{"key":"j6t@kdbg.org","avatar":"https://avatars.githubusercontent.com/u/14810926?v=4"},"body":"Am 04.05.2011 19:56, schrieb Mikhail T.:\n> I need to add a new thing to our project. The thing will be similar to\n> what already exists. I'd like to \"derive\" the new files from the\n> existing ones -- without altering them and by preserving the\n> change-history.\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n> \n> This is not a separate branch -- the \"forked\" files will co-exist. I'd\n> call this git-cp (analogous to git-mv), but it does not exist...\n> \n> Any ideas? Thanks!\n> \n>    -mi\n> \n"},{"id":"167032","messageId":"4DC19955.7040503@kdbg.org","threadId":"27251","inReplyTo":"4DC1934D.6070608@aldan.algebra.com","subject":"Re: How to fork a file (git cp ?)","fromName":"Johannes Sixt","fromEmail":"j6t@kdbg.org","sentAt":"2011-05-04T18:22:13Z","receivedAt":"2011-05-04T18:22:13Z","isPatch":false,"sender":{"key":"j6t@kdbg.org","avatar":"https://avatars.githubusercontent.com/u/14810926?v=4"},"body":"(Sorry for the botched previous post - fat fingers)\n\nAm 04.05.2011 19:56, schrieb Mikhail T.:\n> I need to add a new thing to our project. The thing will be similar to\n> what already exists. I'd like to \"derive\" the new files from the\n> existing ones -- without altering them and by preserving the\n> change-history.\n\nYou cannot. Git does not have such a thing as \"copy-with-preserved-history\".\n\nYou just cp the file and git add it. But you will not be able to follow\na history of the file.\n\n-- Hannes\n"},{"id":"167039","messageId":"14525153.18843.1304535945960.JavaMail.root@mail.hq.genarts.com","threadId":"27251","inReplyTo":"4DC19955.7040503@kdbg.org","subject":"Re: How to fork a file (git cp ?)","fromName":"Stephen Bash","fromEmail":"bash@genarts.com","sentAt":"2011-05-04T19:05:45Z","receivedAt":"2011-05-04T19:05:45Z","isPatch":false,"sender":{"key":"bash@genarts.com","avatar":null},"body":"----- Original Message -----\n> From: \"Johannes Sixt\" <j6t@kdbg.org>\n> Sent: Wednesday, May 4, 2011 2:22:13 PM\n> Subject: Re: How to fork a file (git cp ?)\n> \n> Am 04.05.2011 19:56, schrieb Mikhail T.:\n> > I need to add a new thing to our project. The thing will be similar\n> > to\n> > what already exists. I'd like to \"derive\" the new files from the\n> > existing ones -- without altering them and by preserving the\n> > change-history.\n> \n> You cannot. Git does not have such a thing as\n> \"copy-with-preserved-history\".\n> \n> You just cp the file and git add it. But you will not be able to\n> follow a history of the file.\n\nLog (and other commands) can search for copies while traversing history:\n\n  -C[<n>]\n  --find-copies[=<n>]\n  Detect copies as well as renames. See also --find-copies-harder. If n is specified, it has the same meaning as for -M<n>.\n\n  --find-copies-harder\n  For performance reasons, by default, -C option finds copies only if the original file of the copy was modified in the same changeset. This flag makes the command inspect unmodified files as candidates for the source of copy. This is a very expensive operation for large projects, so use it with caution. Giving more than one -C option has the same effect.\n\nBut as I discovered a few weeks ago, the existing merge strategies don't understand copies (recursive can follow a rename, but if two files pass rename detection, I think the one with the higher similarity index wins).\n\nThanks,\nStephen\n"},{"id":"167040","messageId":"4DC1A64C.4090508@aldan.algebra.com","threadId":"27251","inReplyTo":"4DC19955.7040503@kdbg.org","subject":"Re: How to fork a file (git cp ?)","fromName":"Mikhail T.","fromEmail":"mi+thun@aldan.algebra.com","sentAt":"2011-05-04T19:17:32Z","receivedAt":"2011-05-04T19:17:32Z","isPatch":false,"sender":{"key":"mi+thun@aldan.algebra.com","avatar":null},"body":"On 04.05.2011 14:22, Johannes Sixt wrote:\n> You just cp the file and git add it. But you will not be able to follow\n> a history of the file.\nThank you for the information...\n\nSo, is this something worth adding to the wishlist, or was it omitted on purpose \n(and which purpose was that, then)?\n\nYours,\n\n    -mi\n"},{"id":"167043","messageId":"BANLkTinEb5BmR_Ls8YtGxyqGSVVBcnG32A@mail.gmail.com","threadId":"27251","inReplyTo":"4DC1A64C.4090508@aldan.algebra.com","subject":"Re: How to fork a file (git cp ?)","fromName":"Øyvind A. Holm","fromEmail":"sunny@sunbase.org","sentAt":"2011-05-04T20:36:39Z","receivedAt":"2011-05-04T20:36:39Z","isPatch":false,"sender":{"key":"sunny@sunbase.org","avatar":"https://avatars.githubusercontent.com/u/113445?v=4"},"body":"On 4 May 2011 21:17, Mikhail T. <mi+thun@aldan.algebra.com> wrote:\n> On 04.05.2011 14:22, Johannes Sixt wrote:\n> >\n> > You just cp the file and git add it. But you will not be able to\n> > follow a history of the file.\n>\n> Thank you for the information...\n>\n> So, is this something worth adding to the wishlist, or was it omitted\n> on purpose (and which purpose was that, then)?\n\nOh yes, that was intentional. This is easily one of the most debated\n\"features\" of Git, especially in the early days of Git when almost all\nSCM systems did it \"the CVS way\", by tracking the history of single\nfiles. Instead, Git tracks snapshots of the whole tree and focuses on\nthe whole content instead of single files. Renames are tracked by\ndetecting removal/adding of files, which can be detected later, for\nexample using \"git log --follow\". The reason for this is mostly speed\nissues, and most of the time the history of a single file is not\ninteresting in a project, but changes in the file tree as a whole.\n\nFrom the FAQ at <https://git.wiki.kernel.org/index.php/GitFaq>:\n\n  Git has to interoperate with a lot of different workflows, for example\n  some changes can come from patches, where rename information may not\n  be available. Relying on explicit rename tracking makes it impossible\n  to merge two trees that have done exactly the same thing, except one\n  did it as a patch (create/delete) and one did it using some other\n  heuristic.\n\n  On a second note, tracking renames is really just a special case of\n  tracking how content moves in the tree. In some cases, you may instead\n  be interested in querying when a function was added or moved to a\n  different file. By only relying on the ability to recreate this\n  information when needed, Git aims to provide a more flexible way to\n  track how your tree is changing.\n\n  However, this does not mean that Git has no support for renames. The\n  diff machinery in Git has support for automatically detecting renames,\n  this is turned on by the '-M' switch to the git-diff-* family of\n  commands. The rename detection machinery is used by git-log(1) and\n  git-whatchanged(1), so for example, 'git log -M' will give the commit\n  history with rename information. Git also supports a limited form of\n  merging across renames. The two tools for assigning blame,\n  git-blame(1) and git-annotate(1) both use the automatic rename\n  detection code to track renames.\n\n  As a very special case, 'git log' version 1.5.3 and later has\n  '--follow' option that allows you to follow renames when given a\n  single path.\n\n  Git has a rename command git mv, but that is just for convenience. The\n  effect is indistinguishable from removing the file and adding another\n  with different name and the same content.\n\nThis mail from Linus explains the issue in more detail and colour:\n<http://permalink.gmane.org/gmane.comp.version-control.git/217>.\n\nRegards,\nØyvind\n"},{"id":"167044","messageId":"7viptqdvrf.fsf@alter.siamese.dyndns.org","threadId":"27251","inReplyTo":"4DC19955.7040503@kdbg.org","subject":"Re: How to fork a file (git cp ?)","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2011-05-04T21:02:44Z","receivedAt":"2011-05-04T21:02:44Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Johannes Sixt <j6t@kdbg.org> writes:\n\n> Am 04.05.2011 19:56, schrieb Mikhail T.:\n>> I need to add a new thing to our project. The thing will be similar to\n>> what already exists. I'd like to \"derive\" the new files from the\n>> existing ones -- without altering them and by preserving the\n>> change-history.\n>\n> You cannot. Git does not have such a thing as \"copy-with-preserved-history\".\n\nWell, if you come from the mindset that a \"file\" has an identity (hence\nthere is a distinction between \"This file used to be called A and at one\npoint was renamed to B which is the name we see today\" and \"Some time ago\nsomebody created a file B with the same contents as A and then removed A\nat the same time\"), \"copy\" would not make much sense.  What identity does\na new file B gets when you create it by copying from A?\n\nThe same identity, or a different one?  What happens when you later\nrefactor the redundant part from these two files to create a common third\nfile C?  What identity does C have?\n\n> You just cp the file and git add it. But you will not be able to follow\n> a history of the file.\n\nCorrect.  You cannot follow a history of _the file_, as there is no such\nthing.\n\nYou can still follow the history of contents, though.  If you did a\nrefactor like the one in the above example, \"blame -L <range>\" would\nfollow the contents just fine.  The command is a 80% satisfactory\nimplementation of Linus's grand vision expressed in one of the most\nimportant message in the git mailing list archive:\n\n    http://thread.gmane.org/gmane.comp.version-control.git/27/focus=217\n"},{"id":"167061","messageId":"4DC20461.4090703@aldan.algebra.com","threadId":"27251","inReplyTo":"7viptqdvrf.fsf@alter.siamese.dyndns.org","subject":"Re: How to fork a file (git cp ?)","fromName":"Mikhail T.","fromEmail":"mi+thun@aldan.algebra.com","sentAt":"2011-05-05T01:58:57Z","receivedAt":"2011-05-05T01:58:57Z","isPatch":false,"sender":{"key":"mi+thun@aldan.algebra.com","avatar":null},"body":"On 04.05.2011 17:02, Junio C Hamano wrote:\n> Well, if you come from the mindset that a \"file\" has an identity (hence\n> there is a distinction between \"This file used to be called A and at one\n> point was renamed to B which is the name we see today\" and \"Some time ago\n> somebody created a file B with the same contents as A and then removed A\n> at the same time\"), \"copy\" would not make much sense.  What identity does\n> a new file B gets when you create it by copying from A?\nWhat I want is to signify something like: \"This code was obtained from \nthat in file A.\"\n\n\"copy\" -- of an individual file -- makes just as much sense as \"move\" \n(rename).\n\n    -mi\n"},{"id":"167063","messageId":"7v1v0ddhbz.fsf@alter.siamese.dyndns.org","threadId":"27251","inReplyTo":"4DC20461.4090703@aldan.algebra.com","subject":"Re: How to fork a file (git cp ?)","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2011-05-05T02:14:24Z","receivedAt":"2011-05-05T02:14:24Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"\"Mikhail T.\" <mi+thun@aldan.algebra.com> writes:\n\n> On 04.05.2011 17:02, Junio C Hamano wrote:\n>> Well, if you come from the mindset that a \"file\" has an identity (hence\n>> there is a distinction between \"This file used to be called A and at one\n>> point was renamed to B which is the name we see today\" and \"Some time ago\n>> somebody created a file B with the same contents as A and then removed A\n>> at the same time\"), \"copy\" would not make much sense.  What identity does\n>> a new file B gets when you create it by copying from A?\n> What I want is to signify something like: \"This code was obtained from\n> that in file A.\"\n\nI think that is what exactly \"blame -C -C\" gives you.\n"},{"id":"167138","messageId":"BANLkTimD7byL=rgy79BWFT3vqKpzv9aNOQ@mail.gmail.com","threadId":"27251","inReplyTo":"7v1v0ddhbz.fsf@alter.siamese.dyndns.org","subject":"Re: How to fork a file (git cp ?)","fromName":"Piotr Krukowiecki","fromEmail":"piotr.krukowiecki@gmail.com","sentAt":"2011-05-05T18:02:42Z","receivedAt":"2011-05-05T18:02:42Z","isPatch":false,"sender":{"key":"piotr.krukowiecki@gmail.com","avatar":"https://avatars.githubusercontent.com/u/3259959?v=4"},"body":"On Thu, May 5, 2011 at 4:14 AM, Junio C Hamano <gitster@pobox.com> wrote:\n> \"Mikhail T.\" <mi+thun@aldan.algebra.com> writes:\n>\n>> On 04.05.2011 17:02, Junio C Hamano wrote:\n>>> Well, if you come from the mindset that a \"file\" has an identity (hence\n>>> there is a distinction between \"This file used to be called A and at one\n>>> point was renamed to B which is the name we see today\" and \"Some time ago\n>>> somebody created a file B with the same contents as A and then removed A\n>>> at the same time\"), \"copy\" would not make much sense.  What identity does\n>>> a new file B gets when you create it by copying from A?\n>> What I want is to signify something like: \"This code was obtained from\n>> that in file A.\"\n>\n> I think that is what exactly \"blame -C -C\" gives you.\n\nMaybe Mikhail wanted to say that if there's a git-mv as a shortcut for\n  \"cp old new ; rm old; add new\"\nthen there should be a git-cp as a shortcut for\n  \"cp old new; add new\"\n\nJust for convenience (and symmetry with git-mv).\n\nHe did write:\n> \"copy\" -- of an individual file -- makes just as much sense as \"move\" (rename).\n\n-- \nPiotr Krukowiecki\n"},{"id":"167151","messageId":"7vk4e56kxa.fsf@alter.siamese.dyndns.org","threadId":"27251","inReplyTo":"BANLkTimD7byL=rgy79BWFT3vqKpzv9aNOQ@mail.gmail.com","subject":"Re: How to fork a file (git cp ?)","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2011-05-05T18:50:57Z","receivedAt":"2011-05-05T18:50:57Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Piotr Krukowiecki <piotr.krukowiecki@gmail.com> writes:\n\n> Maybe Mikhail wanted to say that if there's a git-mv as a shortcut for\n>   \"cp old new ; rm old; add new\"\n> then there should be a git-cp as a shortcut for\n>   \"cp old new; add new\"\n\nCopying and then futzing with a copy is a bad discipline to begin with.\ngit already has a reputation of having too many commands.  I am not\nthrilled about the idea of making things worse by adding an unnecessary\ncommand, and especially one that encourages a bad workflow.\n"},{"id":"167163","messageId":"BANLkTimPXVosaJBnOEUkURu4nsk=UNtRag@mail.gmail.com","threadId":"27251","inReplyTo":"7vk4e56kxa.fsf@alter.siamese.dyndns.org","subject":"Re: How to fork a file (git cp ?)","fromName":"Piotr Krukowiecki","fromEmail":"piotr.krukowiecki@gmail.com","sentAt":"2011-05-05T19:27:03Z","receivedAt":"2011-05-05T19:27:03Z","isPatch":false,"sender":{"key":"piotr.krukowiecki@gmail.com","avatar":"https://avatars.githubusercontent.com/u/3259959?v=4"},"body":"On Thu, May 5, 2011 at 8:50 PM, Junio C Hamano <gitster@pobox.com> wrote:\n> Piotr Krukowiecki <piotr.krukowiecki@gmail.com> writes:\n>\n>> Maybe Mikhail wanted to say that if there's a git-mv as a shortcut for\n>>   \"cp old new ; rm old; add new\"\n>> then there should be a git-cp as a shortcut for\n>>   \"cp old new; add new\"\n>\n> Copying and then futzing with a copy is a bad discipline to begin with.\n> git already has a reputation of having too many commands.  I am not\n> thrilled about the idea of making things worse by adding an unnecessary\n> command, and especially one that encourages a bad workflow.\n\nI'm not saying I want to have git-cp, but could you explain what is wrong with\n\"cp old new; add new\" (why is that bad workflow? How come adding a copy\nof a file can be a workflow at all?)\n\n\n-- \nPiotr Krukowiecki\n"},{"id":"167166","messageId":"4DC2FB0A.2090100@aldan.algebra.com","threadId":"27251","inReplyTo":"7v1v0ddhbz.fsf@alter.siamese.dyndns.org","subject":"Re: How to fork a file (git cp ?)","fromName":"Mikhail T.","fromEmail":"mi+thun@aldan.algebra.com","sentAt":"2011-05-05T19:31:22Z","receivedAt":"2011-05-05T19:31:22Z","isPatch":false,"sender":{"key":"mi+thun@aldan.algebra.com","avatar":null},"body":"On 04.05.2011 22:14, Junio C Hamano wrote:\n> I think that is what exactly \"blame -C -C\" gives you.\nFor that to be useful, one has to suspect, the file was derived by \ncopying something else... Simple \"git log\" will not suggest that -- \nunless the commit message, that adds the new copy of a file points to it...\n\nOn 05.05.2011 14:02, Piotr Krukowiecki wrote:\n> Maybe Mikhail wanted to say that if there's a git-mv as a shortcut for\n>    \"cp old new ; rm old; add new\"\ngit-mv preserves the old's change-history in new, so it is more than the \nabove, is not it?\n> then there should be a git-cp as a shortcut for\nYes...\n\n    -mi\n"},{"id":"167173","messageId":"20110505200130.GB1770@sigill.intra.peff.net","threadId":"27251","inReplyTo":"4DC2FB0A.2090100@aldan.algebra.com","subject":"Re: How to fork a file (git cp ?)","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2011-05-05T20:01:30Z","receivedAt":"2011-05-05T20:01:30Z","isPatch":false,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Thu, May 05, 2011 at 03:31:22PM -0400, Mikhail T. wrote:\n\n> On 04.05.2011 22:14, Junio C Hamano wrote:\n> >I think that is what exactly \"blame -C -C\" gives you.\n> For that to be useful, one has to suspect, the file was derived by\n> copying something else... Simple \"git log\" will not suggest that --\n> unless the commit message, that adds the new copy of a file points to\n> it...\n\nI think \"git log --follow\" will do what you want; it uses\nFIND_COPIES_HARDER.\n\n> On 05.05.2011 14:02, Piotr Krukowiecki wrote:\n> >Maybe Mikhail wanted to say that if there's a git-mv as a shortcut for\n> >   \"cp old new ; rm old; add new\"\n> git-mv preserves the old's change-history in new, so it is more than\n> the above, is not it?\n\nNo. The renames are detected at the time of viewing, not at the time of\ncommit.\n\n-Peff\n"},{"id":"167174","messageId":"BANLkTikE8aMh6RUDzrh=SuOxvKxuPShQhQ@mail.gmail.com","threadId":"27251","inReplyTo":"4DC2FB0A.2090100@aldan.algebra.com","subject":"Re: How to fork a file (git cp ?)","fromName":"Piotr Krukowiecki","fromEmail":"piotr.krukowiecki@gmail.com","sentAt":"2011-05-05T20:01:32Z","receivedAt":"2011-05-05T20:01:32Z","isPatch":false,"sender":{"key":"piotr.krukowiecki@gmail.com","avatar":"https://avatars.githubusercontent.com/u/3259959?v=4"},"body":"On Thu, May 5, 2011 at 9:31 PM, Mikhail T. <mi+thun@aldan.algebra.com> wrote:\n> On 04.05.2011 22:14, Junio C Hamano wrote:\n>>\n>> I think that is what exactly \"blame -C -C\" gives you.\n>\n> For that to be useful, one has to suspect, the file was derived by copying\n> something else... Simple \"git log\" will not suggest that -- unless the\n> commit message, that adds the new copy of a file points to it...\n\nMaybe it should be the default (performance issues?)\n\n\n> On 05.05.2011 14:02, Piotr Krukowiecki wrote:\n>>\n>> Maybe Mikhail wanted to say that if there's a git-mv as a shortcut for\n>>   \"cp old new ; rm old; add new\"\n>\n> git-mv preserves the old's change-history in new, so it is more than the\n> above, is not it?\n\nIt's the same IMO: log with --follow will follow both \"copies\" and \"renames\".\n\n\nBTW, I don't understand why 'status' shows renames but not copies:\n\n$ cp f fcp && git add fcp && git status\n# Changes to be committed:\n#\tnew file:   fcp\n\n$ mv f fmv && git add fmv && git rm f && git status\n# Changes to be committed:\n#\trenamed:    f -> fmv\n\nI would expect sth like \"copied: f -> fcp\".\nNot sure what about one file copied to multiple files, but I suppose\nrenames have the same problem.\n\nIt should not be a problem performance-wise...\n\n\n>> then there should be a git-cp as a shortcut for\n>\n> Yes...\n\n\n\n-- \nPiotr Krukowiecki\n"},{"id":"167177","messageId":"BANLkTimn9uKXfRDFnmOhbs6=93xASQ42-g@mail.gmail.com","threadId":"27251","inReplyTo":"BANLkTikE8aMh6RUDzrh=SuOxvKxuPShQhQ@mail.gmail.com","subject":"Re: How to fork a file (git cp ?)","fromName":"Piotr Krukowiecki","fromEmail":"piotr.krukowiecki@gmail.com","sentAt":"2011-05-05T20:06:44Z","receivedAt":"2011-05-05T20:06:44Z","isPatch":false,"sender":{"key":"piotr.krukowiecki@gmail.com","avatar":"https://avatars.githubusercontent.com/u/3259959?v=4"},"body":"On Thu, May 5, 2011 at 10:01 PM, Piotr Krukowiecki\n<piotr.krukowiecki@gmail.com> wrote:\n> BTW, I don't understand why 'status' shows renames but not copies:\n>\n> $ cp f fcp && git add fcp && git status\n> # Changes to be committed:\n> #       new file:   fcp\n>\n> $ mv f fmv && git add fmv && git rm f && git status\n> # Changes to be committed:\n> #       renamed:    f -> fmv\n>\n> I would expect sth like \"copied: f -> fcp\".\n> Not sure what about one file copied to multiple files, but I suppose\n> renames have the same problem.\n\nI mean similar problem - you can delete one or more identical files and add one\nor more new files with the same content.\n\n\n> It should not be a problem performance-wise...\n\n\n-- \nPiotr Krukowiecki\n"},{"id":"167178","messageId":"20110505200715.GC1770@sigill.intra.peff.net","threadId":"27251","inReplyTo":"BANLkTikE8aMh6RUDzrh=SuOxvKxuPShQhQ@mail.gmail.com","subject":"Re: How to fork a file (git cp ?)","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2011-05-05T20:07:15Z","receivedAt":"2011-05-05T20:07:15Z","isPatch":false,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Thu, May 05, 2011 at 10:01:32PM +0200, Piotr Krukowiecki wrote:\n\n> >> I think that is what exactly \"blame -C -C\" gives you.\n> >\n> > For that to be useful, one has to suspect, the file was derived by copying\n> > something else... Simple \"git log\" will not suggest that -- unless the\n> > commit message, that adds the new copy of a file points to it...\n> \n> Maybe it should be the default (performance issues?)\n\nPerformance is part of it, but also the fact that \"--follow\" has some\nlimitations. For example, you can't use it with arbitrary pathspecs. I\nhope to fix that at some point. There was a GSoC proposal, but it didn't\nget selected; I'm hoping to work on it myself sometime this summer.\n\n> BTW, I don't understand why 'status' shows renames but not copies:\n> \n> $ cp f fcp && git add fcp && git status\n> # Changes to be committed:\n> #\tnew file:   fcp\n> \n> $ mv f fmv && git add fmv && git rm f && git status\n> # Changes to be committed:\n> #\trenamed:    f -> fmv\n> \n> I would expect sth like \"copied: f -> fcp\".\n\nYeah, we probably should do copy detection. Even weirder, we seem to do\nrename detection for what's to be committed, but not for what's in the\nworktree.\n\nIf you want to do a patch, the changes would go in wt-status.c, in the\nfunctions:\n\n  wt_status_collect_changes_worktree\n  wt_status_collect_changes_index\n\n> It should not be a problem performance-wise...\n\nFor people running \"git status\" manually, no. But something like\nFIND_COPIES_HARDER may be expensive on a big tree for people who use\n\"git status\" output as part of their shell prompt. So probably it should\nbe configurable.\n\n-Peff\n"},{"id":"167442","messageId":"4DC6F1C8.8040007@pcharlan.com","threadId":"27251","inReplyTo":"BANLkTikE8aMh6RUDzrh=SuOxvKxuPShQhQ@mail.gmail.com","subject":"Re: How to fork a file (git cp ?)","fromName":"Pete Harlan","fromEmail":"pgit@pcharlan.com","sentAt":"2011-05-08T19:40:56Z","receivedAt":"2011-05-08T19:40:56Z","isPatch":false,"sender":{"key":"pgit@pcharlan.com","avatar":null},"body":"On 5/5/2011 1:01 PM, Piotr Krukowiecki wrote:\n> On Thu, May 5, 2011 at 9:31 PM, Mikhail T.<mi+thun@aldan.algebra.com>  wrote:\n>> On 04.05.2011 22:14, Junio C Hamano wrote:\n>>>\n>>> I think that is what exactly \"blame -C -C\" gives you.\n>>\n>> For that to be useful, one has to suspect, the file was derived by copying\n>> something else... Simple \"git log\" will not suggest that -- unless the\n>> commit message, that adds the new copy of a file points to it...\n>\n> Maybe it should be the default (performance issues?)\n\n...\n\n> BTW, I don't understand why 'status' shows renames but not copies:\n\nRename detection compares new files against deleted files.  Copy \ndetection compares new files against every file in the tree, which is \nusually much more costly.\n\n--Pete\n"},{"id":"167443","messageId":"7vd3jtrmdk.fsf@alter.siamese.dyndns.org","threadId":"27251","inReplyTo":"4DC6F1C8.8040007@pcharlan.com","subject":"Re: How to fork a file (git cp ?)","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2011-05-08T20:03:03Z","receivedAt":"2011-05-08T20:03:03Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Pete Harlan <pgit@pcharlan.com> writes:\n\n> Rename detection compares new files against deleted files.  Copy\n> detection compares new files against every file in the tree, which is\n> usually much more costly.\n\nAlmost correct.  Copy detection usually compares new paths with paths\nmodified in the same commit.  \"Every file in the tree\" is done only when\nyou ask to find copies harder.\n"}]}