{"thread":{"id":"27156","subject":"Cloning into an existing, non-empty directory?","startedAt":"2011-04-21T21:27:15Z","lastAt":"2011-04-25T18:37:16Z","messageCount":12,"participants":["Richard Hartmann","Jonathan Nieder","Nguyen Thai Ngoc Duy","Andreas Schwab","Jeff King"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"166206","messageId":"BANLkTi=VwiqN99AMEJb6jb1uFya2Hipibw@mail.gmail.com","threadId":"27156","inReplyTo":null,"subject":"Cloning into an existing, non-empty directory?","fromName":"Richard Hartmann","fromEmail":"richih.mailinglist@gmail.com","sentAt":"2011-04-21T21:27:15Z","receivedAt":"2011-04-21T21:27:15Z","isPatch":false,"sender":{"key":"richih.mailinglist@gmail.com","avatar":"https://avatars.githubusercontent.com/u/754723?v=4"},"body":"Hi all,\n\nI know that the manpage explicitly states that it's not possible to\nclones into an existing, non-empty directory, but I wanted to see if\nanyone is aware of a workaround or if I can convince people that is it\nof use in specific circumstances.\n\nSome of you will be keeping their RC files in git repo(s) which means\nyou are basically left with two options:\n\n1) Use soft-/hardlinks\n2) Change your working tree\n\nI went for option two which looks like:\n\nrichih@roadwarrior ~/.config/vcsh/repo.d/mr.git % ls -a\n.   branches        config       FETCH_HEAD  hooks  info  objects    packed-refs\n..  COMMIT_EDITMSG  description  HEAD        index  logs  ORIG_HEAD  refs\nrichih@roadwarrior ~/.config/vcsh/repo.d/mr.git % cat config\n[core]\n\trepositoryformatversion = 0\n\tfilemode = true\n\tbare = false\n\tlogallrefupdates = true\n\tworktree = /home/richih/\n[remote \"origin\"]\n\tfetch = +refs/heads/*:refs/remotes/origin/*\n\turl = <remote>\n[branch \"master\"]\n\tremote = origin\n\tmerge = refs/heads/master\nrichih@roadwarrior ~/.config/vcsh/repo.d/mr.git %\n\nThis works just fine as long as you're using\n\n  git --work-tree=$HOME \\\n    --git-dir=$HOME/.config/vcsh/repo.d/mr.git \\\n    pull\n\nor similar on an existing, manually mangled repo. The only real\nproblem left is that I can't clone initially as $HOME is obviously\nnon-empty, resulting in\n\n  git --work-tree=$HOME \\\n    --git-dir=$HOME/.config/vcsh/repo.d/mr.git \\\n    clone <remote> .config/vcsh/repo.d/mr.git\nfatal: working tree '/home/richih' already exists.\n\nThis means I am down to cloning, creating the directories I need,\nmoving .git and the actual files around, making git aware that tracked\nfiles were not deleted, just moved, and then finally being able to use\nmy repo.\n\nObviously, this would imply some sort of conflict handling during cloning.\n\nAnyway, I would _really_ love to have a way to avoid all this manual\nwork and just clone into $HOME, telling git that it's OK and I know\nwhat I am doing.\n\n\nThanks,\nRichard\n\nPS: In case you are interested in keeping your RC files (and the rest\nof your life) in git, there's a vcs-home mailing list and #vcs-home on\nirc.oftc.net.\n"},{"id":"166208","messageId":"20110421220327.GA3396@elie","threadId":"27156","inReplyTo":"BANLkTi=VwiqN99AMEJb6jb1uFya2Hipibw@mail.gmail.com","subject":"Re: Cloning into an existing, non-empty directory?","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2011-04-21T22:03:27Z","receivedAt":"2011-04-21T22:03:27Z","isPatch":false,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"Hi,\n\nRichard Hartmann wrote:\n\n> The only real\n> problem left is that I can't clone initially as $HOME is obviously\n> non-empty, resulting in\n>\n>   git --work-tree=$HOME \\\n>     --git-dir=$HOME/.config/vcsh/repo.d/mr.git \\\n>     clone <remote> .config/vcsh/repo.d/mr.git\n> fatal: working tree '/home/richih' already exists.\n>\n> This means I am down to cloning, creating the directories I need,\n> moving .git and the actual files around, making git aware that tracked\n> files were not deleted, just moved, and then finally being able to use\n> my repo.\n\nHave you tried something like the following?\n\n\tcd $CROWDED_DIRECTORY\n\tGIT_DIR=/path/to/git/dir\n\tGIT_WORK_TREE=$(pwd)\n\texport GIT_DIR GIT_WORK_TREE\n\n\tgit init\n\tgit remote add origin <remote>\n\tgit pull\n\nTwo more caveats for the road. :)\n\n - git does not track detailed file permissions or secret/non-secret\n   status.  Please be careful about ssh private keys and so on.\n\n - when updating the worktree, git will unlink existing files before\n   replacing them and does not fsync the result.  So one should be\n   careful when tracking files that will cause major harm if they go\n   missing temporarily (though I can't think of any major examples in\n   $HOME offhand).\n\nHappy hacking,\nJonathan\n"},{"id":"166220","messageId":"BANLkTikY7c7rP+yv5vt2vxw5nu84k_H=Xw@mail.gmail.com","threadId":"27156","inReplyTo":"20110421220327.GA3396@elie","subject":"Re: Cloning into an existing, non-empty directory?","fromName":"Richard Hartmann","fromEmail":"richih.mailinglist@gmail.com","sentAt":"2011-04-22T11:21:42Z","receivedAt":"2011-04-22T11:21:42Z","isPatch":false,"sender":{"key":"richih.mailinglist@gmail.com","avatar":"https://avatars.githubusercontent.com/u/754723?v=4"},"body":"On Fri, Apr 22, 2011 at 00:03, Jonathan Nieder <jrnieder@gmail.com> wrote:\n\n> Have you tried something like the following?\n\nI didn't. Thanks a lot for your feedback.\n\nMy tentative script, which is pretty ham-fisted, takes care of most\n(all?) possible errors, feedback on it is very welcome.\n\nTwo issues remain, though:\n\n1) git merge does not seem to understand either of those parameters.\nThis means that I have to pull, not merge, which introduces a race\ncondition into my safety checks. Which leads me to\n\n2) running `git pull` as suggested results in:\n\nfatal: /usr/lib/git-core/git-pull cannot be used without a working tree.\n\nwhich can be worked around by using --work-tree and --git-dir . Not\nideal, but workeable if I accept the race condition.\n\n\n\n\n#!/bin/sh\nset -x\n\n[[ $# -lt 2 ]] && echo \"not enough arguments\" && exit 1\n[[ $# -eq 2 ]] && GIT_WORK_TREE=\"$HOME/killme/fgit/target-default\"\n[[ $# -eq 3 ]] && GIT_WORK_TREE=\"$3\"\n[[ $# -gt 3 ]] && echo \"too many arguments\" && exit 2\n\nGIT_REMOTE=\"$1\"\nGIT_DIR=\"$2\"\nexport GIT_REMOTE GIT_DIR GIT_WORK_TREE\nmkdir -p $GIT_WORK_TREE\ncd $GIT_WORK_TREE ||\n  (echo \"$(basename $0): fatal: could not enter $GIT_WORK_TREE\" &&\n   exit 20) || exit 20\ngit init\ngit remote add origin $GIT_REMOTE\ngit config branch.master.remote origin\ngit config branch.master.merge  refs/heads/master\ngit fetch\nfor i in $(git ls-tree -r origin/master | awk '{print $4}'); do\n\t[[ -e $i ]] &&\n\t  echo \"$(basename $0): error: $i exists.\" &&\n\t  CONFLICT=1;\ndone\n\n[[ -n $CONFLICT ]] &&\n  echo \"$(basename $0): Will stop after fetching and not try to merge!\\n\" &&\n  exit 3\n\ngit --work-tree=\"$GIT_WORK_TREE\" --git-dir=\"$GIT_DIR\" pull\n#git --work-tree=\"$GIT_WORK_TREE\" --git-dir=\"$GIT_DIR\" merge\n\n\nAs usual, any and all feedback appreciated,\nthanks,\nRichard\n"},{"id":"166264","messageId":"20110423101500.GB1500@elie","threadId":"27156","inReplyTo":"BANLkTikY7c7rP+yv5vt2vxw5nu84k_H=Xw@mail.gmail.com","subject":"Re: Cloning into an existing, non-empty directory?","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2011-04-23T10:15:00Z","receivedAt":"2011-04-23T10:15:00Z","isPatch":false,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"Hi again,\n\nRichard Hartmann wrote[1]:\n\n> 1) git merge does not seem to understand either of those parameters.\n\nI assume you mean --work-tree and --git-dir.  But if true, that would\nbe a bug.\n\nBased on the script, it looks like you are not passing a branch name\nto \"git merge\".  Maybe that is the problem.  In any case, it would be\nnice to see what command you used, what result was expected, and what\nresult actually occured.\n\nSide note: git commands respect the GIT_DIR and GIT_WORK_TREE\nenvironment variables in addition to the corresponding command-line\nparameters, which can save some typing.\n\n[...]\n> 2) running `git pull` as suggested results in:\n>\n> fatal: /usr/lib/git-core/git-pull cannot be used without a working tree.\n>\n> which can be worked around by using --work-tree and --git-dir . Not\n> ideal, but workeable if I accept the race condition.\n\nWeird.  Maybe chdir-ing into the work tree will help?  (Traditionally,\ngit commands tend to be run from within the work tree, so I wouldn't\nbe too surprised if some commands do not like being run from outside.)\n\n[1] http://thread.gmane.org/gmane.comp.version-control.git/171920/focus=171934\n"},{"id":"166265","messageId":"BANLkTi=uNpruRhPcxKMUy4CH2V5q-z9U7Q@mail.gmail.com","threadId":"27156","inReplyTo":"20110423101500.GB1500@elie","subject":"Re: Cloning into an existing, non-empty directory?","fromName":"Nguyen Thai Ngoc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2011-04-23T10:28:48Z","receivedAt":"2011-04-23T10:28:48Z","isPatch":false,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"2011/4/23 Jonathan Nieder <jrnieder@gmail.com>:\n>> 2) running `git pull` as suggested results in:\n>>\n>> fatal: /usr/lib/git-core/git-pull cannot be used without a working tree.\n>>\n>> which can be worked around by using --work-tree and --git-dir . Not\n>> ideal, but workeable if I accept the race condition.\n>\n> Weird.  Maybe chdir-ing into the work tree will help?  (Traditionally,\n> git commands tend to be run from within the work tree, so I wouldn't\n> be too surprised if some commands do not like being run from outside.)\n\nDoes this patch help?\n\nhttp://article.gmane.org/gmane.comp.version-control.git/150986\n-- \nDuy\n"},{"id":"166266","messageId":"20110423103758.GA1883@elie","threadId":"27156","inReplyTo":"BANLkTi=uNpruRhPcxKMUy4CH2V5q-z9U7Q@mail.gmail.com","subject":"Re: Cloning into an existing, non-empty directory?","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2011-04-23T10:37:58Z","receivedAt":"2011-04-23T10:37:58Z","isPatch":false,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"Nguyen Thai Ngoc Duy wrote:\n>> Richard Hartmann wrote:\n\n>>> 2) running `git pull` as suggested results in:\n>>>\n>>> fatal: /usr/lib/git-core/git-pull cannot be used without a working tree.\n[...]\n> Does this patch help?\n> \n> http://article.gmane.org/gmane.comp.version-control.git/150986\n\nThat's what I was thinking of but on second thought that can't be it.\nRichard's script does chdir into $GIT_WORK_TREE.\n\nSo it's still puzzling, and a reduced testcase would be nice. :)\n\nThanks, both, and sorry for the nonsense.\n"},{"id":"166273","messageId":"BANLkTinV4cFC5vzr25V-D3PMwWx284zgoQ@mail.gmail.com","threadId":"27156","inReplyTo":"20110423101500.GB1500@elie","subject":"Re: Cloning into an existing, non-empty directory?","fromName":"Richard Hartmann","fromEmail":"richih.mailinglist@gmail.com","sentAt":"2011-04-23T22:11:11Z","receivedAt":"2011-04-23T22:11:11Z","isPatch":false,"sender":{"key":"richih.mailinglist@gmail.com","avatar":"https://avatars.githubusercontent.com/u/754723?v=4"},"body":"2011/4/23 Jonathan Nieder <jrnieder@gmail.com>:\n\n> Richard Hartmann wrote[1]:\n\nNice. Is that automagic? And if yes, may I steal it?\n\n\n> I assume you mean --work-tree and --git-dir.  But if true, that would\n> be a bug.\n\nWith env variables set:\n\n% git merge origin\nfatal: origin - not something we can merge\n%\n\nWith parameters:\n\n% git '--work-tree=/home/richih/killme/fgit/target-default'\n'--git-dir=/home/richih/killme/fgit/source' merge origin\nfatal: origin - not something we can merge\n%\n\nIn a normal worktree without any mangling:\n% git merge origin\n[...success...]\n%\n\nI think I reduced the test-case as much as I can, especially since the\nscript takes care of everything for you. If you simply run in on any\nrandom git repo, you will be able to replicate this behaviour.\nUnfortunately ;)\n\n\nThanks,\nRichard\n"},{"id":"166300","messageId":"20110425075750.GA28172@elie","threadId":"27156","inReplyTo":"BANLkTinV4cFC5vzr25V-D3PMwWx284zgoQ@mail.gmail.com","subject":"Re: Cloning into an existing, non-empty directory?","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2011-04-25T08:00:10Z","receivedAt":"2011-04-25T08:00:10Z","isPatch":false,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"Hi,\n\nRichard Hartmann wrote:\n\n> I think I reduced the test-case as much as I can\n\nAll right, sorry to be so dense.  I tried:\n\n\tgit init test && cd test\n\tgit remote add origin ~/src/some-repo\n\tgit fetch origin\n\nand then:\n\n\t$ git merge origin\n\tfatal: origin - not something we can merge\n\nIs this what you mean?  \"git merge\" is not advertised as taking the\nname of a remote repository as a parameter.  The usual usage is\ninstead to pass a commit, as in \"git merge origin/master\".\n\nI'm not sure what a good meaning for \"git merge <repository>\" would\nbe.  \"git pull <repository>\" does \"git fetch <repository>\" and then,\nif one of the fetched branches from <repository> is the configured\nupstream for the current branch, merges it.\n\nIdeas?  Probably the documentation or error message could use help\nfrom someone less blind to see what a first-time reader would see.\n\nRegards,\nJonathan\n"},{"id":"166302","messageId":"m2pqoa9121.fsf@linux-m68k.org","threadId":"27156","inReplyTo":"20110425075750.GA28172@elie","subject":"Re: Cloning into an existing, non-empty directory?","fromName":"Andreas Schwab","fromEmail":"schwab@linux-m68k.org","sentAt":"2011-04-25T08:40:06Z","receivedAt":"2011-04-25T08:40:06Z","isPatch":false,"sender":{"key":"schwab@linux-m68k.org","avatar":"https://avatars.githubusercontent.com/u/2175493?v=4"},"body":"Jonathan Nieder <jrnieder@gmail.com> writes:\n\n> I'm not sure what a good meaning for \"git merge <repository>\" would\n> be.\n\nIt's equivalent to refs/remotes/<repository>/HEAD if that exists.\n\nAndreas.\n\n-- \nAndreas Schwab, schwab@linux-m68k.org\nGPG Key fingerprint = 58CA 54C7 6D53 942B 1756  01D3 44D5 214B 8276 4ED5\n\"And now for something completely different.\"\n"},{"id":"166304","messageId":"20110425085913.GB28885@elie","threadId":"27156","inReplyTo":"m2pqoa9121.fsf@linux-m68k.org","subject":"Re: Cloning into an existing, non-empty directory?","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2011-04-25T08:59:13Z","receivedAt":"2011-04-25T08:59:13Z","isPatch":false,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"Andreas Schwab wrote:\n> Jonathan Nieder <jrnieder@gmail.com> writes:\n\n>> I'm not sure what a good meaning for \"git merge <repository>\" would\n>> be.\n>\n> It's equivalent to refs/remotes/<repository>/HEAD if that exists.\n\nAh, I should have checked gitrevisions(7).  Thank you.\n\nJonathan\nwho wonders where his origin/HEAD symref came from and if\n\"git remote set-head --auto origin\" was ever automatic\n"},{"id":"166313","messageId":"BANLkTimi8Q+2bK3QdWdJdX1V-WbrU+AbdA@mail.gmail.com","threadId":"27156","inReplyTo":"20110425075750.GA28172@elie","subject":"Re: Cloning into an existing, non-empty directory?","fromName":"Richard Hartmann","fromEmail":"richih.mailinglist@gmail.com","sentAt":"2011-04-25T14:08:06Z","receivedAt":"2011-04-25T14:08:06Z","isPatch":false,"sender":{"key":"richih.mailinglist@gmail.com","avatar":"https://avatars.githubusercontent.com/u/754723?v=4"},"body":"2011/4/25 Jonathan Nieder <jrnieder@gmail.com>:\n\n> Is this what you mean?  \"git merge\" is not advertised as taking the\n> name of a remote repository as a parameter.  The usual usage is\n> instead to pass a commit, as in \"git merge origin/master\".\n\nUgh. I must have copied the wrong command into my script and then ran\nwith it, trying to fix the error I was getting in the wrong place.\nSorry for that.\nI am running with environment variables and without any explicit\n--work-tree --git-dir as well and everything works just fine.\n\nIn case anyone is interested, I attached the working version.\n\n\nThanks a lot for your help, I really appreciate it!\nRichard\n"},{"id":"166323","messageId":"20110425183715.GA24069@sigill.intra.peff.net","threadId":"27156","inReplyTo":"20110425085913.GB28885@elie","subject":"Re: Cloning into an existing, non-empty directory?","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2011-04-25T18:37:16Z","receivedAt":"2011-04-25T18:37:16Z","isPatch":false,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Mon, Apr 25, 2011 at 03:59:13AM -0500, Jonathan Nieder wrote:\n\n> who wonders where his origin/HEAD symref came from and if\n> \"git remote set-head --auto origin\" was ever automatic\n\nIt is created by \"clone\", but not by \"git remote add\". The \"auto\" in\nremote's \"set-head\" means \"right now, look up the HEAD on the remote and\nset our $remote/HEAD based on it\". Not anything about being set up or\ntracked automatically.\n\nPerhaps \"git remote add\" should automatically do \"set-head --auto\", just\nas if you had cloned. I think the main reason against it is that doing\nso requires hitting the network, which \"remote add\" (without \"-f\") does\nnot otherwise need to do.\n\nCertainly if we are doing \"-f\", it would not be a big deal. In other\ncases, we could perhaps fill in the value on the first \"fetch\", but we\nmay need infrastructure to know when we are on the first fetch (and it\nis not simply the case that the user deleted $remote/HEAD themselves).\n\n-Peff\n"}]}