git命令将文件夹移动到另一个


193

我创建了一个common包含一堆源文件和文件夹的文件夹。

现在我想将common文件夹移到该include文件夹中include/common

我尝试了这些:

  1. git add include

  2. git mv common/ include/

    但由于此错误而失败

    致命:错误的来源,来源= myrepo /常见,目的地= myrepo / include

  3. 我尝试过,git mv common/ include/common但遇到相同的错误

任何想法如何实现这一目标?

Answers:


177

git最好的事情之一就是您不需要显式跟踪文件重命名。Git将通过比较文件内容来弄清楚。

因此,就您而言,不要那么努力:

$ mkdir include
$ mv common include
$ git rm -r common
$ git add include/common

运行git status应该显示以下内容:

$ git status
# On branch master
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#   renamed:    common/file.txt -> include/common/file.txt
#

43
这对我不起作用(使用Windows 7,1.7.6.msysgit.0)。Git认为旧文件已删除,新文件已添加。
巴特

嗯,也许git使用某些外部实用程序来确定文件的同一性taht在Windows上不起作用?这是git实现的核心部分。
Andres Jaan Tack的

13
@OliverF。校正:git mv是等效的。
Andres Jaan Tack 2012年

25
“关于git的最好的事情之一 –这个好功能的缺点之一是,当您还修改了重命名的文件时,它开始失败,这导致它看到删除和添加了新文件,因此,坦率地说,我宁愿使用显式重命名支持。
Erik Kaplun 2015年

2
如果git转换行尾,这将导致@Bart描述的问题。为此,您必须执行以下操作:git config --global core.autocrlf false
Mariano Dupont

162
 git mv common include

应该管用。

git mv手册页

git mv [-f] [-n] [-k] <source> ... <destination directory>

在第二种形式中,最后一个参数必须是现有目录。给定的源将移动到此目录中
成功完成后,索引将更新,但更改仍必须提交。

移动git add请勿进行任何“ ”操作。


注意:“ git mv A B/”(当B不存在于目录中时)应出错,但不存在。

提交c57f628马修莫伊(moyGIT中1.9 / 2.0(Q1 2014):

Git用来修剪尾斜杠,并使命令等效于' git mv file no-such-dir',从而创建了文件no-such-dir(而尾斜杠明确声明了它只能是目录)。

此修补程序跳过了目标路径的尾部斜杠删除。
带有斜杠的路径将传递给rename(2),该错误会因相应的消息而出错:

$ git mv file no-such-dir/
fatal: renaming 'file' failed: Not a directory

2
完美工作-使用git mv外观似乎是更好的方法!
Tomas Petricek

23

命令:

$ git mv oldFolderName newFolderName

通常正常。

错误“错误的源...”通常表示在最后一次提交之后,源目录中有一些重命名,因此git mv找不到所需的文件。

解决方案很简单-只需在应用之前提交即可git mv


15

在运行之前,请确保已将所有更改添加到登台区域

git mv oldFolderName newFoldername

git失败并显示错误

fatal: bad source, source=oldFolderName/somepath/somefile.foo, destination=newFolderName/somepath/somefile.foo

如果有任何未添加的文件,那么我才发现。


“如果有任何未添加的文件,那么我才发现。” - 谢谢!
cacoder

3

将目录中所有文件移动到子目录的另一种方法(保留git历史记录):

$ for file in $(ls | grep -v 'subDir'); do git mv $file subDir; done;


3

我在git mv将一个文件夹的内容移动到现有文件夹中时遇到了类似的问题,并最终得到了这个“简单”脚本:

pushd common; for f in $(git ls-files); do newdir="../include/$(dirname $f)"; mkdir -p $newdir; git mv $f $newdir/$(basename "$f"); done; popd

说明

  • git ls-files:查找所有common签入git的文件(在文件夹中)
  • newdir="../include/$(dirname $f)"; mkdir -p $newdir;:在该include文件夹内新建一个文件夹,其目录结构与common
  • git mv $f $newdir/$(basename "$f"):将文件移到新创建的文件夹中

这样做的原因是git似乎无法将文件移至现有文件夹,并且如果您尝试将文件移至不存在的文件夹也会失败(因此 mkdir -p)。

这种方法的好处是,它涉及已签入git的文件。通过简单地使用git mv移动整个文件夹,并且该文件夹包含未暂存的更改,git将不知道该怎么做。

移动文件后,您可能需要清理存储库以删除所有剩余的未登台的更改-请记住要先空运行!

git clean -fd -n

2

抱歉,我没有足够的声誉来评论“ Andres Jaan Tack”的“答案”。

我认为我的信息将被删除((但我只想警告“ lurscher”和其他遇到相同错误的人:请谨慎

$ mkdir include
$ mv common include
$ git rm -r common
$ git add include/common

这可能会导致您在新文件夹中看不到项目的git历史记录。

我试过了

$ git mv oldFolderName newFolderName

得到

fatal: bad source, source=oldFolderName/somepath/__init__.py, dest
ination=ESWProj_Base/ESWProj_DebugControlsMenu/somepath/__init__.py

我做了

git rm -r oldFolderName

git add newFolderName

而且我在项目中看不到旧的git历史记录。至少我的项目没有丢失。现在我的项目在newFolderName中,但是没有历史记录(

只是想警告,如果您不想失去git hsitory,请谨慎使用“ Andres Jaan Tack”的建议。


确保已添加所有更改。如果有未做的更改,Git不会说“错误的源”,所以我才发现。
Kevin Pluck 2015年

0

我有类似的问题,但是在我想移动的文件夹中,我有没有跟踪的文件。

假设我有档案

a/file1
a/untracked1
b/file2
b/untracked2

我只想将跟踪的文件移动到子文件夹subdir,所以目标是:

subdir/a/file1
subdir/a/untracked1
subdir/b/file2
subdir/b/untracked2

我所做的是:

  • 我创建了新文件夹,并移动了所有我想移动的文件: mkdir tmpdir && mv a b tmpdir
  • 签出旧文件 git checkout a b
  • 创建新的目录并将干净的文件夹(没有未跟踪的文件)移动到新的子目录: mkdir subdir && mv a b subdir
  • 从subdir添加了所有文件(因此Git可以仅添加以前跟踪的文件-有点类似于git add --update目录更改技巧):(git add subdir通常这甚至会添加未跟踪的文件-这将需要创建.gitignore文件)
  • git status 现在仅显示移动的文件
  • 将其余文件从tmpdir移至subdir: mv tmpdir/* subdir
  • git status看起来我们执行了git mv:)

-1

我这样做在Windows上解决了这个问题:

  • Open Power Shell控制台
  • 运行目录
  • Alt单击并在“文件/文件夹名称”列上拖动,然后复制
  • 粘贴到记事本++
  • 运行与正则表达式替换:替换(.*)git mv ".\\\1" ".\\<New_Folder_Here>\"
  • 将所有文本从notepad ++复制到powershell中
  • 点击进入
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.