Git - 如何将目录中的更改自动推送到另一个分支

Git - How to auto push changes in a directory to another branch

完成问题重写

所以我认为我对这个问题的解释非常简单直接,但似乎我过于简单化了,所以这里是所有额外的细节。希望这可以帮助大家看到这也不是重复的。


我有一个存储库(项目),我想在其中自动执行将提交从一个分支中的一个目录推送到另一个分支的过程;我在 SO 上还没有遇到的东西。

这是我的项目及其完整结构:

[PROJECT MASTER BRANCH]
|- gh-pages    (directory)
|- css         (directory)
|- index.html  (file)
|- readme.md   (file)

[PROJECT gh-pages BRANCH]
|- (empty at the moment)

我希望做的是创建一个挂钩,自动处理主分支中我的 gh-pages 目录中的更改,并将它们复制/克隆/替换(无论使用哪个术语都是正确的)到 gh-页面分支,项目网站分支。这是一个省略了所有其他文件的示例:

[PROJECT MASTER BRANCH]
|- gh-pages         (directory)   <=== SEE UPDATE BELOW [A]
|  |- css           (directory)
|  |  |- style.css  (file)
|  |- index.html    (file)

[PROJECT gh-pages BRANCH]
|- css           (directory)   <=== SEE UPDATE BELOW [B]
|  |- style.css  (file)
|- index.html    (file)

我对 Git Hub 这个级别完全陌生。我通常只坚持基础知识,从不使用终端/shell。所以总而言之,为了澄清我希望做什么,我想:

这是我尝试使用的一些 post-receive 钩子代码(我通过研究一些东西制作的)但它不起作用:

#!/bin/bash
while read oldrev newrev refname
do
    branch=$(git rev-parse --symbolic --abbrev-ref $refname)
    if [ "master" == "$branch" ]; then
        git checkout gh-pages
        git checkout master -- gh-pages
        git add gh-pages
        git commit -m "Updating project website from 'master' branch."
    fi
done

注意
正如我的评论中提到的:这不是重复的。这不是在问如何推送,而是在我进行正常推送时如何处理自动 运行 的其他命令。这些命令将完成我的 OP 中提到的额外工作。

更新
我已将这些箭头添加到我在下面引用的部分代码中:<===

[A] 这里应该发生的是 Git 应该递归读取主分支 gh-pages 目录,并且只从中复制更新的内容(或所有内容如果那样更容易的话)进入 gh-pages 分支。

[B] 所以如果 master 中的 gh-pages 目录有一个 index.html 文件和一个 css 文件夹 style.css文件应该只复制该结构而不是 gh-pages 目录本身。下面是一个坏钩子的例子,它也复制了 gh-pages 目录:

[PROJECT gh-pages BRANCH]
|- gh-pages         (Directory)   <=== NOT SUPPOSED TO HAPPEN
|  |- css           (directory)
|  |  |- style.css  (file)
|  |- index.html    (file)

此外,挂钩不应复制任何其他文件,而是复制 gh-pages 中的内容。即使在 master 分支中更改了其他几个文件,也只应复制 gh-pages 目录文件。

[C] 新代码 - 这有效但会导致错误:

#!/bin/bash
branch=$(git rev-parse --abbrev-ref HEAD)
if [ "master" == "$branch" ]; then
    git fetch && git checkout gh-pages
    git checkout master -- gh-pages/*
    git add -A
    git commit -m "Updating project website from 'master' branch."
    git push -u origin gh-pages
fi

这行不通有两个原因。 1)如果回购落后于提交,它无法处理,它会出错;如果使用 pull 而不是 fetch,本地 repo 会像这样被擦除:

如果我离开 fetch,本地回购保持原样:

2) 整个 gh-pages 目录仍然被复制到 gh-pages 分支,而不仅仅是其中的文件。

你写的钩子脚本有什么问题?您创建 b运行ch gh-pages 时的内容是什么?

我用下面的命令创建了一个空的 b运行ch gh-pages:

git checkout --orphan gh-pages
git rm -rf .
touch README.txt
git add README.txt
git commit -m "Initial commit"
git push -u origin gh-pages

然后我 运行 下面的脚本作为 post-receive 挂钩的一部分,它对我有用。

#!/bin/bash
branch=`git rev-parse --abbrev-ref HEAD` 
if [ "master" == "$branch" ]; then
    git fetch && git checkout gh-pages
    git checkout master -- gh-pages
    git add -A
    git commit -m "Updating project website from 'master' branch."
    git push -u origin gh-pages
fi
done

你真的不需要这种复杂的方法。

只需将您自己的存储库添加为子模块(本身!),子模块位于 gh-pages 分支之后(自 a submodule can follow the latest commit of a branch)!

git checkout master
git rm -r gh-pages # save your data first
git submodule add -b gh-pages -- /remote/url/of/your/own/repo
git commit -m "ADd gh-pages branch as submodule"
git push

这样,您可以在主分支或 gh-pages 文件夹(实际上是一个子模块)中更改文件

每当你在 gh-pages 文件夹中进行更改时,不要忘记在那里提交, 在你的回购的主文件夹中,以便记录新的gitlink (special entry in the index) 表示 gh-pages 子模块的新 SHA1。

cd myrepo/gh-pages
# modify files
git add .
git commit -m "modify gh-pages files"
cd .. # back to myrepo folder
git add gh-pages
git commit -m "record gh-pages new SHA1"
git push

With git 2.7+,可以设置:

cd /path/to/main/repo
git config push.recurseSubmodules on-demand

然后来自主仓库的单个 git pushgh-pages 子模块推送到 gh-pages 分支。

稍后,单个 git clone 将克隆您的主存储库 它的 gh-pages 分支(在 gh-pages 子模块文件夹中)。

这样,您始终可以看到这两个内容。

而且您不需要复杂的 "synchronization/copy" 机制。


2016 年 8 月更新:Simpler GitHub Pages publishing 现在允许将您的页面文件保存在 same 分支的子文件夹中(否更多 gh-pages 需要):

您不再需要子模块方法,因为您的寻呼机可以位于同一分支的子文件夹中。