{"thread":{"id":"2116","subject":"getting rid of extra directories","startedAt":"2005-10-15T17:41:03Z","lastAt":"2005-11-04T19:05:43Z","messageCount":9,"participants":["Zack Brown","Junio C Hamano","Petr Baudis"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"10129","messageId":"20051015174103.GA2609@tumblerings.org","threadId":"2116","inReplyTo":null,"subject":"getting rid of extra directories","fromName":"Zack Brown","fromEmail":"zbrown@tumblerings.org","sentAt":"2005-10-15T17:41:03Z","receivedAt":"2005-10-15T17:41:03Z","isPatch":false,"sender":{"key":"zbrown@tumblerings.org","avatar":null},"body":"Hi folks,\n\nI've been using the latest Cogito. When I seek back and forth in a git repo,\ndirectories I've created tend to persist backward in time, cluttering up\nearlier versions.\n\nBy the discussions on this list, I'm pretty sure there's a way to stop this,\nbut I don't know clearly what it is, and I'm worried about trying things\nthat might corrupt my repository. Could someone spell it out for me please?\n\nBe well,\nZack\n\n-- \nZack Brown\n"},{"id":"10130","messageId":"7vu0fimzhn.fsf@assigned-by-dhcp.cox.net","threadId":"2116","inReplyTo":"20051015174103.GA2609@tumblerings.org","subject":"Re: getting rid of extra directories","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2005-10-15T18:00:52Z","receivedAt":"2005-10-15T18:00:52Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Zack Brown <zbrown@tumblerings.org> writes:\n\n> I've been using the latest Cogito. When I seek back and forth in a git repo,\n> directories I've created tend to persist backward in time, cluttering up\n> earlier versions.\n>\n> By the discussions on this list, I'm pretty sure there's a way to stop this,\n> but I don't know clearly what it is, and I'm worried about trying things\n> that might corrupt my repository. Could someone spell it out for me please?\n\nI do not know exactly what Cogito \"seek back and forth\" does,\nbut updating to git-core \"master\" branch may help.\n\nSpecifically, this commit intends to remove empty directory from\nthe working tree, where previously checked out tree object had\nfiles/directories inside while newly checked out tree does not.\n\n    commit 340e4f88c083b0692e6554b1c2c27fd43c7cc8d3\n    Author: Junio C Hamano <junkio@cox.net>\n    Date:   Mon Oct 10 17:34:08 2005 -0700\n\n        Remove empty directories after read-tree -u.\n\n        This fixes everybody's favorite gripe that switching branch\n        with 'git checkout' leaves empty directories.\n\n        Signed-off-by: Junio C Hamano <junkio@cox.net>\n"},{"id":"10131","messageId":"20051015192720.GA11364@tumblerings.org","threadId":"2116","inReplyTo":"7vu0fimzhn.fsf@assigned-by-dhcp.cox.net","subject":"Re: getting rid of extra directories","fromName":"Zack Brown","fromEmail":"zbrown@tumblerings.org","sentAt":"2005-10-15T19:27:20Z","receivedAt":"2005-10-15T19:27:20Z","isPatch":false,"sender":{"key":"zbrown@tumblerings.org","avatar":null},"body":"On Sat, Oct 15, 2005 at 11:00:52AM -0700, Junio C Hamano wrote:\n> Zack Brown <zbrown@tumblerings.org> writes:\n> \n> > I've been using the latest Cogito. When I seek back and forth in a git repo,\n> > directories I've created tend to persist backward in time, cluttering up\n> > earlier versions.\n> >\n> > By the discussions on this list, I'm pretty sure there's a way to stop this,\n> > but I don't know clearly what it is, and I'm worried about trying things\n> > that might corrupt my repository. Could someone spell it out for me please?\n> \n> I do not know exactly what Cogito \"seek back and forth\" does,\n\nIt means to \"cg-seek\" back to an earlier state of the repo, and forward to a\nmore recent state of the repo. \"seeking back and forth\" means doing a lot of\n\"cg-seek\" commands. Sorry that wasn't clear.\n\n> but updating to git-core \"master\" branch may help.\n\nI already use that branch.\n\nHere's some commands that reproduce the problem:\n\n$ mkdir tmpproj\n$ cd tmpproj\n$ cg-init\n\ngive the initial commit message and save\n\n$ ls > a\n$ cg-add a\n$ cg-commit\n\ngive the commit message and save\n\n$ cg-tag nodirs\n$ mkdir d\n$ mv a d/a\n$ cg-rm a\n$ cg-add d/a\n$ cg-commit\n\ngive the commit message and save\n\n$ cg-seek nodirs\n\nnow I would expect to see the original directory, with no 'd' subdirectory, and\njust the 'a' file sitting there.\n\n$ ls -F\na  d/\n$\n\nSee the problem? The 'd' directory did not exist in this version of the\nrepository, but it's there anyway.\n\nBe well,\nZack\n\n\n\n> \n> Specifically, this commit intends to remove empty directory from\n> the working tree, where previously checked out tree object had\n> files/directories inside while newly checked out tree does not.\n> \n>     commit 340e4f88c083b0692e6554b1c2c27fd43c7cc8d3\n>     Author: Junio C Hamano <junkio@cox.net>\n>     Date:   Mon Oct 10 17:34:08 2005 -0700\n> \n>         Remove empty directories after read-tree -u.\n> \n>         This fixes everybody's favorite gripe that switching branch\n>         with 'git checkout' leaves empty directories.\n> \n>         Signed-off-by: Junio C Hamano <junkio@cox.net>\n> \n> -\n> To unsubscribe from this list: send the line \"unsubscribe git\" in\n> the body of a message to majordomo@vger.kernel.org\n> More majordomo info at  http://vger.kernel.org/majordomo-info.html\n\n-- \nZack Brown\n"},{"id":"10142","messageId":"7v8xwummtm.fsf@assigned-by-dhcp.cox.net","threadId":"2116","inReplyTo":"20051015192720.GA11364@tumblerings.org","subject":"Re: getting rid of extra directories","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2005-10-15T22:34:29Z","receivedAt":"2005-10-15T22:34:29Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Zack Brown <zbrown@tumblerings.org> writes:\n\n>> I do not know exactly what Cogito \"seek back and forth\" does,\n>\n> It means to \"cg-seek\" back to an earlier state of the repo, and forward to a\n> more recent state of the repo. \"seeking back and forth\" means doing a lot of\n> \"cg-seek\" commands. Sorry that wasn't clear.\n>\n>> but updating to git-core \"master\" branch may help.\n>\n> I already use that branch.\n\nI usually do not use Cogito, so I updated to the latest and\ntried it myself.  No wonder.\n\ncg-seek does not use \"git-read-tree -m -u $old $new\", which was\nupdated by that commit I mentioned to remove the empty\ndirectories. It does \"git-read-tree -m $new\" and does the\nremoval part manually by reading from diff-tree $old $new.  I\nsuspect the code was there before the two-tree read-tree was\ninvented.\n\nA similar sequence as you did, in pure git, would remove empty\ndirectory d/ when switching branches between.\n\n    $ mkdir junkproj\n    $ cd junkproj\n    $ git-init-db\n    $ ls >a\n    $ git-add a\n    $ git-commit -a -m 'Add a'\n    $ git-checkout -b adddir\n    $ mkdir d\n    $ mv a d/a\n    $ git-add d\n    $ git-commit -a -m 'Move a to d/a'\n\n    $ git-checkout master\n\nI suspect cg-Xlib::tree_timewarp, which currently does\n\"git-read-tree -m $branch\" followed by diff-tree piped to xargs,\ncan be taught to use \"git-read-tree -m -u $base $branch\" (and\nlose the git-checkout-index -f -a immediately after that while\nwe are at it), but I do not do Porcelain, so...\n"},{"id":"11051","messageId":"20051103003423.GH1431@pasky.or.cz","threadId":"2116","inReplyTo":"7v8xwummtm.fsf@assigned-by-dhcp.cox.net","subject":"Three-way merge with the index as one way","fromName":"Petr Baudis","fromEmail":"pasky@suse.cz","sentAt":"2005-11-03T00:34:23Z","receivedAt":"2005-11-03T00:34:23Z","isPatch":false,"sender":{"key":"pasky@ucw.cz","avatar":"https://avatars.githubusercontent.com/u/18439?v=4"},"body":"Dear diary, on Sun, Oct 16, 2005 at 12:34:29AM CEST, I got a letter\nwhere Junio C Hamano <junkio@cox.net> told me that...\n> I suspect cg-Xlib::tree_timewarp, which currently does\n> \"git-read-tree -m $branch\" followed by diff-tree piped to xargs,\n> can be taught to use \"git-read-tree -m -u $base $branch\" (and\n> lose the git-checkout-index -f -a immediately after that while\n> we are at it), but I do not do Porcelain, so...\n\nThis is problematic, since with our current way of tree timewarping,\nrestoring local changes to files which got deleted will make patch error\nout, etc.\n\nI wanted to make tree_timewarp do three-way merge, but didn't figure a\ngood way to do it. First, what do I want - a two-way merge between two\ntrees, which will however respect (not die on) local changes in the\nworking tree.\n\nOne approach is to take the working tree, construct a tree object from\nit and then run the regular three-way merge on that. But that is a waste\nof time and pollutes the database with nonsensical objects. The\nadvantage is that I can reuse the per-file merge resolution script\nwithout any changes.\n\nHowever, this seems to be the only way to do this right now. What do you\nthink about the disadvantages - should we care? A possible alternative I\ncan imagine is to make a two-way merge mode which somehow records the\nconflicts with index back in the index file instead of committing\nsuicide. Possibly the hex(-1) sha1 might be used for the relevant index\nitems, meaning \"the current working copy\". The per-file merge resolution\nscripts would have to be tweaked for this then, but it shouldn't be that\nhard; what I found hard was actually getting my head 'round the weird\ngit-read-tree code recording the stages in the index file. ;-)\n\nOpinions?\n\n-- \n\t\t\t\tPetr \"Pasky\" Baudis\nStuff: http://pasky.or.cz/\nVI has two modes: the one in which it beeps and the one in which\nit doesn't.\n"},{"id":"11058","messageId":"7vy846ma65.fsf@assigned-by-dhcp.cox.net","threadId":"2116","inReplyTo":"20051103003423.GH1431@pasky.or.cz","subject":"Re: Three-way merge with the index as one way","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2005-11-03T08:02:10Z","receivedAt":"2005-11-03T08:02:10Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Petr Baudis <pasky@suse.cz> writes:\n\n> One approach is to take the working tree, construct a tree object from\n> it and then run the regular three-way merge on that. But that is a waste\n> of time and pollutes the database with nonsensical objects. The\n> advantage is that I can reuse the per-file merge resolution script\n> without any changes.\n\nFor a large tree, constructing a full tree just to merge a\ncouple of potentially conflicting paths might turn out be a\nwaste of time, but I suspect that is something you could\noptimize later.  git-am 3-way fallback logic constructs a sparse\ntemporary tree and uses it for running regular 3-way, and you\nmay be able to do something similar.  Right now git-am takes an\ne-mail patch and when it runs all the way it creates a commit,\nbut the core logic that applies patch and falls back to 3-way\ncould be separated out for your application.  Then you could:\n(1) 'git diff HEAD' before tree-warp to preserve the user\nchanges, (2) clean up the working tree to match HEAD, (3) warp\nto the other tree, and (4) fed the user change perserved to\ngit-am core logic.  That might give you something near optimum.\n\nAbout \"nonsensical\" objects, I am not so sure how nonsensical\nthose objects you would record from the working tree\n(intermediate state) are.  If you find two trees match on a path\nthat has changed in the working tree, there won't be any\nconflict on that paths so it is like the user did an extra\ngit-update-index on that path when no merge or warp is involved,\nfrom object database pollution POV; I do not personally think\nthat is such a bad thing.\n"},{"id":"11083","messageId":"20051103202125.GK1431@pasky.or.cz","threadId":"2116","inReplyTo":"7vy846ma65.fsf@assigned-by-dhcp.cox.net","subject":"Re: Three-way merge with the index as one way","fromName":"Petr Baudis","fromEmail":"pasky@suse.cz","sentAt":"2005-11-03T20:21:25Z","receivedAt":"2005-11-03T20:21:25Z","isPatch":false,"sender":{"key":"pasky@ucw.cz","avatar":"https://avatars.githubusercontent.com/u/18439?v=4"},"body":"Dear diary, on Thu, Nov 03, 2005 at 09:02:10AM CET, I got a letter\nwhere Junio C Hamano <junkio@cox.net> told me that...\n> git-am 3-way fallback logic constructs a sparse\n> temporary tree and uses it for running regular 3-way, and you\n> may be able to do something similar.\n\nI'm confused now - if the tree is sparse, how does git-read-tree -m know\nthat the missing files from the other tree are not deletes?\n\n> Right now git-am takes an\n> e-mail patch and when it runs all the way it creates a commit,\n> but the core logic that applies patch and falls back to 3-way\n> could be separated out for your application.  Then you could:\n> (1) 'git diff HEAD' before tree-warp to preserve the user\n> changes, (2) clean up the working tree to match HEAD,\n\nAt this point I get nervous since there is a potential for data loss\nwhen something goes wrong at this point (e.g. system crash). I'm not\nsaying there are no places like that in Cogito now, but I generally\ntry to avoid them whenever possible.\n\n> (3) warp to the other tree, and (4) fed the user change perserved\n> to git-am core logic.  That might give you something near optimum.\n> \n> About \"nonsensical\" objects, I am not so sure how nonsensical\n> those objects you would record from the working tree\n> (intermediate state) are.  If you find two trees match on a path\n> that has changed in the working tree, there won't be any\n> conflict on that paths so it is like the user did an extra\n> git-update-index on that path when no merge or warp is involved,\n> from object database pollution POV; I do not personally think\n> that is such a bad thing.\n\nBut if they don't match, you'll get superfluous blobs for the original\nindex versions which are almost certain to go away.\n\n-- \n\t\t\t\tPetr \"Pasky\" Baudis\nStuff: http://pasky.or.cz/\nVI has two modes: the one in which it beeps and the one in which\nit doesn't.\n"},{"id":"11088","messageId":"7v8xw5ctrc.fsf@assigned-by-dhcp.cox.net","threadId":"2116","inReplyTo":"20051103202125.GK1431@pasky.or.cz","subject":"Re: Three-way merge with the index as one way","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2005-11-03T21:21:27Z","receivedAt":"2005-11-03T21:21:27Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Petr Baudis <pasky@suse.cz> writes:\n\n>> git-am 3-way fallback logic constructs a sparse\n>> temporary tree and uses it for running regular 3-way, and you\n>> may be able to do something similar.\n>\n> I'm confused now - if the tree is sparse, how does git-read-tree -m know\n> that the missing files from the other tree are not deletes?\n\nThe git-am 3-way fallback works like this:\n\n    - the patch did not apply to our current head cleanly.\n\n    - however, we have all the original blobs, recorded on\n      'index xxxxxxx..xxxxxxx' line of the patch.\n\n    - construct a temporary tree T0 that has only paths affected\n      by that patch, with the original blobs.\n\n    - apply the patch to T0 to construct another temporary tree\n      T1.\n\n    - 3-way merge our current head and T1, pretending as if T0\n      is our common ancestor.  I.e. \"read-tree -m -u T0 HEAD T1\"\n\nThe paths that did not change by the patch (in your case, the\npaths without local modification before tree-warp) are not\npresent in either T0 or T1, so the 3-way merge in the last step\nwould see that our current head added those paths while T0->T1\ntransition kept their absense intact --- which results in\nadded-in-one-side-only.\n\nI think the problem you are solving would be solved by what I\nsuggested in the earlier message, but probably always doing that\nmay not be the optimum solution.\n\n    - the working tree (and index) is derived from HEAD, but may\n      not match HEAD (local modifications).\n\n    - you want to tree-warp to T1, doing an equivalent of\n      \"read-tree -m -u HEAD T1\" but preserving the local\n      modifications.\n\nYou would want a merge between INDEX and T1 using HEAD as the\ncommon ancestor (INDEX is a tree that your user would get if all\nthe local modification in the working tree were registered with\nupdate-index and then git-write-tree were run).\n\n\t INDEX\n        /\n    HEAD\n        \\\n         T1\n\nTwo-tree form of read-tree -m -u should work as long as\ndifferences between HEAD and INDEX do not interfere with\nHEAD->T1 transition.  So you probably would first want to try\n\"read-tree -m -u HEAD T1\", and use the 3-way fallback I\ndescribed earlier when it fails?\n\n> But if they don't match, you'll get superfluous blobs for the original\n> index versions which are almost certain to go away.\n\nAnother way of putting it is that I would not particularly worry\nabout those dangling blobs and trees -- that's what we have 'git\nprune' for.\n"},{"id":"11144","messageId":"7vslucutbs.fsf@assigned-by-dhcp.cox.net","threadId":"2116","inReplyTo":"20051103003423.GH1431@pasky.or.cz","subject":"Re: Three-way merge with the index as one way","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2005-11-04T19:05:43Z","receivedAt":"2005-11-04T19:05:43Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Petr Baudis <pasky@suse.cz> writes:\n\n> I wanted to make tree_timewarp do three-way merge, but didn't figure a\n> good way to do it. First, what do I want - a two-way merge between two\n> trees, which will however respect (not die on) local changes in the\n> working tree.\n\nI remember that we used to have --emu23 flag to read-tree.  It\nwas yanked out when we did multi-merge-base conversion, because\nnobody was using it, but I wonder if that is close to what you\nare looking for.\n\n$ git whatchanged -S--emu23 read-tree.c\n\ntells me that 32192e6622d78347448cfc0572827d6e64e0de28 commit\ncompleted it and ee6566e8d70da682ac4926dd8a67ac821b2c1743 commit\nremoved it.\n"}]}