如何克隆到非空目录?


572

我的目录A的文件与目录B匹配。目录A可能还有其他需要的文件。目录B是git仓库。

我想将目录B克隆到目录A,但是git-clone不允许我这样做,因为该目录是非空的。

我希望它只是克隆.git,既然所有文件都匹配,我可以从那里去吗?

我无法克隆到空目录,因为目录A中的文件不在目录B中,因此我想保留它们。

复制.git是不可行的,因为我想使用refs进行推/拉操作,并且我不想手动设置它们。

有什么办法吗?

更新:我认为这可行,任何人都可以看到任何问题吗?->

cd a
git clone --no-hardlinks --no-checkout ../b a.tmp 
mv a.tmp/.git .
rm -rf a.tmp
git unstage # apparently git thinks all the files are deleted if you don't do this

5
也许您可以更改接受的答案?
巴斯蒂安Quast

Answers:


724

这为我工作:

git init
git remote add origin PATH/TO/REPO
git fetch
git reset origin/master  # Required when the versioned files existed in path before "git init" of this repo.
git checkout -t origin/master

注意: -t如果您想要的话,将会为您设置上游分支,通常是这样。


70
当传入文件已经存在时(如原始问题所述),这在非空目录中不起作用。但是,如果您git reset origin/master在之后git fetch,它会起作用(还保留所有本地更改)。
Araxia

8
致命:无法同时更新路径并切换到分支“ master”。
阿诺德·罗阿2015年

7
这个答案对我不起作用。当我这样做时,git checkout ...git抱怨我的所有文件都会被覆盖,因此我应该先将其移动。当我首先执行git reset origin / master /时,checkout命令抱怨名为master的分支已经存在。
萨斯基亚

4
git checkout master对我来说是足够的最后一步。
yoyo'1

16
所有步骤都工作正常,但最后一个让我成功:fatal: A branch named 'master' already exists。我想我并不是真的需要它。
Shadi

164

在以下Shell命令中existing-dir是目录,其内容与repo-to-clonegit存储库中的跟踪文件匹配。

# Clone just the repository's .git folder (excluding files as they are already in
# `existing-dir`) into an empty temporary directory
git clone --no-checkout repo-to-clone existing-dir/existing-dir.tmp # might want --no-hardlinks for cloning local repo

# Move the .git folder to the directory with the files.
# This makes `existing-dir` a git repo.
mv existing-dir/existing-dir.tmp/.git existing-dir/

# Delete the temporary directory
rmdir existing-dir/existing-dir.tmp
cd existing-dir

# git thinks all files are deleted, this reverts the state of the repo to HEAD.
# WARNING: any local changes to the files will be lost.
git reset --hard HEAD

5
我需要做,git reset --hard HEAD否则它不会放弃“已删除”的文件。
Dimitar

18
git reset HEAD对我来说很好。git reset --hard HEAD销毁文件中的所有更改,因此,如果它们与存储库中的文件不完全相同,则不应这样做。
Tgr

1
git reset HEAD似乎对我没有任何影响。git reset --hard HEAD可以-但这会丢失您对文件所做的任何更改。有更好的解决方案吗?
雅各布·多曼

1
@Casey的答案-git init / remote add / fetch / checkout-更干净,更简单,不需要任何临时文件夹。
yoyo 2014年

1
当文件夹中已经有需要保留但不在git repo中的文件时,@ Casey的答案对我不起作用。这对于在运行创建了文件和目录的安装脚本之后更新配置非常有用,但是您需要在已安装项的顶部更新/添加文件。
soulston 2014年

104

对对我有用的答案之一稍作修改:

git init
git remote add origin PATH/TO/REPO
git pull origin master

立即开始在master分支上工作。


1
必须重置HEAD-难以清理脏的现有目录,而又不删除gitignore中指定的不相关文件
Ray Foss

1
这是对我真正有用的,而不是@cmcginty的答案。
肯定

4
这并不完全等同于git-clone-缺少的是master分支的上游信息。可以通过添加来解决git branch --set-upstream-to=origin/master master
Slaven Rezic '18

此版本为我工作,刚刚做了git的复位-硬头
弗雷德里克·克利


25

这是我遇到相同问题时所要做的(至少我认为这是相同问题)。我进入目录A并运行git init

由于我不希望目录A中的文件后面跟随git,因此我编辑了.gitignore并将现有文件添加到其中。在此之后,我将git remote add origin '<url>' && git pull origin masterB克隆到A中而没有打h。


2
当传入文件已经存在时(如原始问题所述),该技术不适用于非空目录。
Araxia

11

我刚才使用过,需要最少破坏性的命令:

cd existing-dir
git clone --bare repo-to-clone .git
git config --unset core.bare
git remote rm origin
git remote add origin repo-to-clone
git reset

瞧!


10

另一个简单的食谱似乎对我很有效:

git clone --bare $URL .git
git config core.bare false

我检出包含现有文件的目录的主要用例是使用Git控制Unix点文件。在新帐户上,主目录中已经有一些文件,甚至可能是我想从Git获取的文件。


1
裸存储库的设置略有不同,尽管确实可以,但我不建议这样做。:)
ThorSummoner

1
你可以说得更详细点吗?有什么不同吗?
肯·威廉姆斯

1
只有两个区别:1.)该.git/config文件表明存储库是裸露的。2.)通常存储在其中的文件存储在.git根目录(您称为.git
mozey

4
这些都是正是克隆的变化.git,并设置core.barefalse会照顾的,所以我还是觉得这个方法不错。
肯·威廉姆斯

10

这为我工作:

cd existing_folder
git init
git remote add origin path_to_your_repo.git
git add .
git commit
git push -u origin master

6

我计划将新的Apache Web目录(使用WHM创建的帐户)用作登台Web服务器时遇到类似的问题。我首先需要使用代码库克隆我的新项目,然后通过从存储库中提取定期部署更改。

问题在于该帐户已经包含Web服务器文件,例如:

.bash_history
.bash_logout
.bash_profile
.bashrc
.contactemail
.cpanel/
...

...我不想删除或提交到我的存储库。我需要他们呆在那儿而没有上路和跟踪。

我做了什么:

我转到我的Web文件夹(existing_folder):

cd /home/existing_folder

然后:

git init
git remote add origin PATH/TO/REPO
git pull origin master
git status

它按预期显示了许多未暂存文件的列表-最初在我的cPanel Web帐户中已经存在的那些文件。

然后,感谢本文,我将这些文件的列表添加到了:

**.git/info/exclude**

这个文件,几乎像 .gitignore文件一样,使您可以忽略文件暂存。之后,我没有什么要提交到.git /目录中的了-它就像个人.gitignore一个人都看不到。

现在检查git status返回:

On branch master
nothing to commit, working tree clean

现在,只需从git存储库中提取内容,就可以将更改部署到此Web服务器。希望这有助于某些Web开发人员轻松创建登台服务器。


5

这是我在做什么:

git clone repo /tmp/folder
cp -rf /tmp/folder/.git /dest/folder/
cd /dest/folder
git checkout -f master

4

也许我误解了您的问题,但是如果您将文件从A复制/移动到git repo B并使用git add添加所需的文件,会不会更简单?

更新:从git文档:

仅当目录为空时才允许克隆到现有目录。

消息来源:http//git-scm.com/docs/git-clone


2
不,所有者和文件可以是任意的。这是针对具有多个开发人员的情况。我们都有现有的目录,目前只有一个具有git checkout。我们所有人都具有相同的文件子集,因此我们希望其他开发人员能够在保留其文件的同时进行克隆。并且它应该尽可能优雅和方便。
Dale Forester

老实说,我看不到在这种情况下发展的意义。您不能使用分支和合并操作吗?还是拥有带有外部依赖项的子存储库?您为什么要依赖一个“ git checkout”?
罗伯托·阿洛伊

5
“单次git checkout”不是整个折磨的重点。就是这样,我们需要一种前进的方式。我用似乎有效的解决方案更新了原始问题。不过,我感谢您的反馈。
Dale Forester

3
对此有很多合理的案例-我必须设置一个复杂的文件夹树,然后才能设置我的项目的源,并且该文件夹树包含例如不能存储在GitHub上的许可作品。
BrainSlugs83 2014年

3

我一直在寻找类似的东西,这是我想到的:

我的情况是,我有一个活动的Web树,而我试图为其创建一个远程存储库,而不移动当前Web树中的任何文件。这是我所做的:

  1. 转到网络树并运行 git init
  2. 转到存储库的预期位置并运行: git clone --bare /path/to/web/repo
  3. 在我的远程仓库中编辑配置文件,然后删除该[remote "origin"]部分。
  4. [remote "origin"]在Web树的.git / config中添加指向新远程仓库的部分。

我很喜欢这个食谱。
dland

git clone --bare这里是多余的,迂回的。为什么不仅仅git remote add origin <URL>放在首位?
Araxia

3

这对我来说是工作,但是您应该将远程存储库文件合并到本地文件:

git init
git remote add origin url-to-git
git branch --set-upstream-to=origin/master master
git fetch
git status

1

我喜欢Dale的答案,并且还添加了

git clone --depth 2 --no-checkout repo-to-clone existing-dir/existing-dir.tmp
git branch dev_new214
git checkout dev_new214
git add .
git commit
git checkout dev
git merge dev_new214

浅层的深度避免了很多额外的早期开发人员投入。新分支为我们提供了良好的可视化历史记录,该服务器中放置了一些新代码。在我看来,这是完美的用法分支。感谢所有发布在此的人的深刻见解。


0

尝试克隆到C /代码时遇到相同的问题

但是此文件夹包含一堆项目。

我在c / code / newproject中创建了一个新文件夹,并将克隆副本映射到该文件夹​​。

git桌面版,然后问我的用户,然后克隆就好了。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.