如何将一个目录和文件连同提交历史记录沿着移动到子目录中?例如:
[project]/x/[files & sub-dirs]
[project]/x/p/q/[files & sub-dirs]
3pmvbmvn1#
要添加到bmargulies的注解,完整的序列是:
mkdir -p x/p/q # make sure the parent directories exist first git mv x/* x/p/q # move folder, with history preserved git commit -m "changed the foldername x into x/p/q"
请先尝试此操作以查看移动的预览:
git mv -n x/* x/p/q
Wolfgang注解:如果使用bash,可以使用扩展的glob(使用the shopt built-in)来避免试图将文件夹移动到自身中的问题:
shopt
shopt -s extglob; git mv !(folder) folder
Captain Man报告中的注解必须执行:
mkdir temp git mv x/* temp mkdir -p x/p/q git mv temp x/p/q rmdir temp;
背景:我和Cygwin在Windows上。我刚刚意识到我做错了shopt -s extglob示例,所以我的方法可能没有必要,但我通常使用zsh而不是bash,而且它没有命令shopt -s extglob(尽管我确信有一个替代方法),所以这种方法应该可以跨shell工作(如果它是特别外来的,可以在shell的mkdir和rmdir中使用subbing)作为替代,spanky在注解中提到git mv的-k选项:跳过可能导致错误情况的移动或重命名操作。
shopt -s extglob
mkdir
rmdir
git mv
-k
git mv -k * target/
这将避免“can not move directory into itself“错误。
can not move directory into itself
gfttwv5a2#
Git在跟踪内容方面做得非常好,即使内容被移动,git mv显然是你移动文件的方式,因为它们曾经属于x,但现在它们属于x/p/q,因为项目是这样发展的。然而,有时候,在整个项目历史中,将文件移动到一个子目录是有原因的。例如,如果文件被错误地放在了某个地方,此后又进行了一些提交,但间歇性的提交甚至对错误位置的文件都没有意义。如果所有这些都发生在本地分支上,我们希望在推送之前清理混乱。这个问题声明“与提交历史记录沿着”,我会将其解释为以完全相同的方式重写历史记录。
x
x/p/q
git filter-branch --tree-filter "cd x; mkdir -p p/q; mv [files & sub-dirs] p/q" HEAD
然后,这些文件将显示在整个历史记录的p/q子目录中。树形过滤器非常适合小型项目,它的优点是命令简单易懂。对于大型项目,这个解决方案的伸缩性不是很好,如果性能很重要,那么考虑使用索引过滤器,如this answer中所述。请注意,如果重写操作涉及之前已推送的提交,则不应将结果推送到公共服务器。
p/q
olmpazwi3#
我可以看到这是一个老问题,但我仍然觉得有义务回答与我目前的解决方案的问题,我已经从一个例子中导出的git book.而不是使用一个低效的--tree-filter我直接移动文件的索引与--index-filter.
--tree-filter
--index-filter
git filter-branch -f --index-filter 'PATHS=`git ls-files -s | sed "s/^<old_location>/<new_location>/"`;GIT_INDEX_FILE=$GIT_INDEX_FILE.new; echo -n "$PATHS" | git update-index --index-info && if [ -e "$GIT_INDEX_FILE.new" ]; then mv "$GIT_INDEX_FILE.new" "$GIT_INDEX_FILE"; fi' -- --all
这是书中的一个例子的特殊化我也使用了同一个例子在一个特殊的情况下批量重命名提交历史中的文件。如果在子目录中移动文件:记住用\转义路径中的/字符以使sed命令按预期工作。示例:
Project Directory |-a | |-a1.txt | |-b | | |-b1.txt
将B目录移动到项目根目录:
git filter-branch -f --index-filter 'PATHS=`git ls-files -s | sed "s/a\/b\//b\//"`;GIT_INDEX_FILE=$GIT_INDEX_FILE.new; echo -n "$PATHS" | git update-index --index-info && if [ -e "$GIT_INDEX_FILE.new" ]; then mv "$GIT_INDEX_FILE.new" "$GIT_INDEX_FILE"; fi' -- --all
结果:
Project Directory |-a | |-a1.txt | |-b | |-b1.txt
mum43rcc4#
git mv命令是最简单的方法。但是,至少在我的Linux系统上,我需要提供-k标志,以避免返回一个错误,即文件夹不能被移动到它本身。我可以使用...
mkdir subdirectory git mv -k ./* ./subdirectory # check to make sure everything moved (see below) git commit
作为一个警告,这将跳过 * 所有 * 移动,这将导致一个错误的条件,所以你可能会想检查一切都正常工作后,移动和提交之前。
tzxcd3kk5#
如果你出于某种原因不想使用git mv命令,这里有一个替代方法:
git状态
mkdir新文件夹实体化视图旧文件夹新文件夹
mv新文件夹/旧文件夹/.git新文件夹/
ou6hu8tu6#
我自己的建议:git fast-export,然后编辑导出文件,再编辑git fast-import。
git fast-export
git fast-import
6条答案
按热度按时间3pmvbmvn1#
要添加到bmargulies的注解,完整的序列是:
请先尝试此操作以查看移动的预览:
Wolfgang注解:
如果使用bash,可以使用扩展的glob(使用the
shopt
built-in)来避免试图将文件夹移动到自身中的问题:Captain Man报告中的注解必须执行:
背景:
我和Cygwin在Windows上。
我刚刚意识到我做错了
shopt -s extglob
示例,所以我的方法可能没有必要,但我通常使用zsh而不是bash,而且它没有命令shopt -s extglob
(尽管我确信有一个替代方法),所以这种方法应该可以跨shell工作(如果它是特别外来的,可以在shell的mkdir
和rmdir
中使用subbing)作为替代,spanky在注解中提到
git mv
的-k
选项:跳过可能导致错误情况的移动或重命名操作。
这将避免“
can not move directory into itself
“错误。gfttwv5a2#
Git在跟踪内容方面做得非常好,即使内容被移动,
git mv
显然是你移动文件的方式,因为它们曾经属于x
,但现在它们属于x/p/q
,因为项目是这样发展的。然而,有时候,在整个项目历史中,将文件移动到一个子目录是有原因的。例如,如果文件被错误地放在了某个地方,此后又进行了一些提交,但间歇性的提交甚至对错误位置的文件都没有意义。如果所有这些都发生在本地分支上,我们希望在推送之前清理混乱。
这个问题声明“与提交历史记录沿着”,我会将其解释为以完全相同的方式重写历史记录。
然后,这些文件将显示在整个历史记录的
p/q
子目录中。树形过滤器非常适合小型项目,它的优点是命令简单易懂。对于大型项目,这个解决方案的伸缩性不是很好,如果性能很重要,那么考虑使用索引过滤器,如this answer中所述。
请注意,如果重写操作涉及之前已推送的提交,则不应将结果推送到公共服务器。
olmpazwi3#
我可以看到这是一个老问题,但我仍然觉得有义务回答与我目前的解决方案的问题,我已经从一个例子中导出的git book.而不是使用一个低效的
--tree-filter
我直接移动文件的索引与--index-filter
.这是书中的一个例子的特殊化我也使用了同一个例子在一个特殊的情况下批量重命名提交历史中的文件。如果在子目录中移动文件:记住用\转义路径中的/字符以使sed命令按预期工作。
示例:
将B目录移动到项目根目录:
结果:
mum43rcc4#
git mv命令是最简单的方法。但是,至少在我的Linux系统上,我需要提供-k标志,以避免返回一个错误,即文件夹不能被移动到它本身。我可以使用...
作为一个警告,这将跳过 * 所有 * 移动,这将导致一个错误的条件,所以你可能会想检查一切都正常工作后,移动和提交之前。
tzxcd3kk5#
如果你出于某种原因不想使用git mv命令,这里有一个替代方法:
git状态
mkdir新文件夹实体化视图旧文件夹新文件夹
mv新文件夹/旧文件夹/.git新文件夹/
ou6hu8tu6#
我自己的建议:
git fast-export
,然后编辑导出文件,再编辑git fast-import
。