Git - 如何在不丢失这些更改的情况下将更改压缩到忽略的文件?

Phs*_*pok 5 git

我想使用git来保存应用程序随着时间的推移使用的实际依赖关系的历史记录,其保真度高于我从包管理器获得的保真度.

我正在使用这些分支:

  • master:仅限源代码.依赖于.gitignore
  • build:源代码和依赖项
  • 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
Run Code Online (Sandbox Code Playgroud)

哪个有效,并且给我一个有用的视图,从一个发行版到下一个发行版的源,依赖项和二进制文件的更改:

截图显示合并气泡

但它需要两倍的提交.我希望树看起来像这样:

艺术家的概念

如何将"复制构建文件"提交与"构建为"提交相结合?

当我尝试时git merge --squash,它最终处于打开的状态build而不是打开的状态build-$TIMESTAMP,这是不正确的(我想将更改导入到被忽略的文件中,但是合并似乎没有语言来执行此操作).当我尝试git rebase --onto build build-$TIMESTAMP失去新提交的父母时.

我只想记录我在build-$TIMESTAMP分支上获得的确切文件,但是将分支buildmaster分支作为父项,然后将build分支指向该提交.

jth*_*ill 3

这是简单的管道领域。你正在使用“瓷器”命令,这是建立在 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
Run Code Online (Sandbox Code Playgroud)

作为一个快速概述或提醒(视情况而定),git 的对象数据库是一个哈希码索引的键值存储。你通过 git 的类型和哈希向 git 询问任何东西,它会从它的对象数据库中准确地反刍出这些信息。索引只不过是一个平面文件,一个路径索引清单,显示对象数据库中的内容在哪个路径,以及一些用于跟踪正在进行的操作的元数据和注释。 git add在路径中获取内容只是将内容放入对象数据库中,并将内容的哈希放入该路径的索引条目中。

(这里有点咆哮,如果没有心情被说教,请跳过)需要理解的是 git 是完全、残酷的具体的。除了对象数据库之外,有关存储库的所有内容都是纯粹的约定。 git checkoutmakeHEAD指的是您纯粹按照约定签出的提交。您可以将其实现git checkout为一个非常薄的包装器git read-tree -um——主要的额外操作是设置HEAD您从中获得该树的提交。 纯粹按照惯例使您所提交的内容git commit成为父项。HEAD您可以将自己实现为和git commit的一个非常薄的包装器,主要的额外操作是将作为父项和 tu opdate提供给新提交。这个名字本身纯粹是约定俗成的。构建这些内容的内容跟踪器不会关心分支和标签之间的区别,或任何类似的事情。这些约定是故意的、积极的和残酷的简单,因为 (a) 不需要抽象,内容模型已经完美地匹配了需求,并且 (b) git 的全部要点在于核心缺乏抽象:它是“愚蠢的” ”。git commit-treegit write-treeHEADHEADHEADHEAD