ChatGPT解决这个技术问题 Extra ChatGPT

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

git

我有一个项目的工作副本,没有任何源代码控制元数据。现在,我想在这个文件夹中执行相当于 git-clone 的操作,并保留我的本地更改。

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

更好的讨论是here
@MEM我更喜欢这个答案,但要么工作...... stackoverflow.com/a/5377989/11236
@ripper234 - 是的。我处于同样的情况,我只是做了这些步骤,没有问题。一切都干净漂亮。我想这是一个偏好问题,最重要的是,正如你所说,两者都有效。干杯。
这太疯狂了,没有一种干净的方法可以实现它,当您想将项目克隆到已安装的共享文件夹时非常有用。

C
Community

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

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

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

这也可以在克隆命令期间不进行检出的情况下完成;更多信息可以在 here 中找到。


请注意,这正是他在评论中留下的@ChrisJohnsen 的建议。我发现它很有用,并想把它变成一个实际的答案。克里斯,如果你最终提出答案,我会很乐意删除这个。
谢谢!虽然这缺少像“git checkout --”这样的步骤。因为它认为所有文件都被删除了,对吧?
不,只要您使用 git clone 作为第一个命令,就不需要进一步的 checkout 命令。如果您在第一步中使用 git clone --no-checkout 之类的东西,那么在移动 .git 目录后,将需要使用 git reset HEAD 告诉 git 文件尚未被删除。
我会将其添加为第三步: mv temp/.gitignore code/.gitignore
@KalpeshSoni,是的,git 会知道修改后的文件,并且可以使用普通的 git 命令(例如 git status)查看更改。
A
Albireo

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

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...

你就像克隆人一样。

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


我不喜欢这个 - 根据 github 设置“提示:凭据帮助程序仅在您克隆 HTTPS 存储库 URL 时有效。”我正在使用凭证助手,这让我陷入了一个漫长而毫无结果的兔子洞。
'git checkout --track origin/master' 也可以很好地代替 'git checkout -b master --track origin/master'。不需要重置。
我收到错误“Git 错误:以下未跟踪的工作树文件将被结帐覆盖”,所以我添加了这个命令:git clean -d -fx“”
绝对不是在所有情况下都是可取的,但这正是我所需要的。
@AndreasKrey您的原始答案(我进入编辑历史以查看)正是问题(和我)所需要的。结帐时更改的答案 barfs 不使用 -f,它会丢弃本地更改,这正是我不想要的。如果我是你,我会考虑回滚到你原来的答案。
a
alexwenzel

我做了以下检查现有目录中的主分支:

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

这是一个很好的答案,并且避免了任何文件系统问题。
这应该是公认的答案,因为它不是黑客。
实际上,这正是 OP(和我)不想要的,即覆盖本地更改。
有人可以解释为什么这里使用 -t 标志吗?
git checkout --help-t--track 用于使指定的分支成为默认的上游分支。据我所知,它相当于 git push -u *branch*,所以从那时起你可以只做 git push。我个人不知道它如何影响 git checkout,但我会以同样的方式猜测。
e
eckes

使用临时目录很好,但如果您想避免该步骤,这将起作用。从工作目录的根目录:

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

git reset --hard origin/master 将删除所有本地文件。
添加到上面已经指出的内容,hardmixed 之间的区别在于混合将保留本地更改(因此,如果您稍后尝试拉取它会显示例如 Cannot pull with rebase: You have未暂存的更改。请提交或存储它们),而 hard 将丢弃这些本地更改
你拼错了遥控器。
如果 git checkout -- . 最后运行,我认为这可以按要求工作。否则,克隆时不在 DIR 中的任何内容都会被暂存为已删除。
j
jhwist

我会 git clone 到一个新目录并将现有目录的内容复制到新的克隆。


如果您这样做,请确保在非常仔细地提交之前查看差异 - 这是一个绝对经典的案例,您可能会意外恢复在源代码库中所做的更改,因为每当您获得工作副本时 - 因为没有足够的信息在工作副本中找出您所做的更改与开始更改之前的更改,以与 repo 中所做的其他更改合并。在这种情况下,我一次又一次地看到这种情况发生,以至于我“强烈劝阻”自己和与我一起工作的人不要这样做。
git clone wherever tmp && git mv tmp/.git . && rm -rf tmp 换句话说,将 .git 目录移出临时克隆似乎比清除克隆的工作树并在那里复制现有文件更简单。
@ChrisJohnsen:你应该把它变成一个答案,这绝对是最好的方法,恕我直言
@ChrisJohnsen git mv tmp/.git . 为我返回 fatal: cannot move directory over file, source=tmp/.git, destination=.git。有谁知道是什么问题?
@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)。
r
return1.at
git clone your_repo tmp && mv tmp/.git . && rm -rf tmp && git reset --mixed

使用 git reset --hard 将取消本地文件更改,特别是不是此 OP 请求的内容。 --mixed 应改为使用。
--mixed 可以省略,因为它是默认值。
A
Andrew

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

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

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


V
Vadim Kotov

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

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

请注意 git clone 命令末尾的 .。这会将 repo 下载到当前工作目录中。


fatal: destination path '.' already exists and is not an empty directory.
目录必须为空。
OP 询问如何克隆到现有项目中,并指出 git clone 抱怨。不好的答案。
这仅在您创建新目录时有效,运行上述命令而不使用“git init”
该目录必须为空才能正常工作,其中包括隐藏文件,例如 .DS_Store。使用命令行创建目录,你不会有问题。
n
nwillo
git init
git remote add origin git@github.com:<user>/<repo>.git
git remote -v
git pull origin master

如果当前工作副本的文件不存在于拉出的分支中,这将失败:“以下未跟踪的工作树文件将被合并覆盖”(可能来自不同的分支)。
是的。这仅适用于您在开始在目录中工作之前拉取您的存储库。 @GinoMempin
当我的 .git 文件夹以某种方式损坏并且我不得不重新克隆时,这对我有用
A
Amirtha Rajan

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

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

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

将 .git 文件夹移动到包含文件的目录。这使得 existing-dir 成为一个 git 存储库。

mv 现有目录/现有目录.tmp/.git 现有目录/

删除临时目录

rmdir 现有目录/现有目录.tmp cd 现有目录

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

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

git reset --混合头


在您需要执行此操作的 99% 的情况下,硬重置似乎是不需要的。
C
Caleb

对此有两种方法。在可能的情况下,我会为您的新 git 工作目录创建一个干净的文件夹,然后再复制您的版本。这可能看起来像*:

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 开始。


M
Mike Chen

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

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

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

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

M
Mustapha GHLISSI

您可以通过递归地键入以下命令行来执行此操作:

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

D
Docuemada

作为参考,来自 Gitlab 命令行指令:

推送现有文件夹

cd existing_folder
git init
git remote add origin <url>
git add .
git commit -m "Initial commit"
git push -u origin master

或推送现有的 Git 存储库

cd existing_repo
git remote rename origin old-origin
git remote add origin <url>
git push -u origin --all
git push -u origin --tags

A
Araxia

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

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

这通过以下方式起作用:

将存储库克隆到新的 .git 文件夹中

--mirror 使新克隆成为纯元数据文件夹,因为 .git 需要

--config core.bare=false 对 --mirror 选项的隐式 bare=true 进行反制,从而允许存储库具有关联的工作目录并像普通克隆一样工作

如果您希望转换为工作副本的目录中已经存在 .git 元数据目录,这显然不起作用。


请注意,此技术将导致本地配置的 [core] 部分同时包含 bare = true bare = false。更大的问题是它会为 origin 远程设置错误的值,其中 [remote "origin"] 部分包括 mirror = true 和一个无法与工作副本一起正常工作的获取规范。解决这些问题后,正常克隆和移动新工作副本的 .git 会更有效率。
J
John F

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

cd your_dir_to_clone_in/
git clone git@github.com/somerepo/ .

不起作用:致命:目标路径“。”已经存在并且不是空目录。
您不能克隆到非空目录中。
M
Mohsin Mahmood

如果您正在克隆同一个存储库,则通过现有存储库运行以下代码段

git pull origin master