我想使用 git 保存应用程序随时间使用的实际依赖项的历史记录,其保真度比我从包管理器获得的保真度更高。
我正在使用这些分支:
- master:仅源代码。依赖于
.gitignore
- 构建:源代码和依赖项
- build-$TIMESTAMP:用于强制提交被忽略文件的临时分支
而这个脚本,build-release.sh
:
DEV_MODULES="mocha chai bower coffeelint"
BUILT_FILES="node_modules build"
DATE=$(date)
TIMESTAMP=$(date +"%s")
BRANCH=$(git rev-parse --abbrev-ref HEAD)
# create a temporary branch with the current dependencies and binaries
npm uninstall $DEV_MODULES
git checkout -b build-$TIMESTAMP
git add --all --force $BUILT_FILES
git commit -m "copy $BUILT_FILES from $BRANCH"
# merge the temporary branch into the build branch
git branch build || echo "build branch already exists"
git checkout build --force
git merge build-$TIMESTAMP --strategy=subtree -m "Build as of $DATE"
git branch -D build-$TIMESTAMP
# restore the original branch
git checkout $BRANCH
git checkout build -- $BUILT_FILES
git rm -r --cached $BUILT_FILES
它有效,并为我提供了从一个版本到下一个版本对源代码、依赖项和二进制文件的更改的有用视图:
但它需要两倍的必要提交次数。我希望这棵树看起来像这样:
如何将“复制构建文件”提交与“构建为”提交结合起来?
当我尝试git merge --squash
,它最终处于开启状态build
而不是当时的状态build-$TIMESTAMP
,这是不正确的(我想导入对忽略文件的更改,但合并似乎没有语言可以执行此操作)。当我尝试git rebase --onto build build-$TIMESTAMP
我失去了新提交的出身。
我只是想记录我在网站上获得的确切文件build-$TIMESTAMP
分支,但同时具有build
and master
分支作为父级,然后指向build
分支到该提交。
这是简单的管道领域。你正在使用“瓷器”命令,这是建立在 git 内容跟踪器核心之上的源代码控制系统,其方式恰好能让瓷器做你想做的事情,但直接与内容跟踪器对话要简单得多。
为了最简单地阅读您的问题中的内容,即您希望“构建”分支记录当前结账的快照以及对问题中内容的选择"$BUILT_FILES"
路径/目录,它是
# knobs
DEV_MODULES="mocha chai bower coffeelint"
BUILT_FILES="node_modules build"
DATE=$(date)
# clean out stuff we don't care about
npm uninstall $DEV_MODULES
# record current checkout plus "$BUILT_FILES" to `build` branch
git add --all --force $BUILT_FILES
build=`git rev-parse -q --verify build`
git update-ref refs/heads/build $(
git commit-tree ${build:+-p $build} -p HEAD \
-m "build as of $DATE" \
`git write-tree`
)
# reset index to HEAD
git reset # `git read-tree HEAD` will have the same effect, perhaps more quietly
作为一个快速概述或提醒(视情况而定),git 的对象数据库是一个哈希码索引的键值存储。你通过 git 的类型和哈希向 git 询问任何东西,它会从它的对象数据库中准确地反刍出这些信息。索引只不过是一个平面文件,一个路径索引清单,显示对象数据库中的内容在哪个路径,以及一些用于跟踪正在进行的操作的元数据和注释。git add
在路径中获取内容只是将内容放入对象数据库中,并将内容的哈希放入该路径的索引条目中。
(这里有点咆哮,如果没有心情被说教,请跳过)需要理解的是 git 是完全、残酷的具体的。除了对象数据库之外,有关存储库的所有内容都是纯粹的约定。git checkout
makes HEAD
纯粹按照惯例引用您签出的提交。你可以实施git checkout
作为一个极薄的包装纸git read-tree -um
-- 主要的额外操作是设置HEAD
到您从中获得那棵树的提交。git commit
makes HEAD
您纯粹按照惯例提交的内容的父级。你可以实施git commit
你自己就像一个极薄的包装纸git commit-tree
and git write-tree
,主要的额外操作是提供HEAD
作为父母和你的更新HEAD
到新的提交。名字HEAD
本身就是纯粹的传统。构建这些内容的内容跟踪器根本不关心HEAD
,或分支和标签之间的区别,或任何类似的东西。这些约定是故意的、积极的和残酷的简单,因为 (a) 不需要抽象,内容模型已经完美匹配需求,并且 (b) git 的全部要点在于核心缺乏抽象:它是“愚蠢的” ”。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)