在git

时间:2019-02-07 14:52:57

标签: bash git

我正在尝试从我的主分支的子文件夹中创建分支。然后,在每个“子文件夹”分支中,我分别删除“同级”子文件夹,从而每个子文件夹有一个分支。我正在重构一个oodo代码库,其中每个包/附件都位于master分支中,并且我希望每个都在自己的分支中,以便以后可以合并也可以不合并。

我的代码如下

#!/bin/bash
master=$(git symbolic-ref --short HEAD)
find  . -maxdepth 1 -mindepth 1 -type d -name "[!.]*" -printf "%f\n" | while read branch
do
   # Use -b if the branches do not exist
   git checkout -b $branch
   # The following can be used to determine which files/folders are removed from the repository
   find ./* -mindepth 1 -path ./.git -prune -o -path ./attooh_sms -prune -o -type f -printf "%p\n" | sed "s|^\./||" > pruned.files
#    cat pruned.files
   # The following removes the specified files and folders from teh repository
   cat pruned.files | while read file
   do
     echo  $file
     git filter-branch --tree-filter "git rm '$file'"  -- HEAD
   done
#    git filter-branch --tree-filter "git rm $(cat pruned.files | tr '\n' ' ')"  -- HEAD
   git -am "Created the $branch branch from $master removing all other addons"
   git checkout $master
done

我不断收到以下错误,但我似乎无法解决为什么。

fatal: pathspec 'attooh_sms/views/sms_views.xml' did not match any files

我相信这与逃避bash有关,我希望有人可能对我有所提示。从本质上讲,我认为"$file"正在崩溃为"",这导致git rm调用失败并导致git filter-branch跳闸。我应该如何确保转义正常进行?

更新

出于完整性的考虑,对于Google以外的人,我最后给出了以下内容:

#!/bin/bash
master=$(git symbolic-ref --short HEAD)
find  . -maxdepth 1 -mindepth 1 -type d -name "[!.]*" -printf "%f\n" | while read branch
do
   git checkout $branch
   find . -mindepth 1 -maxdepth 1 -path ./.git -prune -o -path ./$branch -prune -o -type d -printf "%p\n" | sed "s|^\./||" > pruned.files
   git filter-branch --tree-filter "git rm -r --cached --ignore-unmatch $(cat pruned.files|tr '\n' ' ')"  -- HEAD
   echo git checkout $master
done

这正常工作,问题出在git rm上,它似乎无法处理目录或文件列表,但这不是最漂亮的,而且我不确定它能否真正实现我最初想要的功能,与答案不同JTHill

1 个答案:

答案 0 :(得分:0)

要为当前提示的每个子目录划分分支,这应该比您现在拥有的方法更好:

branch=`git symbolic-ref --q --short HEAD` || { echo not on a branch; exit; }
git ls-tree @ | grep ^04 | cut -f2-  \
| while read subdir; do
        git checkout -B $branch-$subdir
        git filter-branch -f --subdirectory-filter $subdir
        git checkout $branch
done

这会将每个子目录提升到新分支中的根目录,因此,如果您有目录src,则mastersrc/main.c历史记录中的内容仍然位于master-src的{​​{1}}历史记录。如果您不希望这样做,则可以更深一层:

main.c

这样的大型手术最好在临时回购中进行。

branch=`git symbolic-ref --q --short HEAD` || { echo not on a branch; exit; }
git ls-tree @ | grep ^04 | cut -f2-  \
| while read subdir; do
        git checkout -B $branch-$subdir
        git filter-branch -f --index-filter '
                git read-tree --empty
                # the `|| git reset etc` here is in case older versions were not dirs
                git read-tree --prefix='$subdir'/ $GIT_COMMIT:'$subdir' ||
                        git reset $GIT_COMMIT '$subdir'
        ' -- HEAD -- $subdir
        git checkout $branch
done

因此,如果发生任何问题,您只需放弃克隆。