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

时间:2016-02-05 04:44:21

标签: git github configuration

完成问题重写

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

我有一个存储库(项目),我希望自动化将提交从分支中的一个目录推送到另一个分支的过程;在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-pages分支复制/克隆/替换它们(无论哪个术语使用正确) ,项目网站分支。这是一个省略所有其他文件的例子:

[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完全陌生。我通常只是坚持基础,从不使用终端/外壳。总而言之,为了澄清我希望做的事情,我想:

  • 只需要在[Master Branch]工作。我需要对[gh-pages Branch]进行的所有更改,我在[Master Branch]的gh-pages目录中进行的更改
  • 最好通过添加一个似乎是post-receive hook的简单文件来实现这个目的吗?

这是我尝试使用的一些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中提到的额外工作。

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

[A] 这里应该发生的是Git应该递归地读取主分支gh-pages目录,并且只从已更新的内容(或者更容易的内容)复制到gh-页面分支。

[B] 因此,如果master中的gh-pages目录有一个index.html文件,而一个带有style.css文件的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页面内的内容。即使在主分支中更改了其他几个文件,也只应复制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)如果repo落后于提交它无法处理它,它将会出错;如果使用pull而不是fetch,则本地repo会被擦除:

Local repo has been wiped when changing code to pull.

如果我离开fetch,本地仓库将保持原样:

Local repo the way it should stay after a push. Fetch was used here.

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

2 个答案:

答案 0 :(得分:3)

你写的钩子脚本有什么问题?你创建它时分支gh-pages的内容是什么?

我用以下命令创建了一个空分支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 hook的一部分运行,它对我有用。

#!/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

答案 1 :(得分:3)

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

只需将您自己的repo添加为子模块(自身!),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文件夹中进行更改时,请不要忘记在您的仓库的主文件夹中提交,以便记录新的 {{ 3}} gitlink)重新处理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

special entry in the index,您可以设置:

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

然后,您主回购中的单个git push gh-pages子模块推送到gh-pages分支。

稍后,单个git clone将克隆您的主要回购gh-pages分支(位于gh-pages子模块文件夹中)。

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

并且您不需要复杂的“同步/复制”机制。

2016年8月更新: With git 2.7+ 现在允许将您的网页文件保存在相同分支的子文件夹中(不再需要gh-pages) :

Simpler GitHub Pages publishing

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