gpt4 book ai didi

git - 有没有办法将项目中的每个文件都设为 `git stash`(不仅仅是更改)?

转载 作者:太空狗 更新时间:2023-10-29 14:30:58 26 4
gpt4 key购买 nike

我遇到了一个问题,我认为最好的解决方案是捕获项目的当前状态并将其应用于新分支中的新提交。

这是我的 git 工作流的概述:

  • 我在我的机器上保留了 origin/master 分支的本地副本,我将其称为 local/master。
  • 在我自己的本地/功能分支中调试更改时,我使用 local/master 进行比较。例如,如果我注意到本地/功能分支中的错误,我可能会切换回本地/主分支以查看它是否在那里重现。这让我知道错误是预先存在的还是由我自己的更改引起的。
  • 在 origin/master 和我的 local/feature 分支之间执行 merge 时,我还使用 local/master 作为中间暂存分支。这可以防止源分支(master)成为移动目标,以防我需要放弃 merge 并重新开始。
  • 我只通过从 origin/master pull 来更新 local/master。每当其他开发人员将他们自己的更改 merge 到 origin/master 时,就会执行此操作。
  • 我通过从 local/feature 推送到 origin/feature 并提交从 origin/feature 到 origin/master 的 merge 请求来提交我的代码。

以下是导致这种情况的时间顺序:

  1. 我从 local/master 分支了一个分支作为 local/feature1。
  2. 我对 local/feature1 做了几次提交。
  3. 一项功能已 merge 到 origin/master 中,将一些 .pem 文件(公钥/私钥)从一个目录移动到另一个目录。
  4. 一个钩子(Hook)被添加到 origin(一个私有(private)的 Gitlab 实例),以防止任何后续的 .pem 文件被 checkin 。
  5. 我从 origin/master pull 到 local/master。
  6. 我从 local/master merge 到 local/feature1。
  7. 我对 local/feature1 做了更多的提交。
  8. 我试图将我的代码从 local/feature1 推送到 origin 作为 origin/feature1。
  9. origin 提示不允许我 checkin .pem 文件。

我相信这是因为 local/feature1 中的提交历史现在包含一个包含 .pem 文件更改的 merge 提交。这个文件是在 hook 实现之前添加到 origin/master 的,所以它不受 hook 的限制。但是, merge 提交到我的分支之后会随着我的代码更改一起提交,因此它会被钩子(Hook)标记。

此时我想从 local/feature1 的提交历史中删除 .pem 文件而不实际删除这些文件。此时重新设置和压缩提交不会解决问题,因为 .pem 文件已经存在。删除 .pem 文件无济于事,因为它们实际上需要在项目中(不相关的故事)。将我的分支恢复到未 merge 状态也不是一种选择,因为上传的原点/特征与原点/母版相比太过时了,以至于审查没有意义。

显而易见的解决方案似乎是:

# Copy current state of the project to a backup directory
cp -r . ../backup
rm -rf ../backup/.git

# Reset project to latest official state
git checkout local/master
git pull

# Regenerate local branch so the merged changes aren't included as local commits
git branch -D local/feature1
git checkout -b local/feature2

# Copy the desired project state back in and commit it
cp -rf ../backup/. .
git add --all
git commit -m "Regenerating feature branch"
rm -rf ../backup

# Upload without being restricted by hook
git push --set-upstream origin feature2

我觉得应该有一种方法可以使用 git 在本地执行此操作,而无需直接扰乱文件系统。这样做有什么魔术吗?也许通过 git stash

最佳答案

这里不需要git stashgit stash 已经保存了完整的快照,但所有的提交也是如此。没有提交是差异。 Git 通过将提交与另一个完整的快照进行比较, 提交转换为 差异:两个快照中的不同之处就是差异。许多命令,包括 git stash,通过将提交与其父项进行比较来执行很多操作。例如,git cherry-pick 将要选择的提交与其父提交进行比较,以查看发生了什么变化,然后将这些更改应用到您现在所在的位置(同时进行第二次比较并使用 merge 引擎)。

git commit 根据 index 的内容创建快照,而不是根据工作树中的内容。因此,如果您想要在某个现有分支上进行新提交,该分支与任何现有提交完全匹配,您所要做的就是删除索引中的所有内容,并将其全部替换为来自其他提交的所有内容。 (工作树随之而来,这样您就可以看到发生了什么。)有一个明显、简单的方法可以做到这一点:

$ git checkout br1
$ git rm -r . # from the top level: remove everything
$ git checkout br2 -- . # extract everything from commit at tip of br2
$ git commit

这会产生一个新的提交,它添加到 br1 的提示,其内容来自 br2。 (没有未跟踪的文件随行,因为根据定义,未跟踪的文件不在索引中,但请注意提取的提交中跟踪的文件,这些文件在旧的 br1 提示中未跟踪,反之亦然.)

有一个更短的版本:

$ git read-tree -m -u br2
$ git commit

这会减少工作树中的流失(有时对例如 make 很重要):read-tree将提交读入索引,使用 -u 使 Git 更新工作树以匹配。因为这里只有一个参数给 git read-tree,这会抛出当前索引内容,删除其中(和工作树)中不在 br2 中的所有文件 提交。与较长的变体一样,这不会影响未跟踪的文件。

关于git - 有没有办法将项目中的每个文件都设为 `git stash`(不仅仅是更改)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56501190/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com