“ git clone”到现有文件夹的最佳实践是什么?


479

我有该项目的工作副本,没有任何源代码控制元数据。现在,我想在此文件夹中执行与git-clone等效的操作,并保留我的本地更改。

git-clone不允许我克隆到现有文件夹。最佳做法是什么?


4
更好的讨论在这里
cdunn2001

1
@MEM我更喜欢这个答案,但是两者都可以... stackoverflow.com/a/5377989/11236
ripper234

2
@ ripper234-是的。我当时处在相同的情况下,我只是做了那些步骤,没有任何问题。一切都很好。我想这是优先考虑的问题,最重要的是,正如您所说的,两者都有效。干杯。
MEM 2014年

1
这太疯狂了,没有干净的方法可以实现,当您要将projet克隆到已安装的共享文件夹时,此功能非常有用。
Thomas Decaux

Answers:


557

可以通过克隆到新目录,然后将.git目录移到现有目录中来完成。

如果您现有的目录名为“代码”。

git clone https://myrepo.com/git.git temp
mv temp/.git code/.git
rm -rf temp

也可以在克隆命令期间不执行检出操作来完成此操作。更多信息可以在这里找到。


25
请注意,这正是@ChrisJohnsen的建议,即他在评论中留下了。我发现它很有用,并希望将其变为实际答案。克里斯,如果您最终提出一个答案,我会很乐意删除这个答案。
2012年

2
谢谢!尽管缺少“ git checkout-”之类的步骤。因为它认为所有文件都被删除了,对吗?
mrooney 2012年

2
不,只要您git clone用作第一个命令,就不需要进一步的checkout命令。如果您git clone --no-checkout在第一步中使用类似的方法,那么在移动.git目录之后,有必要使用git reset HEAD告诉git这些文件尚未删除。
2013年

3
我将其添加为第三步:mv temp / .gitignore code / .gitignore
Daniel Aranda

1
@KalpeshSoni,是的,git将了解修改过的文件,并且可以使用普通的git命令(例如)查看更改git status
amicitas

284

不要克隆,取而代之。在回购中:

git init
git remote add origin $url_of_clone_source
git fetch origin
git checkout -b master --track origin/master # origin/master is clone's default

然后,您可以重置树以获取所需的提交:

git reset origin/master # or whatever commit you think is proper...

你就像被克隆了。

这里有趣的问题(还有一个没有答案的问题):如何找出裸树是基于哪个提交的,因此要重置到哪个位置。


7
我不喜欢这样做-按github设置“提示:仅在克隆HTTPS存储库URL时,凭据帮助器才起作用。” 我使用了凭证助手,这使我陷入了一个漫长而毫无结果的兔子洞。
安德鲁

5
'git checkout --track origin / master'也比'git checkout -b master --track origin / master'更好。不需要重置。
felipecrp 2014年

1
我收到错误“ Git错误:以下未跟踪的工作树文件将被签出覆盖”,因此我添加了以下命令:git clean -d -fx“”
shakaran 2015年

1
绝对不是在所有情况下都建议,但这正是我所需要的。
Chaim Eliyah '17

1
@AndreasKrey您的原始答案(我进入了编辑历史记录以查看)完全符合问题(和我)所需。更改的答案栏在结帐时不使用-f,这会丢弃本地更改,而这正是我所不想要的。如果我是您,我会考虑退回到您的原始答案。
阿珍(Ajean)

77

我做了以下操作,以检出现有目录中的master分支:

git init
git remote add origin [my-repo]
git fetch
git checkout origin/master -ft

2
这是一个很好的答案,并且避免了任何文件系统损坏。
user151841

1
这应该是公认的答案,因为它不是hack。
php_nub_qq

5
实际上,这恰恰是OP(和我)所不希望的,那就是覆盖本地更改。
阿让

我的支持表示这对我有帮助,但这不是对OP的问题的最佳答案。
TecBrat

2
有人可以解释为什么在-t这里使用标志吗?
jfowkes

38

我想要git clone一个新目录,然后将现有目录的内容复制到新克隆中。


4
如果这样做的话,请确保在非常仔细地提交之前先检查差异-这是绝对的经典案例,在这种情况下,自从您获得工作副本以来,您就可能不小心还原源存储库中所做的更改-因为没有足够的信息在工作副本中找出要进行的更改与开始进行更改之前的状态,以与回购中进行的其他更改合并。在这种情况下,我一次又一次地看到这种情况发生,以至于我从那时开始就“强烈劝阻”我自己和与之共事的人。
本·克利福德

71
git clone wherever tmp && git mv tmp/.git . && rm -rf tmp换句话说,将.git目录移出临时克隆似乎比清除克隆的工作树并在其中复制现有文件更简单。
克里斯·约翰森

1
@ChrisJohnsen:您应该回答一个问题,这绝对是做恕我直言的最佳方法
Stefano

2
@ChrisJohnsen 为我git mv tmp/.git .回来fatal: cannot move directory over file, source=tmp/.git, destination=.git。有人知道这个问题是什么吗?
丹尼斯2012年

6
@Dennis,这是一个错字:该命令应该是简单的mv,而不是git mv; 尽管这不能解释为什么您已经有一个.git文件(包含gitdir: some/path/to/a/git-dir一个“ gitfile”;如果不存在,则您会看到fatal: Not a git repository (or any of the parent directories): .git)。
克里斯·约翰森

34

使用临时目录是可以的,但是如果您想避免该步骤,则可以使用该目录。从工作目录的根目录:

$ rm -fr .git
$ git init
$ git remote add origin your-git-url
$ git fetch
$ git reset --mixed origin/master

20
git reset --hard origin/master将删除所有本地文件。
Mouad Debbar

1
要添加到什么上面已经指出的,之间的区别hard,并mixed是混合将保持局部变化(所以如果您稍后尝试把它会告诉你如不能与底垫拉:你有不分阶段的变化,请提交或藏匿它们) ,尽管努力会放弃这些本地更改
aexl

你拼错了遥控器。
Glenn Dayton

10
git clone your_repo tmp && mv tmp/.git . && rm -rf tmp && git reset --mixed

7
使用git reset --hard会否决本地文件更改,特别是不是此OP请求的更改。--mixed应该改为使用。
加勒布

4

要将git repo克隆到现有的空目录中,请执行以下操作:

cd myfolder
git clone https://myrepo.com/git.git . 

注意命令.末尾的git clone。这将把仓库下载到当前的工作目录中。


4
fatal: destination path '.' already exists and is not an empty directory.
罗兰·科夫勒

该目录必须为空。
okTalk

4
OP正在询问如何克隆到现有项目中,并指出git clone抱怨。错误的答案。
mix3d

仅当您创建新目录,运行上述命令而不使用“ git init”时,此方法才有效
Bilal Ahmed

3

按照OP的要求,已经有很多答案可以解决。但值得注意的是,以相反的方式进行操作要简单得多:

git clone repo-url tmp/
cp -R working/ tmp/

现在,您具有所需的目标状态-新鲜克隆+本地更改。


2

有两种方法。在可能的情况下,我将从新文件夹的干净文件夹开始,然后在以后复制您的版本。可能看起来像*:

mv $dir $dir.orig
git clone $url $dir
rsync -av --delete --exclude '.git' $dir.orig/ $dir/
rm -rf $dir.orig

此时,您应该拥有一个非常干净的工作副本,并将以前的工作文件夹作为当前工作目录,这样,如果您运行,任何更改(包括文件删除)都会显示在雷达上git status

另一方面,如果您确实必须这样做,则可以通过以下方式获得相同的结果:

cd $dir
git clone --no-checkout $url tempdir
mv tempdir/.git .
rmdir tempdir
git reset --mixed HEAD

无论哪种方式,我要做的第一件事就是运行类似的操作,git stash以获取保留的所有本地更改的副本,然后您可以重新应用它们,并通过它们来确定要提交的更改。

* 两个示例都假定您从项目的父目录中的Shell开始。


2

这是我遇到的所有方法中最好的

将存储库的.git文件夹(不包括已存在的文件)克隆existing-dir到一个空的临时目录中

  1. git clone --no-checkout repo-path-to-clone existing-dir/existing-dir.tmp //可能需要--no-hardlinks来克隆本地仓库

将.git文件夹移至包含文件的目录。这使existing-dir一个git回购。

  1. mv existing-dir/existing-dir.tmp/.git existing-dir/

删除临时目录

  1. rmdir existing-dir/existing-dir.tmp

  2. cd existing-dir

Git认为所有文件都已删除,这会将存储库的状态恢复为HEAD。

警告:文件的任何本地更改都将丢失。

  1. git reset --mixed HEAD

1
在99%的情况下,硬重置似乎是不必要的。
Stefan Fabian

0

如果您至少使用git 1.7.7(教clone--config选项),请将当前目录转换为工作副本:

git clone example.com/my.git ./.git --mirror --config core.bare=false

这是通过以下方式工作的:

  • 将存储库克隆到新.git文件夹中
  • --mirror根据.git需要将新克隆放入纯元数据文件夹中
  • --config core.bare=falsecountermands隐含bare=true的的--mirror选项,从而使存储库有相关的工作目录和行为像一个正常的克隆

如果.git您希望将其转换为工作副本的目录中已经存在元数据目录,则这显然将无法工作。


1
请注意,此技术将导致[core]本地配置中包含bare = true 和的部分 bare = false。更具问题的是,它将为origin远程服务器使用错误的值,[remote "origin"]包括mirror = true和在内的部分将对工作副本无法正常工作。解决这些问题之后,正常克隆并移动新的工作副本.git将更加有效。
Araxia

0

通常,我将首先克隆初始存储库,然后将现有文件夹中的所有内容移动到初始存储库。它每次都起作用。

这种方法的优点是您不会丢失任何初始存储库,包括README或.gitignore。

您还可以使用以下命令完成步骤:

$ git clone https://github.com/your_repo.git && mv existing_folder/* your_repo

0

您可以通过递归键入以下命令行来做到这一点:

mkdir temp_dir   //  Create new temporary dicetory named temp_dir
git clone https://www...........git temp_dir // Clone your git repo inside it
mv temp_dir/* existing_dir // Move the recently cloned repo content from the temp_dir to your existing_dir
rm -rf temp_dir // Remove the created temporary directory

0

只需使用即可。在git clone命令末尾(位于该目录中),如下所示:

cd your_dir_to_clone_in/
git clone git@github.com/somerepo/ .
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.