【问题标题】:Git - How to auto push changes in a directory to another branchGit - 如何将目录中的更改自动推送到另一个分支
【发布时间】:2016-02-05 04:44:20
【问题描述】:

完成问题重写

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


我有一个存储库(项目),我想在其中自动化将提交从一个分支中的一个目录推送到另一个分支的过程;我在 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 目录中来自 master 分支的更改,并将它们复制/克隆/替换它们(无论使用哪个正确的术语)到 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]工作。我需要在 [Master Branch] 的 gh-pages 目录中对 [gh-pages Branch] 进行的所有更改
  • 最好通过添加一个似乎是接收后挂钩的简单文件来完成此操作?

这是我尝试使用的一些接收后挂钩代码(我通过研究一些东西来实现)但它不起作用:

#!/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-页面分支。

[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-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)如果repo在提交上落后,它无法处理,它会出错;如果使用 pull 而不是 fetch,则本地 repo 会像这样被擦除:

如果我离开 fetch 本地 repo 保持它应该的方式:

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

【问题讨论】:

  • @gzh 这不是重复的。这不是在问如何推送,而是在问我进行正常推送时如何处理自动运行的其他命令。这些命令将完成我的 OP 中提到的额外工作。 That question 是关于在每次用户点击提交时自动化整个 Git 周期,而不是提交到 master 并同时将目录克隆到一个完全不同的分支。
  • 看来你需要写一个post-receive hook来完成这个任务。
  • @gzh 凹凸。改写了问题。接收后挂钩很有意义,但我不知道如何实现它。
  • 钩子脚本应该在 $your_repo/hooks/post-receive 目录下,那么你的钩子脚本的运行目录是什么,你的结帐代码将放在哪里?我认为你应该创建一个新文件夹,克隆源代码并做你想做的事。

标签: git github configuration


【解决方案1】:

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

只需将您自己的 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 文件夹中进行更改时,请不要忘记在那里提交,在您的 repo 的主文件夹中以记录新的 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 子模块文件夹中)。

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

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


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

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

【讨论】:

  • 注意:这是我在 2011 年 (stackoverflow.com/a/8148319/6309) 提到的旧方法,基于 Mark Longair 的回答 (stackoverflow.com/a/5296433/6309)。但当时,子模块不跟随分支,你不能一次推送所有的东西。
  • 你在这里迷失了我:“每当你在 gh-pages 文件夹中进行更改时,不要忘记在那里提交”。如果我在 shell 中运行您的代码,它可以工作,但是如果我尝试使用 Git for windows(桌面)进行任何类型的正常提交,我会收到一条错误消息,提示使用 shell 添加子模型或删除 .git 文件
  • 我试过这个答案,但没有骰子:stackoverflow.com/questions/5542910/…
  • @Blizzardengle 我已经详细说明了“不要忘记提交”步骤。我在初始submodule add 之后添加了您必须执行的提交。再次克隆您的存储库,然后重试这些步骤。 (仅在命令行中。GitHub Desktop 是一个 GUI,它可以包装和混淆真正发生的事情:你不需要它)
  • 我整晚都在努力修改它,只有两件事要说。 1)它的作品,谢谢。 2)它没有回答我要求非外壳解决方案的操作。我的目标和迫切的愿望是每次都使用 Gits 窗口 GUI 而不是 shell。我做了一个预提交钩子,甚至是一个预推送钩子,在我的 GUI 提交之前自动提交子模块更改并且没有骰子。但是,如果我在 shell 中手动执行此操作,它可以工作......对此不满意,但它可以工作。
【解决方案2】:

你写的钩子脚本有什么问题? 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

【讨论】:

  • 我不理解你的代码,所以我认为你可能误解了。出于某种原因,我的钩子无法运行,但如果我自己在 shell 中运行所有这些,它就可以了。它所做的只是将每个更改的文件从我的整个 master 分支复制到 gh-pages 中,这不是我需要的。 github.com/blizzardengle/barebones-framework
  • 我编辑了我的问题以指出不工作的部分。
  • 这从来没有按原样工作,因为 branch=git rev-parse --abbrev-ref HEAD 需要是 $(git rev-parse --abbrev-ref HEAD)。它还复制了超出预期的内容,即 gh-pages 目录。这是一个快速的解决方案,可以考虑作为一个答案,但@VonC 的答案更让人头疼。
  • 我们将制作一个外壳来处理我昨天建议的预期任务。但是我同意 VonC 的答案是值得的..
猜你喜欢
  • 2015-01-01
  • 2022-11-15
  • 2018-12-19
  • 2015-07-03
  • 2020-06-03
  • 2021-06-28
  • 2017-12-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多