【问题标题】:Git - separate folder for each branch. Setting it upGit - 每个分支的单独文件夹。设置它
【发布时间】:2013-02-08 11:19:40
【问题描述】:

我需要在 3 个单独的文件夹中保留 3 个分支。 (我知道这不是 git 做事的方式。但我需要这样做是有原因的)。

假设回购名称是my_proj_repo.git 我在本地系统中创建了一个名为 prodv1 的文件夹:

git clone url:/my_proj_repo.git

现在我进入prodv1文件夹并从服务器复制文件,然后:

git commit -am "initial import"
git push origin master

这会将文件推送到 master。 现在我在本地系统中又创建了两个类似上面的文件夹

stagingv1
devv1

我想创建两个本地和远程分支,名称分别为:

staging // this local branch points (push/pull) to staging remote branch
dev     // this local branch points ((push/pull) to dev remote branch

而且这两个分支应该在对应的文件夹中:

staging ==> stagingv1 folder
dev     ==> devv1 folder

我尝试了一些东西,但我想我搞砸了。 有人可以指点我的命令/步骤来获得我想要的所有这些设置吗?

我所做的是,进入stagingv1 文件夹并执行git clone <repo>。但它默认为master。而且我不确定如何在这里初始化staging 分支。

【问题讨论】:

  • 怎么不是“git的做事方式”?如果不是新的存储库,单独的项目应该是它们自己的分支。否则在同一个分支上有不同的项目会使历史与其他项目的历史混为一谈。

标签: git branch directory


【解决方案1】:

自从 git 2.5 引入git worktree 命令以来,您想要实现的目标变得更简单(甚至微不足道)。

基本上,您的 git 存储库现在拥有完全免费的已签出分支,称为工作树:

  • 0(一个 bare repo - 大致就是你的 repo 的 .git 目录的内容)
  • 1(一个普通的 repo - 你在树中的代码,.git 下的 git 目录)
  • n > 1,一个普通的 repo,您​​在其中添加了 n-1 个 worktrees(在 repo 之外的任意路径中,并带有一个指向 repo 的 git 目录的 .git 文件)

如果您的 repo 已经包含您的分支,您可以这样做:

git worktree add <path to branch> <branch name>

或者,如果该分支尚未创建并且您想从 master 分支:

git worktree add -b <new branch name> <path to branch> master

请注意,您不能同时签出多个目录中的分支。

【讨论】:

    【解决方案2】:

    这是一个 bash 脚本,用于将所有远程分支检出到单独的工作树中,然后使它们保持同步。每次运行时,它都会丢弃任何本地更改。它只是试图使签出的代码镜像 repo。

    git fetch --all --prune
    
    # reset branch only if it has deviated from the remote
    function update_branch {
            if git diff --exit-code --quiet $1; then
                    echo "No changes on branch $1"
            else
                    echo "Resetting branch $1"
                    git reset --hard $1
            fi
    }
    
    # master branch is checked out in the root
    update_branch origin/master
    
    # check out each remote branch into a subfolder
    branches=$(git for-each-ref --format='%(refname:short)' refs/remotes/origin | grep -v /HEAD | grep -v /master)
    for branch in $branches; do
            if [ -d $branch ]; then
                    cd $branch
                    update_branch $branch
                    cd $OLDPWD
            else
                    echo "Checking out new branch $branch"
                    git worktree add $branch $branch
            fi
    done
    
    # check for branches that have been deleted on the remote
    for branch in origin/*; do
            if ! git show-ref --verify refs/remotes/$branch --quiet; then
                    echo "Removing worktree $branch"
                    git worktree remove $branch
            fi
    done
    
    git worktree prune
    
    

    【讨论】:

      【解决方案3】:

      问题中提出的上述场景在以下场景中非常有效。

      1. 微服务:AWS Lambda 开发,例如一两个开发 lambda 的工作,总共有 70 个 lambda。因此,包括 test 和 code_folder 在内的 70 个文件夹。如果它是一个单体系统,您必须通过零合并问题来确保系统的所有部分一起工作。但这里 70 个文件夹中的每一个都是独立的,除了少数全局配置和少数共享文件夹。

      2. Monorepo:大公司使用 monorepo 来管理大型项目的所有子项目,包括移动应用、网站、后端和其他相关内容。

      如果每个分支轨道仅在其文件夹中更改,则主分支可能具有也可能不具有所有代码。

      一种方法,首先为共享模块创建一个共享分支。 然后,创建多个分支,每个分支都以空文件夹开头。 永远不要将您的分支与 master 合并,仅拉共享分支在本地合并您的分支并推送到远程分支。

      因此,远程上的每个分支都有共享模块和您的代码。

      【讨论】:

        【解决方案4】:

        我认为您可能必须在您的 repo 中创建所有分支

        $ git branch <name_of_your_new_branch>
        

        然后创建所有文件夹并在每个文件夹中克隆 repo,但检查相应的分支。

        每个文件夹应该/可能只跟踪适当的分支

        Step 1 $ git branch [name_branch#1]
        
        Step 2 $ git branch [name_branch#2]
        
        Step 3 $ git branch [name_branch#3]
        

        ...

        Step 4 $ git push --all
        Step 5 md Folder #2
        Step 6 $ git clone [URL]
        Step 7 $ git checkout [name_branch]
        

        【讨论】:

        • @KevinRave 我写了这一步,你可能需要调整命令,但我认为想法就在那里。
        • 这已经过时了,@Cimbali 的答案应该是被接受的
        猜你喜欢
        • 2011-06-20
        • 2016-09-13
        • 1970-01-01
        • 1970-01-01
        • 2020-03-13
        • 1970-01-01
        • 2011-10-18
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多